Merge "Release resources for a previously loaded cursor if a new one comes in."
diff --git a/core/java/android/animation/Sequencer.java b/core/java/android/animation/Sequencer.java
index e73ac88..74d81e9 100644
--- a/core/java/android/animation/Sequencer.java
+++ b/core/java/android/animation/Sequencer.java
@@ -69,11 +69,6 @@
     private final ArrayList<Node> mSortedNodes = new ArrayList<Node>();
 
     /**
-     * The set of listeners to be sent events through the life of an animation.
-     */
-    private ArrayList<AnimatableListener> mListeners = null;
-
-    /**
      * Flag indicating whether the nodes should be sorted prior to playing. This
      * flag allows us to cache the previous sorted nodes so that if the sequence
      * is replayed with no changes, it does not have to re-sort the nodes again.
@@ -224,7 +219,6 @@
             if (mSequenceListener == null) {
                 mSequenceListener = new SequencerAnimatableListener(this);
             }
-            node.animation.addListener(mSequenceListener);
             if (node.dependencies == null || node.dependencies.size() == 0) {
                 nodesToStart.add(node);
             } else {
@@ -234,6 +228,7 @@
                 }
                 node.tmpDependencies = (ArrayList<Dependency>) node.dependencies.clone();
             }
+            node.animation.addListener(mSequenceListener);
         }
         // Now that all dependencies are set up, start the animations that should be started.
         for (Node node : nodesToStart) {
@@ -329,6 +324,7 @@
             if (mNode.tmpDependencies.size() == 0) {
                 // all dependencies satisfied: start the animation
                 mNode.animation.start();
+                mSequencer.mPlayingSet.add(mNode.animation);
             }
         }
 
@@ -356,9 +352,21 @@
         public void onAnimationEnd(Animatable animation) {
             animation.removeListener(this);
             mPlayingSet.remove(animation);
-            if (mPlayingSet.size() == 0) {
+            Node animNode = mSequencer.mNodeMap.get(animation);
+            animNode.done = true;
+            ArrayList<Node> sortedNodes = mSequencer.mSortedNodes;
+            int numNodes = sortedNodes.size();
+            int nodeIndex = sortedNodes.indexOf(animNode);
+            boolean allDone = true;
+            for (int i = nodeIndex + 1; i < numNodes; ++i) {
+                if (!sortedNodes.get(i).done) {
+                    allDone = false;
+                    break;
+                }
+            }
+            if (allDone) {
                 // If this was the last child animation to end, then notify listeners that this
-                // sequence ended
+                // sequencer has ended
                 if (mListeners != null) {
                     ArrayList<AnimatableListener> tmpListeners =
                             (ArrayList<AnimatableListener>) mListeners.clone();
@@ -435,6 +443,7 @@
                         }
                     }
                 }
+                node.done = false; // also reset done flag
             }
         }
     }
@@ -502,6 +511,13 @@
         public ArrayList<Node> nodeDependents = null;
 
         /**
+         * Flag indicating whether the animation in this node is finished. This flag
+         * is used by Sequencer to check, as each animation ends, whether all child animations
+         * are done and it's time to send out an end event for the entire Sequencer.
+         */
+        public boolean done = false;
+
+        /**
          * Constructs the Node with the animation that it encapsulates. A Node has no
          * dependencies by default; dependencies are added via the addDependency()
          * method.
diff --git a/core/java/android/widget/RemoteViewsAdapter.java b/core/java/android/widget/RemoteViewsAdapter.java
index 07a54eb..52635e8 100644
--- a/core/java/android/widget/RemoteViewsAdapter.java
+++ b/core/java/android/widget/RemoteViewsAdapter.java
@@ -16,8 +16,8 @@
 
 package android.widget;
 
-import java.util.Arrays;
 import java.util.HashMap;
+import java.util.LinkedList;
 import java.util.Map;
 
 import android.content.ComponentName;
@@ -85,6 +85,7 @@
         public void onServiceConnected(ComponentName name, IBinder service) {
             mRemoteViewsFactory = IRemoteViewsFactory.Stub.asInterface(service);
             mConnected = true;
+
             // notifyDataSetChanged should be called first, to ensure that the
             // views are not updated twice
             notifyDataSetChanged();
@@ -107,17 +108,23 @@
                     });
                 }
             });
+
+            // start the background loader
+            mViewCache.startBackgroundLoader();
         }
 
         public void onServiceDisconnected(ComponentName name) {
             mRemoteViewsFactory = null;
             mConnected = false;
-            if (mCallback != null)
-                mCallback.onRemoteAdapterDisconnected();
 
             // clear the main/worker queues
             mMainQueue.removeMessages(0);
-            mWorkerQueue.removeMessages(0);
+            
+            // stop the background loader
+            mViewCache.stopBackgroundLoader();
+
+            if (mCallback != null)
+                mCallback.onRemoteAdapterDisconnected();
         }
 
         public IRemoteViewsFactory getRemoteViewsFactory() {
@@ -135,6 +142,9 @@
     private class RemoteViewsCache {
         private RemoteViewsInfo mViewCacheInfo;
         private RemoteViewsIndexInfo[] mViewCache;
+        private int[] mTmpViewCacheLoadIndices;
+        private LinkedList<Integer> mViewCacheLoadIndices;
+        private boolean mBackgroundLoaderEnabled;
 
         // if a user loading view is not provided, then we create a temporary one
         // for the user using the height of the first view
@@ -150,16 +160,6 @@
         private int mCacheSlack;
         private final float mCacheSlackPercentage = 0.75f;
 
-        // determines whether to reorder the posted items on the worker thread
-        // so that the items in the current window can be loaded first
-        private int mPriorityLoadingWindowSize;
-        private int mPriorityLoadingWindowStart;
-        private int mPriorityLoadingWindowEnd;
-
-        // determines which way to load items in the current window based on how
-        // the window shifted last
-        private boolean mLoadUpwards;
-
         /**
          * The data structure stored at each index of the cache. Any member 
          * that is not invalidated persists throughout the lifetime of the cache.
@@ -218,22 +218,21 @@
             mCacheSlack = Math.round(mCacheSlackPercentage * mHalfCacheSize);
             mViewCacheStartPosition = 0;
             mViewCacheEndPosition = -1;
-            mPriorityLoadingWindowSize = 4;
-            mPriorityLoadingWindowStart = 0;
-            mPriorityLoadingWindowEnd = 0;
-            mLoadUpwards = false;
+            mBackgroundLoaderEnabled = false;
 
             // initialize the cache
+            int cacheSize = 2 * mHalfCacheSize + 1;
             mViewCacheInfo = new RemoteViewsInfo();
-            mViewCache = new RemoteViewsIndexInfo[2 * mHalfCacheSize + 1];
+            mViewCache = new RemoteViewsIndexInfo[cacheSize];
             for (int i = 0; i < mViewCache.length; ++i) {
                 mViewCache[i] = new RemoteViewsIndexInfo();
             }
+            mTmpViewCacheLoadIndices = new int[cacheSize];
+            mViewCacheLoadIndices = new LinkedList<Integer>();
         }
 
         private final boolean contains(int position) {
-            // take the modulo of the position
-            return (mViewCacheStartPosition <= position) && (position < mViewCacheEndPosition);
+            return (mViewCacheStartPosition <= position) && (position <= mViewCacheEndPosition);
         }
 
         private final boolean containsAndIsValid(int position) {
@@ -247,6 +246,7 @@
         }
 
         private final int getCacheIndex(int position) {
+            // take the modulo of the position
             return (mViewCache.length + (position % mViewCache.length)) % mViewCache.length;
         }
 
@@ -298,7 +298,7 @@
 
                 synchronized (mViewCache) {
                     // skip if the window has moved
-                    if (position < mViewCacheStartPosition || position >= mViewCacheEndPosition)
+                    if (position < mViewCacheStartPosition || position > mViewCacheEndPosition)
                         return;
 
                     final int positionIndex = position;
@@ -316,16 +316,28 @@
                                     RemoteViewsIndexInfo indexInfo = mViewCache[cacheIndex];
                                     FrameLayout flipper = indexInfo.flipper;
 
-                                    // recompose the flipper
-                                    View loadingView = flipper.getChildAt(0);
-                                    loadingView.setVisibility(View.GONE);
-                                    flipper.removeAllViews();
-                                    flipper.addView(loadingView);
-                                    flipper.addView(indexInfo.view.apply(mContext, flipper));
-
-                                    // hide the loader view and bring the new view to the front
-                                    flipper.requestLayout();
-                                    flipper.invalidate();
+                                    // update the flipper
+                                    flipper.getChildAt(0).setVisibility(View.GONE);
+                                    boolean addNewView = true;
+                                    if (flipper.getChildCount() > 1) {
+                                        View v = flipper.getChildAt(1);
+                                        int typeId = ((Integer) v.getTag()).intValue();
+                                        if (typeId == indexInfo.typeId) {
+                                            // we can reapply since it is the same type
+                                            indexInfo.view.reapply(mContext, v);
+                                            v.setVisibility(View.VISIBLE);
+                                            if (v.getAnimation() != null) 
+                                                v.buildDrawingCache();
+                                            addNewView = false;
+                                        } else {
+                                            flipper.removeViewAt(1);
+                                        }
+                                    }
+                                    if (addNewView) {
+                                        View v = indexInfo.view.apply(mContext, flipper);
+                                        v.setTag(new Integer(indexInfo.typeId));
+                                        flipper.addView(v);
+                                    }
                                 }
                             }
                         }
@@ -336,88 +348,52 @@
 
         private RemoteViewsIndexInfo requestCachedIndexInfo(final int position) {
             int indicesToLoadCount = 0;
-            int[] indicesToLoad = null;
 
             synchronized (mViewCache) {
-                indicesToLoad = new int[mViewCache.length];
-                Arrays.fill(indicesToLoad, 0);
-
                 if (containsAndIsValid(position)) {
                     // return the info if it exists in the window and is loaded
                     return mViewCache[getCacheIndex(position)];
-                } 
+                }
 
                 // if necessary update the window and load the new information
                 int centerPosition = (mViewCacheEndPosition + mViewCacheStartPosition) / 2;
                 if ((mViewCacheEndPosition <= mViewCacheStartPosition) || (Math.abs(position - centerPosition) > mCacheSlack)) {
                     int newStartPosition = position - mHalfCacheSize;
                     int newEndPosition = position + mHalfCacheSize;
+                    int frameSize = mHalfCacheSize / 4;
+                    int frameCount = (int) Math.ceil(mViewCache.length / (float) frameSize);
 
                     // prune/add before the current start position
                     int effectiveStart = Math.max(newStartPosition, 0);
-                    int effectiveEnd = Math.min(newEndPosition, getCount());
-
-                    mWorkerQueue.removeMessages(0);
+                    int effectiveEnd = Math.min(newEndPosition, getCount() - 1);
 
                     // invalidate items in the queue
-                    boolean loadFromBeginning = effectiveStart < mViewCacheStartPosition;
-                    int numLoadFromBeginning = mViewCacheStartPosition - effectiveStart;
-                    boolean loadFromEnd = effectiveEnd > mViewCacheEndPosition;
                     int overlapStart = Math.max(mViewCacheStartPosition, effectiveStart);
                     int overlapEnd = Math.min(Math.max(mViewCacheStartPosition, mViewCacheEndPosition), effectiveEnd);
-                    for (int i = newStartPosition; i < newEndPosition; ++i) {
-                        if (loadFromBeginning && (effectiveStart <= i) && (i < overlapStart)) {
-                            // load new items at the beginning in reverse order
-                            mViewCache[getCacheIndex(i)].invalidate();
-                            indicesToLoad[indicesToLoadCount++] = effectiveStart
-                                    + (numLoadFromBeginning - (i - effectiveStart) - 1);
-                        } else if (loadFromEnd && (overlapEnd <= i) && (i < effectiveEnd)) {
-                            mViewCache[getCacheIndex(i)].invalidate();
-                            indicesToLoad[indicesToLoadCount++] = i;
-                        } else if ((overlapStart <= i) && (i < overlapEnd)) {
-                            // load the stuff in the middle that has not already
-                            // been loaded
-                            if (!mViewCache[getCacheIndex(i)].isValid()) {
-                                indicesToLoad[indicesToLoadCount++] = i;
+                    for (int i = 0; i < (frameSize * frameCount); ++i) {
+                        int index = newStartPosition + ((i % frameSize) * frameCount + (i / frameSize));
+                        
+                        if (index <= newEndPosition) {
+                            if ((overlapStart <= index) && (index <= overlapEnd)) {
+                                // load the stuff in the middle that has not already
+                                // been loaded
+                                if (!mViewCache[getCacheIndex(index)].isValid()) {
+                                    mTmpViewCacheLoadIndices[indicesToLoadCount++] = index;
+                                }
+                            } else if ((effectiveStart <= index) && (index <= effectiveEnd)) {
+                                // invalidate and load all new effective items
+                                mViewCache[getCacheIndex(index)].invalidate();
+                                mTmpViewCacheLoadIndices[indicesToLoadCount++] = index;
+                            } else {
+                                // invalidate all other cache indices (outside the effective start/end)
+                                // but don't load
+                                mViewCache[getCacheIndex(index)].invalidate();
                             }
-                        } else {
-                            // invalidate all other cache indices (outside the effective start/end)
-                            mViewCache[getCacheIndex(i)].invalidate();
                         }
                     }
 
                     mViewCacheStartPosition = newStartPosition;
                     mViewCacheEndPosition = newEndPosition;
-                    mPriorityLoadingWindowStart = position;
-                    mPriorityLoadingWindowEnd = position + mPriorityLoadingWindowSize;
-                    mLoadUpwards = loadFromBeginning && !loadFromEnd;
-                } else if (contains(position)) {
-                    // prioritize items around this position so that they load first
-                    if (position < mPriorityLoadingWindowStart || position > mPriorityLoadingWindowEnd) {
-                        mWorkerQueue.removeMessages(0);
-
-                        int index;
-                        int effectiveStart = Math.max(position - mPriorityLoadingWindowSize, 0);
-                        int effectiveEnd = 0;
-                        synchronized (mViewCacheInfo) {
-                            effectiveEnd = Math.min(position + mPriorityLoadingWindowSize - 1,
-                                    mViewCacheInfo.count - 1);
-                        }
-
-                        for (int i = 0; i < mViewCache.length; ++i) {
-                            if (mLoadUpwards) {
-                                index = effectiveEnd - i;
-                            } else {
-                                index = effectiveStart + i;
-                            }
-                            if (!mViewCache[getCacheIndex(index)].isValid()) {
-                                indicesToLoad[indicesToLoadCount++] = index;
-                            }
-                        }
-
-                        mPriorityLoadingWindowStart = effectiveStart;
-                        mPriorityLoadingWindowEnd = position + mPriorityLoadingWindowSize;
-                    }
                 }
             }
 
@@ -426,15 +402,15 @@
             synchronized (mViewCacheInfo) {
                 length = mViewCacheInfo.count;
             }
-            for (int i = 0; i < indicesToLoadCount; ++i) {
-                final int index = indicesToLoad[i];
-                if (0 <= index && index < length) {
-                    mWorkerQueue.post(new Runnable() {
-                        @Override
-                        public void run() {
-                            updateRemoteViewsInfo(index);
+            if (indicesToLoadCount > 0) {
+                synchronized (mViewCacheLoadIndices) {
+                    mViewCacheLoadIndices.clear();
+                    for (int i = 0; i < indicesToLoadCount; ++i) {
+                        final int index = mTmpViewCacheLoadIndices[i];
+                        if (0 <= index && index < length) {
+                            mViewCacheLoadIndices.addLast(index);
                         }
-                    });
+                    }
                 }
             }
 
@@ -446,7 +422,7 @@
             if (mServiceConnection.isConnected()) {
                 // create the flipper views if necessary (we have to do this now
                 // for all the flippers while we have the reference to the parent)
-                createInitialLoadingFlipperViews(parent);
+                initializeLoadingViews(parent);
 
                 // request the item from the cache (queueing it to load if not
                 // in the cache already)
@@ -456,6 +432,7 @@
                 synchronized (mViewCache) {
                     int cacheIndex = getCacheIndex(position);
                     FrameLayout flipper = mViewCache[cacheIndex].flipper;
+                    flipper.setVisibility(View.VISIBLE);
 
                     if (indexInfo == null) {
                         // hide the item view and show the loading view
@@ -463,17 +440,12 @@
                         for (int i = 1; i < flipper.getChildCount(); ++i) {
                             flipper.getChildAt(i).setVisibility(View.GONE);
                         }
-                        flipper.requestLayout();
-                        flipper.invalidate();
                     } else {
                         // hide the loading view and show the item view
-                        flipper.setVisibility(View.VISIBLE);
                         for (int i = 0; i < flipper.getChildCount() - 1; ++i) {
                             flipper.getChildAt(i).setVisibility(View.GONE);
                         }
                         flipper.getChildAt(flipper.getChildCount() - 1).setVisibility(View.VISIBLE);
-                        flipper.requestLayout();
-                        flipper.invalidate();
                     }
                     return flipper;
                 }
@@ -481,7 +453,7 @@
             return new View(mContext);
         }
 
-        private void createInitialLoadingFlipperViews(ViewGroup parent) {
+        private void initializeLoadingViews(ViewGroup parent) {
             // ensure that the cache has the appropriate initial flipper
             synchronized (mViewCache) {
                 if (mViewCache[0].flipper == null) {
@@ -519,6 +491,50 @@
             }
         }
 
+        public void startBackgroundLoader() {
+            // initialize the worker runnable
+            mBackgroundLoaderEnabled = true;
+            mWorkerQueue.post(new Runnable() {
+                @Override
+                public void run() {
+                    while (mBackgroundLoaderEnabled) {
+                        int index = -1;
+                        synchronized (mViewCacheLoadIndices) {
+                            if (!mViewCacheLoadIndices.isEmpty()) {
+                                index = mViewCacheLoadIndices.removeFirst();
+                            }
+                        }
+                        if (index < 0) {
+                            // there were no items to load, so sleep for a bit
+                            try {
+                                Thread.sleep(10);
+                            } catch (InterruptedException e) {
+                                e.printStackTrace();
+                            }
+                        } else {
+                            // otherwise, try and load the item
+                            updateRemoteViewsInfo(index);
+
+                            // sleep for a bit to allow things to catch up after the load
+                            try {
+                                Thread.sleep(50);
+                            } catch (InterruptedException e) {
+                                e.printStackTrace();
+                            }
+                        }
+                    }
+                }
+            });
+        }
+
+        public void stopBackgroundLoader() {
+            // clear the items to be loaded
+            mBackgroundLoaderEnabled = false;
+            synchronized (mViewCacheLoadIndices) {
+                mViewCacheLoadIndices.clear();
+            }
+        }
+
         public long getItemId(int position) {
             synchronized (mViewCache) {
                 if (containsAndIsValid(position)) {
@@ -567,9 +583,13 @@
         }
 
         public void flushCache() {
+            // clear the items to be loaded
+            synchronized (mViewCacheLoadIndices) {
+                mViewCacheLoadIndices.clear();
+            }
+
             synchronized (mViewCache) {
                 // flush the internal cache and invalidate the adapter for future loads
-                mWorkerQueue.removeMessages(0);
                 mMainQueue.removeMessages(0);
 
                 for (int i = 0; i < mViewCache.length; ++i) {
diff --git a/include/media/stagefright/CameraSourceTimeLapse.h b/include/media/stagefright/CameraSourceTimeLapse.h
index f153f09..fa11b3e 100644
--- a/include/media/stagefright/CameraSourceTimeLapse.h
+++ b/include/media/stagefright/CameraSourceTimeLapse.h
@@ -33,11 +33,13 @@
 public:
     static CameraSourceTimeLapse *Create(bool useStillCameraForTimeLapse,
         int64_t timeBetweenTimeLapseFrameCaptureUs,
+        int32_t width, int32_t height,
         int32_t videoFrameRate);
 
     static CameraSourceTimeLapse *CreateFromCamera(const sp<Camera> &camera,
         bool useStillCameraForTimeLapse,
         int64_t timeBetweenTimeLapseFrameCaptureUs,
+        int32_t width, int32_t height,
         int32_t videoFrameRate);
 
     virtual ~CameraSourceTimeLapse();
@@ -70,6 +72,7 @@
     CameraSourceTimeLapse(const sp<Camera> &camera,
         bool useStillCameraForTimeLapse,
         int64_t timeBetweenTimeLapseFrameCaptureUs,
+        int32_t width, int32_t height,
         int32_t videoFrameRate);
 
     // For still camera case starts a thread which calls camera's takePicture()
diff --git a/include/media/stagefright/MediaSource.h b/include/media/stagefright/MediaSource.h
index a31395e..dafc621 100644
--- a/include/media/stagefright/MediaSource.h
+++ b/include/media/stagefright/MediaSource.h
@@ -78,18 +78,31 @@
         void clearSeekTo();
         bool getSeekTo(int64_t *time_us, SeekMode *mode) const;
 
+        // Option allows encoder to skip some frames until the specified
+        // time stamp.
+        // To prevent from being abused, when the skipFrame timestamp is
+        // found to be more than 1 second later than the current timestamp,
+        // an error will be returned from read().
+        void clearSkipFrame();
+        bool getSkipFrame(int64_t *timeUs) const;
+        void setSkipFrame(int64_t timeUs);
+
         void setLateBy(int64_t lateness_us);
         int64_t getLateBy() const;
 
     private:
         enum Options {
+            // Bit map
             kSeekTo_Option      = 1,
+            kSkipFrame_Option   = 2,
         };
 
         uint32_t mOptions;
         int64_t mSeekTimeUs;
         SeekMode mSeekMode;
         int64_t mLatenessUs;
+
+        int64_t mSkipFrameUntilTimeUs;
     };
 
     // Causes this source to suspend pulling data from its upstream source
diff --git a/include/media/stagefright/OMXCodec.h b/include/media/stagefright/OMXCodec.h
index 79e7a2f..6c6949b 100644
--- a/include/media/stagefright/OMXCodec.h
+++ b/include/media/stagefright/OMXCodec.h
@@ -143,6 +143,7 @@
     int64_t mSeekTimeUs;
     ReadOptions::SeekMode mSeekMode;
     int64_t mTargetTimeUs;
+    int64_t mSkipTimeUs;
 
     MediaBuffer *mLeftOverBuffer;
 
diff --git a/libs/gui/Sensor.cpp b/libs/gui/Sensor.cpp
index 48e1cb7..cb85df9 100644
--- a/libs/gui/Sensor.cpp
+++ b/libs/gui/Sensor.cpp
@@ -89,7 +89,7 @@
     return  sizeof(int32_t) + ((mName.length() + 3) & ~3) +
             sizeof(int32_t) + ((mVendor.length() + 3) & ~3) +
             sizeof(int32_t) * 2 +
-            sizeof(float) * 3;
+            sizeof(float) * 4;
 }
 
 size_t Sensor::getFdCount() const
diff --git a/libs/hwui/Extensions.h b/libs/hwui/Extensions.h
new file mode 100644
index 0000000..99b34dd
--- /dev/null
+++ b/libs/hwui/Extensions.h
@@ -0,0 +1,79 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "OpenGLRenderer"
+
+#ifndef ANDROID_UI_EXTENSIONS_H
+#define ANDROID_UI_EXTENSIONS_H
+
+#include <utils/SortedVector.h>
+#include <utils/String8.h>
+
+#include <GLES2/gl2.h>
+#include <GLES2/gl2ext.h>
+
+namespace android {
+namespace uirenderer {
+
+class Extensions {
+public:
+    Extensions() {
+        const char* buffer = (const char*) glGetString(GL_EXTENSIONS);
+        const char* current = buffer;
+        const char* head = current;
+        do {
+            head = strchr(current, ' ');
+            String8 s(current, head ? head - current : strlen(current));
+            if (s.length()) {
+                mExtensionList.add(s);
+            }
+            current = head + 1;
+        } while (head);
+
+        mHasNPot = hasExtension("GL_OES_texture_npot");
+        mHasDrawPath = hasExtension("GL_NV_draw_path");
+        mHasCoverageSample = hasExtension("GL_NV_coverage_sample");
+
+        mExtensions = buffer;
+    }
+
+    inline bool hasNPot() const { return mHasNPot; }
+    inline bool hasDrawPath() const { return mHasDrawPath; }
+    inline bool hasCoverageSample() const { return mHasCoverageSample; }
+
+    bool hasExtension(const char* extension) const {
+        const String8 s(extension);
+        return mExtensionList.indexOf(s) >= 0;
+    }
+
+    void dump() {
+        LOGD("Supported extensions:\n%s", mExtensions);
+    }
+
+private:
+    SortedVector<String8> mExtensionList;
+
+    const char* mExtensions;
+
+    bool mHasNPot;
+    bool mHasDrawPath;
+    bool mHasCoverageSample;
+}; // class Extensions
+
+}; // namespace uirenderer
+}; // namespace android
+
+#endif // ANDROID_UI_EXTENSIONS_H
diff --git a/libs/hwui/FontRenderer.cpp b/libs/hwui/FontRenderer.cpp
index 5ab89e2..24dee55 100644
--- a/libs/hwui/FontRenderer.cpp
+++ b/libs/hwui/FontRenderer.cpp
@@ -16,14 +16,24 @@
 
 #define LOG_TAG "OpenGLRenderer"
 
-#include "FontRenderer.h"
-
 #include <SkUtils.h>
 
+#include <cutils/properties.h>
+#include <utils/Log.h>
+
+#include "FontRenderer.h"
+
 namespace android {
 namespace uirenderer {
 
 ///////////////////////////////////////////////////////////////////////////////
+// Defines
+///////////////////////////////////////////////////////////////////////////////
+
+#define DEFAULT_TEXT_CACHE_WIDTH 1024
+#define DEFAULT_TEXT_CACHE_HEIGHT 256
+
+///////////////////////////////////////////////////////////////////////////////
 // Font
 ///////////////////////////////////////////////////////////////////////////////
 
@@ -41,7 +51,7 @@
     }
 
     for (uint32_t i = 0; i < mCachedGlyphs.size(); i++) {
-        CachedGlyphInfo *glyph = mCachedGlyphs.valueAt(i);
+        CachedGlyphInfo* glyph = mCachedGlyphs.valueAt(i);
         delete glyph;
     }
 }
@@ -53,19 +63,24 @@
 }
 
 void Font::drawCachedGlyph(CachedGlyphInfo* glyph, int x, int y) {
-    FontRenderer *state = mState;
-
     int nPenX = x + glyph->mBitmapLeft;
     int nPenY = y + glyph->mBitmapTop + glyph->mBitmapHeight;
 
-    state->appendMeshQuad(nPenX, nPenY, 0, glyph->mBitmapMinU, glyph->mBitmapMaxV,
-            nPenX + (int) glyph->mBitmapWidth, nPenY, 0, glyph->mBitmapMaxU, glyph->mBitmapMaxV,
-            nPenX + (int) glyph->mBitmapWidth, nPenY - (int) glyph->mBitmapHeight,
-            0, glyph->mBitmapMaxU, glyph->mBitmapMinV, nPenX, nPenY - (int) glyph->mBitmapHeight,
-            0, glyph->mBitmapMinU, glyph->mBitmapMinV);
+    float u1 = glyph->mBitmapMinU;
+    float u2 = glyph->mBitmapMaxU;
+    float v1 = glyph->mBitmapMinV;
+    float v2 = glyph->mBitmapMaxV;
+
+    int width = (int) glyph->mBitmapWidth;
+    int height = (int) glyph->mBitmapHeight;
+
+    mState->appendMeshQuad(nPenX, nPenY, 0, u1, v2,
+            nPenX + width, nPenY, 0, u2, v2,
+            nPenX + width, nPenY - height, 0, u2, v1,
+            nPenX, nPenY - height, 0, u1, v1);
 }
 
-void Font::renderUTF(SkPaint* paint, const char *text, uint32_t len, uint32_t start,
+void Font::renderUTF(SkPaint* paint, const char* text, uint32_t start, uint32_t len,
         int numGlyphs, int x, int y) {
     if (numGlyphs == 0 || text == NULL || len == 0) {
         return;
@@ -77,13 +92,9 @@
         glyphsLeft = numGlyphs;
     }
 
-    //size_t index = start;
-    //size_t nextIndex = 0;
-
     text += start;
 
     while (glyphsLeft > 0) {
-        //int32_t utfChar = utf32_at(text, len, index, &nextIndex);
         int32_t utfChar = SkUTF16_NextUnichar((const uint16_t**) &text);
 
         // Reached the end of the string or encountered
@@ -91,14 +102,11 @@
             break;
         }
 
-        // Move to the next character in the array
-        //index = nextIndex;
-
-        CachedGlyphInfo *cachedGlyph = mCachedGlyphs.valueFor(utfChar);
-
+        CachedGlyphInfo* cachedGlyph = mCachedGlyphs.valueFor(utfChar);
         if (cachedGlyph == NULL) {
             cachedGlyph = cacheGlyph(paint, utfChar);
         }
+
         // Is the glyph still in texture cache?
         if (!cachedGlyph->mIsValid) {
             const SkGlyph& skiaGlyph = paint->getUnicharMetrics(utfChar);
@@ -119,7 +127,7 @@
     }
 }
 
-void Font::updateGlyphCache(SkPaint* paint, const SkGlyph& skiaGlyph, CachedGlyphInfo *glyph) {
+void Font::updateGlyphCache(SkPaint* paint, const SkGlyph& skiaGlyph, CachedGlyphInfo* glyph) {
     glyph->mAdvanceX = skiaGlyph.fAdvanceX;
     glyph->mAdvanceY = skiaGlyph.fAdvanceY;
     glyph->mBitmapLeft = skiaGlyph.fLeft;
@@ -128,11 +136,9 @@
     uint32_t startX = 0;
     uint32_t startY = 0;
 
-    // Let the font state figure out where to put the bitmap
-    FontRenderer *state = mState;
     // Get the bitmap for the glyph
     paint->findImage(skiaGlyph);
-    glyph->mIsValid = state->cacheBitmap(skiaGlyph, &startX, &startY);
+    glyph->mIsValid = mState->cacheBitmap(skiaGlyph, &startX, &startY);
 
     if (!glyph->mIsValid) {
         return;
@@ -144,19 +150,19 @@
     glyph->mBitmapWidth = skiaGlyph.fWidth;
     glyph->mBitmapHeight = skiaGlyph.fHeight;
 
-    uint32_t cacheWidth = state->getCacheWidth();
-    uint32_t cacheHeight = state->getCacheHeight();
+    uint32_t cacheWidth = mState->getCacheWidth();
+    uint32_t cacheHeight = mState->getCacheHeight();
 
     glyph->mBitmapMinU = (float) startX / (float) cacheWidth;
     glyph->mBitmapMinV = (float) startY / (float) cacheHeight;
     glyph->mBitmapMaxU = (float) endX / (float) cacheWidth;
     glyph->mBitmapMaxV = (float) endY / (float) cacheHeight;
 
-    state->mUploadTexture = true;
+    mState->mUploadTexture = true;
 }
 
-Font::CachedGlyphInfo *Font::cacheGlyph(SkPaint* paint, int32_t glyph) {
-    CachedGlyphInfo *newGlyph = new CachedGlyphInfo();
+Font::CachedGlyphInfo* Font::cacheGlyph(SkPaint* paint, int32_t glyph) {
+    CachedGlyphInfo* newGlyph = new CachedGlyphInfo();
     mCachedGlyphs.add(glyph, newGlyph);
 
     const SkGlyph& skiaGlyph = paint->getUnicharMetrics(glyph);
@@ -172,9 +178,9 @@
     Vector<Font*> &activeFonts = state->mActiveFonts;
 
     for (uint32_t i = 0; i < activeFonts.size(); i++) {
-        Font *ithFont = activeFonts[i];
-        if (ithFont->mFontId == fontId && ithFont->mFontSize == fontSize) {
-            return ithFont;
+        Font* font = activeFonts[i];
+        if (font->mFontId == fontId && font->mFontSize == fontSize) {
+            return font;
         }
     }
 
@@ -188,14 +194,31 @@
 ///////////////////////////////////////////////////////////////////////////////
 
 FontRenderer::FontRenderer() {
+    LOGD("Creating FontRenderer");
+
     mInitialized = false;
     mMaxNumberOfQuads = 1024;
     mCurrentQuadIndex = 0;
 
     mIndexBufferID = 0;
 
-    mCacheWidth = 1024;
-    mCacheHeight = 256;
+    mCacheWidth = DEFAULT_TEXT_CACHE_WIDTH;
+    mCacheHeight = DEFAULT_TEXT_CACHE_WIDTH;
+
+    char property[PROPERTY_VALUE_MAX];
+    if (property_get(PROPERTY_TEXT_CACHE_WIDTH, property, NULL) > 0) {
+        LOGD("  Setting text cache width to %s pixels", property);
+        mCacheWidth = atoi(property);
+    } else {
+        LOGD("  Using default text cache width of %i pixels", mCacheWidth);
+    }
+
+    if (property_get(PROPERTY_TEXT_CACHE_HEIGHT, property, NULL) > 0) {
+        LOGD("  Setting text cache width to %s pixels", property);
+        mCacheHeight = atoi(property);
+    } else {
+        LOGD("  Using default text cache height of %i pixels", mCacheHeight);
+    }
 }
 
 FontRenderer::~FontRenderer() {
@@ -225,7 +248,7 @@
     }
 }
 
-bool FontRenderer::cacheBitmap(const SkGlyph& glyph, uint32_t *retOriginX, uint32_t *retOriginY) {
+bool FontRenderer::cacheBitmap(const SkGlyph& glyph, uint32_t* retOriginX, uint32_t* retOriginY) {
     // If the glyph is too tall, don't cache it
     if (glyph.fWidth > mCacheLines[mCacheLines.size() - 1]->mMaxHeight) {
         LOGE("Font size to large to fit in cache. width, height = %i, %i",
@@ -273,8 +296,8 @@
 
     uint32_t cacheWidth = mCacheWidth;
 
-    unsigned char *cacheBuffer = mTextTexture;
-    unsigned char *bitmapBuffer = (unsigned char*) glyph.fImage;
+    unsigned char* cacheBuffer = mTextTexture;
+    unsigned char* bitmapBuffer = (unsigned char*) glyph.fImage;
     unsigned int stride = glyph.rowBytes();
 
     uint32_t cacheX = 0, bX = 0, cacheY = 0, bY = 0;
@@ -304,24 +327,24 @@
 
     // Split up our cache texture into lines of certain widths
     int nextLine = 0;
-    mCacheLines.push(new CacheTextureLine(16, mCacheWidth, nextLine, 0));
+    mCacheLines.push(new CacheTextureLine(mCacheWidth, 16, nextLine, 0));
     nextLine += mCacheLines.top()->mMaxHeight;
-    mCacheLines.push(new CacheTextureLine(24, mCacheWidth, nextLine, 0));
+    mCacheLines.push(new CacheTextureLine(mCacheWidth, 24, nextLine, 0));
     nextLine += mCacheLines.top()->mMaxHeight;
-    mCacheLines.push(new CacheTextureLine(32, mCacheWidth, nextLine, 0));
+    mCacheLines.push(new CacheTextureLine(mCacheWidth, 32, nextLine, 0));
     nextLine += mCacheLines.top()->mMaxHeight;
-    mCacheLines.push(new CacheTextureLine(32, mCacheWidth, nextLine, 0));
+    mCacheLines.push(new CacheTextureLine(mCacheWidth, 32, nextLine, 0));
     nextLine += mCacheLines.top()->mMaxHeight;
-    mCacheLines.push(new CacheTextureLine(40, mCacheWidth, nextLine, 0));
+    mCacheLines.push(new CacheTextureLine(mCacheWidth, 40, nextLine, 0));
     nextLine += mCacheLines.top()->mMaxHeight;
-    mCacheLines.push(new CacheTextureLine(mCacheHeight - nextLine, mCacheWidth, nextLine, 0));
+    mCacheLines.push(new CacheTextureLine(mCacheWidth, mCacheHeight - nextLine, nextLine, 0));
 }
 
 // Avoid having to reallocate memory and render quad by quad
 void FontRenderer::initVertexArrayBuffers() {
     uint32_t numIndicies = mMaxNumberOfQuads * 6;
     uint32_t indexBufferSizeBytes = numIndicies * sizeof(uint16_t);
-    uint16_t *indexBufferData = (uint16_t*) malloc(indexBufferSizeBytes);
+    uint16_t* indexBufferData = (uint16_t*) malloc(indexBufferSizeBytes);
 
     // Four verts, two triangles , six indices per quad
     for (uint32_t i = 0; i < mMaxNumberOfQuads; i++) {
@@ -372,8 +395,8 @@
         mUploadTexture = false;
     }
 
-    float *vtx = mTextMeshPtr;
-    float *tex = vtx + 3;
+    float* vtx = mTextMeshPtr;
+    float* tex = vtx + 3;
 
     // position is slot 0
     uint32_t slot = 0;
@@ -396,7 +419,7 @@
 
     const uint32_t vertsPerQuad = 4;
     const uint32_t floatsPerVert = 5;
-    float *currentPos = mTextMeshPtr + mCurrentQuadIndex * vertsPerQuad * floatsPerVert;
+    float* currentPos = mTextMeshPtr + mCurrentQuadIndex * vertsPerQuad * floatsPerVert;
 
     (*currentPos++) = x1;
     (*currentPos++) = y1;
@@ -434,8 +457,8 @@
     mCurrentFont = Font::create(this, fontId, fontSize);
 }
 
-void FontRenderer::renderText(SkPaint* paint, const Rect* clip, const char *text, uint32_t len,
-        uint32_t startIndex, int numGlyphs, int x, int y) {
+void FontRenderer::renderText(SkPaint* paint, const Rect* clip, const char *text,
+        uint32_t startIndex, uint32_t len, int numGlyphs, int x, int y) {
     checkInit();
 
     if (!mCurrentFont) {
@@ -444,7 +467,7 @@
     }
 
     mClip = clip;
-    mCurrentFont->renderUTF(paint, text, len, startIndex, numGlyphs, x, y);
+    mCurrentFont->renderUTF(paint, text, startIndex, len, numGlyphs, x, y);
 
     if (mCurrentQuadIndex != 0) {
         issueDrawCommand();
diff --git a/libs/hwui/FontRenderer.h b/libs/hwui/FontRenderer.h
index b73a96e..c1cd7fb 100644
--- a/libs/hwui/FontRenderer.h
+++ b/libs/hwui/FontRenderer.h
@@ -27,26 +27,34 @@
 #include <GLES2/gl2.h>
 
 #include "Rect.h"
+#include "Properties.h"
 
 namespace android {
 namespace uirenderer {
 
 class FontRenderer;
 
+/**
+ * Represents a font, defined by a Skia font id and a font size. A font is used
+ * to generate glyphs and cache them in the FontState.
+ */
 class Font {
 public:
     ~Font();
 
-    void renderUTF(SkPaint* paint, const char *text, uint32_t len, uint32_t start,
+    /**
+     * Renders the specified string of text.
+     */
+    void renderUTF(SkPaint* paint, const char *text, uint32_t start, uint32_t len,
             int numGlyphs, int x, int y);
-
+    /**
+     * Creates a new font associated with the specified font state.
+     */
     static Font* create(FontRenderer* state, uint32_t fontId, float fontSize);
 
 protected:
-
     friend class FontRenderer;
 
-    void invalidateTextureCache();
     struct CachedGlyphInfo {
         // Has the cache been invalidated?
         bool mIsValid;
@@ -68,17 +76,19 @@
         uint32_t mBitmapTop;
     };
 
-    FontRenderer* mState;
-    uint32_t mFontId;
-    float mFontSize;
-
     Font(FontRenderer* state, uint32_t fontId, float fontSize);
 
     DefaultKeyedVector<int32_t, CachedGlyphInfo*> mCachedGlyphs;
 
+    void invalidateTextureCache();
+
     CachedGlyphInfo *cacheGlyph(SkPaint* paint, int32_t glyph);
     void updateGlyphCache(SkPaint* paint, const SkGlyph& skiaGlyph, CachedGlyphInfo *glyph);
     void drawCachedGlyph(CachedGlyphInfo *glyph, int x, int y);
+
+    FontRenderer* mState;
+    uint32_t mFontId;
+    float mFontSize;
 };
 
 class FontRenderer {
@@ -90,8 +100,8 @@
     void deinit();
 
     void setFont(uint32_t fontId, float fontSize);
-    void renderText(SkPaint* paint, const Rect* clip, const char *text, uint32_t len,
-            uint32_t startIndex, int numGlyphs, int x, int y);
+    void renderText(SkPaint* paint, const Rect* clip, const char *text, uint32_t startIndex,
+            uint32_t len, int numGlyphs, int x, int y);
 
     GLuint getTexture() {
         checkInit();
@@ -107,10 +117,12 @@
         uint32_t mCurrentRow;
         uint32_t mCurrentCol;
 
-        CacheTextureLine(uint16_t maxHeight, uint16_t maxWidth, uint32_t currentRow,
+        CacheTextureLine(uint16_t maxWidth, uint16_t maxHeight, uint32_t currentRow,
                 uint32_t currentCol):
-            mMaxHeight(maxHeight), mMaxWidth(maxWidth), mCurrentRow(currentRow),
-            mCurrentCol(currentCol) {
+                    mMaxHeight(maxHeight),
+                    mMaxWidth(maxWidth),
+                    mCurrentRow(currentRow),
+                    mCurrentCol(currentCol) {
         }
 
         bool fitBitmap(const SkGlyph& glyph, uint32_t *retOriginX, uint32_t *retOriginY) {
diff --git a/libs/hwui/OpenGLRenderer.cpp b/libs/hwui/OpenGLRenderer.cpp
index 58a3a69..c6a2e33 100644
--- a/libs/hwui/OpenGLRenderer.cpp
+++ b/libs/hwui/OpenGLRenderer.cpp
@@ -27,6 +27,7 @@
 #include <utils/Log.h>
 
 #include "OpenGLRenderer.h"
+#include "Properties.h"
 
 namespace android {
 namespace uirenderer {
@@ -35,11 +36,6 @@
 // Defines
 ///////////////////////////////////////////////////////////////////////////////
 
-// These properties are defined in mega-bytes
-#define PROPERTY_TEXTURE_CACHE_SIZE "ro.hwui.texture_cache_size"
-#define PROPERTY_LAYER_CACHE_SIZE "ro.hwui.layer_cache_size"
-#define PROPERTY_GRADIENT_CACHE_SIZE "ro.hwui.gradient_cache_size"
-
 #define DEFAULT_TEXTURE_CACHE_SIZE 20.0f
 #define DEFAULT_LAYER_CACHE_SIZE 10.0f
 #define DEFAULT_PATCH_CACHE_SIZE 100
@@ -555,7 +551,7 @@
     const Rect& clip = mSnapshot->getLocalClip();
 
     mFontRenderer.setFont(SkTypeface::UniqueID(paint->getTypeface()), paint->getTextSize());
-    mFontRenderer.renderText(paint, &clip, text, count, 0, count, x, y);
+    mFontRenderer.renderText(paint, &clip, text, 0, count, count, x, y);
 
     glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
 }
diff --git a/libs/hwui/OpenGLRenderer.h b/libs/hwui/OpenGLRenderer.h
index b82366b..43e568f 100644
--- a/libs/hwui/OpenGLRenderer.h
+++ b/libs/hwui/OpenGLRenderer.h
@@ -30,6 +30,7 @@
 #include <utils/RefBase.h>
 #include <utils/ResourceTypes.h>
 
+#include "Extensions.h"
 #include "Matrix.h"
 #include "Program.h"
 #include "Rect.h"
@@ -361,6 +362,9 @@
     float* mShaderPositions;
     int mShaderCount;
 
+    // GL extensions
+    Extensions mExtensions;
+
     // Font renderer
     FontRenderer mFontRenderer;
 
diff --git a/libs/hwui/Properties.h b/libs/hwui/Properties.h
new file mode 100644
index 0000000..4f20a95
--- /dev/null
+++ b/libs/hwui/Properties.h
@@ -0,0 +1,35 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ANDROID_UI_PROPERTIES_H
+#define ANDROID_UI_PROPERTIES_H
+
+/**
+ * This file contains the list of system properties used to configure
+ * the OpenGLRenderer.
+ */
+
+// These properties are defined in mega-bytes
+#define PROPERTY_TEXTURE_CACHE_SIZE "ro.hwui.texture_cache_size"
+#define PROPERTY_LAYER_CACHE_SIZE "ro.hwui.layer_cache_size"
+#define PROPERTY_GRADIENT_CACHE_SIZE "ro.hwui.gradient_cache_size"
+
+// These properties are defined in pixels
+#define PROPERTY_TEXT_CACHE_WIDTH "ro.hwui.text_cache_width"
+#define PROPERTY_TEXT_CACHE_HEIGHT "ro.hwui.text_cache_height"
+
+#endif // ANDROID_UI_PROPERTIES_H
+
diff --git a/libs/hwui/TextureCache.cpp b/libs/hwui/TextureCache.cpp
index ff9e2aff..4975edb 100644
--- a/libs/hwui/TextureCache.cpp
+++ b/libs/hwui/TextureCache.cpp
@@ -128,6 +128,11 @@
     glPixelStorei(GL_UNPACK_ALIGNMENT, bitmap->bytesPerPixel());
 
     switch (bitmap->getConfig()) {
+    case SkBitmap::kA8_Config:
+        texture->blend = true;
+        glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, bitmap->rowBytesAsPixels(), texture->height, 0,
+                GL_ALPHA, GL_UNSIGNED_BYTE, bitmap->getPixels());
+        break;
     case SkBitmap::kRGB_565_Config:
         texture->blend = false;
         glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, bitmap->rowBytesAsPixels(), texture->height, 0,
diff --git a/libs/rs/java/ImageProcessing/src/com/android/rs/image/horizontal_blur.rs b/libs/rs/java/ImageProcessing/src/com/android/rs/image/horizontal_blur.rs
index 12180c6..4ed5aba4 100644
--- a/libs/rs/java/ImageProcessing/src/com/android/rs/image/horizontal_blur.rs
+++ b/libs/rs/java/ImageProcessing/src/com/android/rs/image/horizontal_blur.rs
@@ -7,31 +7,44 @@
     const FilterStruct *fs = (const FilterStruct *)usrData;
     const uchar4 *input = (const uchar4 *)rsGetElementAt(fs->ain, 0, y);
 
-    float4 blurredPixel = 0;
-    float4 currentPixel = 0;
+    float3 blurredPixel = 0;
+    float3 currentPixel = 0;
 
-    for(int r = -fs->radius; r <= fs->radius; r ++) {
-        // Stepping left and right away from the pixel
-        int validW = x + r;
-        // Clamp to zero and width max() isn't exposed for ints yet
-        if(validW < 0) {
-            validW = 0;
+    const float *gPtr = fs->gaussian;
+    if ((x > fs->radius) && (x < (fs->width - fs->radius))) {
+        const uchar4 *i = input + (x - fs->radius);
+        for(int r = -fs->radius; r <= fs->radius; r ++) {
+            currentPixel.x = (float)(i->x);
+            currentPixel.y = (float)(i->y);
+            currentPixel.z = (float)(i->z);
+            blurredPixel += currentPixel * gPtr[0];
+            gPtr++;
+            i++;
         }
-        if(validW > fs->width - 1) {
-            validW = fs->width - 1;
+    } else {
+        for(int r = -fs->radius; r <= fs->radius; r ++) {
+            // Stepping left and right away from the pixel
+            int validW = x + r;
+            // Clamp to zero and width max() isn't exposed for ints yet
+            if(validW < 0) {
+                validW = 0;
+            }
+            if(validW > fs->width - 1) {
+                validW = fs->width - 1;
+            }
+            //int validW = rsClamp(w + r, 0, width - 1);
+
+            currentPixel.x = (float)(input[validW].x);
+            currentPixel.y = (float)(input[validW].y);
+            currentPixel.z = (float)(input[validW].z);
+
+            blurredPixel += currentPixel * gPtr[0];
+            gPtr++;
         }
-        //int validW = rsClamp(w + r, 0, width - 1);
-
-        float weight = fs->gaussian[r + fs->radius];
-        currentPixel.x = (float)(input[validW].x);
-        currentPixel.y = (float)(input[validW].y);
-        currentPixel.z = (float)(input[validW].z);
-        //currentPixel.w = (float)(input->a);
-
-        blurredPixel += currentPixel * weight;
     }
 
     output->x = (uint8_t)blurredPixel.x;
     output->y = (uint8_t)blurredPixel.y;
     output->z = (uint8_t)blurredPixel.z;
 }
+
diff --git a/libs/rs/java/ImageProcessing/src/com/android/rs/image/levels.rs b/libs/rs/java/ImageProcessing/src/com/android/rs/image/levels.rs
index 86ec56d..bb8a6fc 100644
--- a/libs/rs/java/ImageProcessing/src/com/android/rs/image/levels.rs
+++ b/libs/rs/java/ImageProcessing/src/com/android/rs/image/levels.rs
@@ -64,17 +64,18 @@
     const uchar4 *input = v_in;
     uchar4 *output = v_out;
 
-    float4 currentPixel = 0;
+    float3 currentPixel = 0;
 
     //currentPixel.xyz = convert_float3(input.xyz);
     currentPixel.x = (float)(input->x);
     currentPixel.y = (float)(input->y);
     currentPixel.z = (float)(input->z);
 
-    float3 temp = rsMatrixMultiply(&colorMat, currentPixel.xyz);
+    float3 temp = rsMatrixMultiply(&colorMat, currentPixel);
     temp = (clamp(temp, 0.f, 255.f) - inBlack) * overInWMinInB;
-    temp = pow(temp, (float3)gamma);
-    currentPixel.xyz = clamp(temp * outWMinOutB + outBlack, 0.f, 255.f);
+    if (gamma.x != 1.0f)
+        temp = pow(temp, (float3)gamma);
+    currentPixel = clamp(temp * outWMinOutB + outBlack, 0.f, 255.f);
 
     //output.xyz = convert_uchar3(currentPixel.xyz);
     output->x = (uint8_t)currentPixel.x;
diff --git a/libs/rs/java/ImageProcessing/src/com/android/rs/image/vertical_blur.rs b/libs/rs/java/ImageProcessing/src/com/android/rs/image/vertical_blur.rs
index 394d36a..008c8b5 100644
--- a/libs/rs/java/ImageProcessing/src/com/android/rs/image/vertical_blur.rs
+++ b/libs/rs/java/ImageProcessing/src/com/android/rs/image/vertical_blur.rs
@@ -7,35 +7,48 @@
     const FilterStruct *fs = (const FilterStruct *)usrData;
     const uchar4 *input = (const uchar4 *)rsGetElementAt(fs->ain, x, 0);
 
-    float4 blurredPixel = 0;
-    float4 currentPixel = 0;
-    for(int r = -fs->radius; r <= fs->radius; r ++) {
-#if 1
-        int validH = y + r;
-        // Clamp to zero and width
-        if(validH < 0) {
-            validH = 0;
+    float3 blurredPixel = 0;
+    float3 currentPixel = 0;
+
+    const float *gPtr = fs->gaussian;
+    if ((y > fs->radius) && (y < (fs->height - fs->radius))) {
+        const uchar4 *i = input + ((y - fs->radius) * fs->width);
+        for(int r = -fs->radius; r <= fs->radius; r ++) {
+            currentPixel.x = (float)(i->x);
+            currentPixel.y = (float)(i->y);
+            currentPixel.z = (float)(i->z);
+            blurredPixel += currentPixel * gPtr[0];
+            gPtr++;
+            i += fs->width;
         }
-        if(validH > fs->height - 1) {
-            validH = fs->height - 1;
+    } else {
+        for(int r = -fs->radius; r <= fs->radius; r ++) {
+    #if 1
+            int validH = y + r;
+            // Clamp to zero and width
+            if(validH < 0) {
+                validH = 0;
+            }
+            if(validH > fs->height - 1) {
+                validH = fs->height - 1;
+            }
+
+            const uchar4 *i = input + validH * fs->width;
+            //const uchar4 *i = (const uchar4 *)rsGetElementAt(fs->ain, x, validH);
+
+            currentPixel.x = (float)(i->x);
+            currentPixel.y = (float)(i->y);
+            currentPixel.z = (float)(i->z);
+            blurredPixel += currentPixel * gPtr[0];
+            gPtr++;
+    #else
+            int validH = rsClamp(y + r, 0, height - 1);
+            validH -= y;
+            uchar4 *i = input + validH * width + x;
+            blurredPixel.xyz += convert_float3(i->xyz) * gPtr[0];
+            gPtr++;
+    #endif
         }
-
-        const uchar4 *i = input + validH * fs->width;
-        //const uchar4 *i = (const uchar4 *)rsGetElementAt(fs->ain, x, validH);
-
-        float weight = fs->gaussian[r + fs->radius];
-
-        currentPixel.x = (float)(i->x);
-        currentPixel.y = (float)(i->y);
-        currentPixel.z = (float)(i->z);
-
-        blurredPixel.xyz += currentPixel.xyz * weight;
-#else
-        int validH = rsClamp(y + r, 0, height - 1);
-        validH -= y;
-        uchar4 *i = input + validH * width + x;
-        blurredPixel.xyz += convert_float3(i->xyz) * gaussian[r + fs->radius];
-#endif
     }
 
     //output->xyz = convert_uchar3(blurredPixel.xyz);
diff --git a/media/java/android/media/MediaRecorder.java b/media/java/android/media/MediaRecorder.java
index 47a8cfc..65f1e4d 100644
--- a/media/java/android/media/MediaRecorder.java
+++ b/media/java/android/media/MediaRecorder.java
@@ -279,6 +279,24 @@
     }
 
     /**
+     * Enables/Disables time lapse capture and sets its parameters. This method should
+     * be called after setProfile().
+     *
+     * @param enableTimeLapse Pass true to enable time lapse capture, false to disable it.
+     * @param timeBetweenTimeLapseFrameCaptureMs time between two captures of time lapse frames.
+     * @param encoderLevel the video encoder level.
+     * @hide
+     */
+    public void setTimeLapseParameters(boolean enableTimeLapse,
+            int timeBetweenTimeLapseFrameCaptureMs, int encoderLevel) {
+        setParameter(String.format("time-lapse-enable=%d",
+                    (enableTimeLapse) ? 1 : 0));
+        setParameter(String.format("time-between-time-lapse-frame-capture=%d",
+                    timeBetweenTimeLapseFrameCaptureMs));
+        setVideoEncoderLevel(encoderLevel);
+    }
+
+    /**
      * Sets the format of the output file produced during recording. Call this
      * after setAudioSource()/setVideoSource() but before prepare().
      *
@@ -445,6 +463,16 @@
     }
 
     /**
+     * Sets the level of the encoder. Call this before prepare().
+     *
+     * @param encoderLevel the video encoder level.
+     * @hide
+     */
+    public void setVideoEncoderLevel(int encoderLevel) {
+        setParameter(String.format("video-param-encoder-level=%d", encoderLevel));
+    }
+
+    /**
      * Pass in the file descriptor of the file to be written. Call this after
      * setOutputFormat() but before prepare().
      *
diff --git a/media/libeffects/lvm/wrapper/Bundle/EffectBundle.cpp b/media/libeffects/lvm/wrapper/Bundle/EffectBundle.cpp
index 9e39e79..6043dd5 100644
--- a/media/libeffects/lvm/wrapper/Bundle/EffectBundle.cpp
+++ b/media/libeffects/lvm/wrapper/Bundle/EffectBundle.cpp
@@ -17,8 +17,7 @@
 
 #define LOG_TAG "Bundle"
 #define ARRAY_SIZE(array) (sizeof array / sizeof array[0])
-#define LVM_BUNDLE                // Include all the bundle code
-//#define LOG_NDEBUG 0
+#define LOG_NDEBUG 0
 
 #include <cutils/log.h>
 #include <assert.h>
@@ -27,14 +26,10 @@
 #include <new>
 #include <EffectBundle.h>
 
-#ifdef LVM_BUNDLE
 #define LVM_MAX_SESSIONS        32
 #define MAX_NUM_BANDS           5
 #define MAX_CALL_SIZE           256
-#endif  /* end LVM_BUNDLE */
 
-
-int framecountag = 0;
 // effect_interface_t interface implementation for bass boost
 extern "C" const struct effect_interface_s gLvmEffectInterface;
 
@@ -57,10 +52,6 @@
         }\
     }
 
-
-
-
-
 // Namespaces
 namespace android {
 namespace {
@@ -73,6 +64,7 @@
     }                                         \
 }
 
+// Flag to allow a one time init of global memory, only happens on first call ever
 int LvmInitFlag = LVM_FALSE;
 SessionContext GlobalSessionMemory[32];
 
@@ -81,7 +73,8 @@
         {0x0634f220, 0xddd4, 0x11db, 0xa0fc, { 0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b }},
         {0x8631f300, 0x72e2, 0x11df, 0xb57e, {0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b}}, // uuid
         EFFECT_API_VERSION,
-        (EFFECT_FLAG_TYPE_INSERT | EFFECT_FLAG_INSERT_LAST),
+        (EFFECT_FLAG_TYPE_INSERT | EFFECT_FLAG_INSERT_LAST | EFFECT_FLAG_DEVICE_IND
+        | EFFECT_FLAG_VOLUME_CTRL),
         0, // TODO
         1,
         "Dynamic Bass Boost",
@@ -90,10 +83,11 @@
 
 // NXP SW Virtualizer UUID
 const effect_descriptor_t gVirtualizerDescriptor = {
-        {0x37cc2c00, 0xdddd, 0x11db, 0x8577, {0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b}}, // Virtualizer ID
-        {0x1d4033c0, 0x8557, 0x11df, 0x9f2d, {0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b}}, // NXP SW UUID gen july 01 2010
+        {0x37cc2c00, 0xdddd, 0x11db, 0x8577, {0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b}},
+        {0x1d4033c0, 0x8557, 0x11df, 0x9f2d, {0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b}},
         EFFECT_API_VERSION,
-        (EFFECT_FLAG_TYPE_INSERT | EFFECT_FLAG_INSERT_LAST),
+        (EFFECT_FLAG_TYPE_INSERT | EFFECT_FLAG_INSERT_LAST | EFFECT_FLAG_DEVICE_IND
+        | EFFECT_FLAG_VOLUME_CTRL),
         0, // TODO
         1,
         "Virtualizer",
@@ -105,7 +99,7 @@
         {0x0bed4300, 0xddd6, 0x11db, 0x8f34, {0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b}}, // type
         {0xce772f20, 0x847d, 0x11df, 0xbb17, {0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b}}, // uuid Eq NXP
         EFFECT_API_VERSION,
-        (EFFECT_FLAG_TYPE_INSERT | EFFECT_FLAG_INSERT_LAST),
+        (EFFECT_FLAG_TYPE_INSERT | EFFECT_FLAG_INSERT_LAST | EFFECT_FLAG_VOLUME_CTRL),
         0, // TODO
         1,
         "Equalizer",
@@ -115,10 +109,9 @@
 // NXP SW Volume UUID
 const effect_descriptor_t gVolumeDescriptor = {
         {0x09e8ede0, 0xddde, 0x11db, 0xb4f6, { 0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b }},
-        //{0x8631f300, 0x72e2, 0x11df, 0xb57e, { 0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b }}, // uuid
         {0x119341a0, 0x8469, 0x11df, 0x81f9, { 0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b }}, //uuid VOL NXP
         EFFECT_API_VERSION,
-        (EFFECT_FLAG_TYPE_INSERT | EFFECT_FLAG_INSERT_LAST),
+        (EFFECT_FLAG_TYPE_INSERT | EFFECT_FLAG_INSERT_LAST | EFFECT_FLAG_VOLUME_CTRL),
         0, // TODO
         1,
         "Volume",
@@ -131,9 +124,9 @@
 int  LvmEffect_enable          (EffectContext *pContext);
 int  LvmEffect_disable         (EffectContext *pContext);
 void LvmEffect_free            (EffectContext *pContext);
-int  Effect_configure       (EffectContext *pContext, effect_config_t *pConfig);
+int  Effect_configure          (EffectContext *pContext, effect_config_t *pConfig);
 int  BassBoost_setParameter    (EffectContext *pContext, int32_t *pParam, void *pValue);
-int  BassBoost_getParameter    (EffectContext *pContext, 
+int  BassBoost_getParameter    (EffectContext *pContext,
                                int32_t        *pParam,
                                size_t         *pValueSize,
                                void           *pValue);
@@ -141,7 +134,7 @@
 int  Virtualizer_getParameter  (EffectContext *pContext,
                                int32_t        *pParam,
                                size_t         *pValueSize,
-                               void           *pValue);                               
+                               void           *pValue);
 int  Equalizer_setParameter    (EffectContext *pContext, int32_t *pParam, void *pValue);
 int  Equalizer_getParameter    (EffectContext *pContext,
                                 int32_t       *pParam,
@@ -153,41 +146,25 @@
                                 size_t        *pValueSize,
                                 void          *pValue);
 
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
 /* Effect Library Interface Implementation */
 extern "C" int EffectQueryNumberEffects(uint32_t *pNumEffects){
     LOGV("\n\tEffectQueryNumberEffects start");
     *pNumEffects = 4;
-    LOGV("\tEffectQueryNumberEffects creating %d effects", *pNumEffects);  
-    LOGV("\tEffectQueryNumberEffects end\n");      
+    LOGV("\tEffectQueryNumberEffects creating %d effects", *pNumEffects);
+    LOGV("\tEffectQueryNumberEffects end\n");
     return 0;
 }     /* end EffectQueryNumberEffects */
 
-
 extern "C" int EffectQueryEffect(uint32_t index, effect_descriptor_t *pDescriptor){
     LOGV("\n\tEffectQueryEffect start");
     LOGV("\tEffectQueryEffect processing index %d", index);
-    
+
     if (pDescriptor == NULL){
-    	LOGV("\tLVM_ERROR : EffectQueryEffect was passed NULL pointer");
+        LOGV("\tLVM_ERROR : EffectQueryEffect was passed NULL pointer");
         return -EINVAL;
     }
     if (index > 3){
-    	LOGV("\tLVM_ERROR : EffectQueryEffect index out of range %d", index);
+        LOGV("\tLVM_ERROR : EffectQueryEffect index out of range %d", index);
         return -ENOENT;
     }
     if(index == LVM_BASS_BOOST){
@@ -202,12 +179,11 @@
     } else if(index == LVM_VOLUME){
         LOGV("\tEffectQueryEffect processing LVM_VOLUME");
         memcpy(pDescriptor, &gVolumeDescriptor, sizeof(effect_descriptor_t));
-    }       
+    }
     LOGV("\tEffectQueryEffect end\n");
     return 0;
 }     /* end EffectQueryEffect */
 
-
 extern "C" int EffectCreate(effect_uuid_t       *uuid,
                             int32_t             sessionId,
                             int32_t             ioId,
@@ -219,13 +195,13 @@
     LOGV("\n\tEffectCreate start session %d", sessionId);
 
     if (pInterface == NULL || uuid == NULL){
-    	LOGV("\tLVM_ERROR : EffectCreate() called with NULL pointer");
+        LOGV("\tLVM_ERROR : EffectCreate() called with NULL pointer");
         return -EINVAL;
     }
 
     if((sessionId < 0)||(sessionId >= LVM_MAX_SESSIONS)){
         LOGV("\tLVM_ERROR : EffectCreate sessionId is less than 0");
-        return -EINVAL;  
+        return -EINVAL;
     }
 
     if(LvmInitFlag == LVM_FALSE){
@@ -238,29 +214,48 @@
     if(GlobalSessionMemory[sessionId].bBundledEffectsEnabled == LVM_FALSE){
         LOGV("\tEffectCreate - This is the first effect in current session %d", sessionId);
         LOGV("\tEffectCreate - Setting up Bundled Effects Instance for session %d", sessionId);
+
         GlobalSessionMemory[sessionId].bBundledEffectsEnabled = LVM_TRUE;
         GlobalSessionMemory[sessionId].pBundledContext        = new BundledEffectContext;
 
         pContext->pBundledContext = GlobalSessionMemory[sessionId].pBundledContext;
-        pContext->pBundledContext->SessionNo            = sessionId;
-        pContext->pBundledContext->hInstance            = NULL;        
-        pContext->pBundledContext->bVolumeEnabled       = LVM_FALSE;
-        pContext->pBundledContext->bEqualizerEnabled    = LVM_FALSE;
-        pContext->pBundledContext->bBassEnabled         = LVM_FALSE;
-        pContext->pBundledContext->bVirtualizerEnabled  = LVM_FALSE;        
-        pContext->pBundledContext->NumberEffectsEnabled = 0;
-        pContext->pBundledContext->NumberEffectsCalled  = 0;        
-        
+        pContext->pBundledContext->SessionNo                = sessionId;
+        pContext->pBundledContext->hInstance                = NULL;
+        pContext->pBundledContext->bVolumeEnabled           = LVM_FALSE;
+        pContext->pBundledContext->bEqualizerEnabled        = LVM_FALSE;
+        pContext->pBundledContext->bBassEnabled             = LVM_FALSE;
+        pContext->pBundledContext->bBassTempDisabled        = LVM_FALSE;
+        pContext->pBundledContext->bVirtualizerEnabled      = LVM_FALSE;
+        pContext->pBundledContext->bVirtualizerTempDisabled = LVM_FALSE;
+        pContext->pBundledContext->NumberEffectsEnabled     = 0;
+        pContext->pBundledContext->NumberEffectsCalled      = 0;
+        pContext->pBundledContext->frameCount               = 0;
+
+        #ifdef LVM_PCM
+        pContext->pBundledContext->PcmInPtr  = NULL;
+        pContext->pBundledContext->PcmOutPtr = NULL;
+
+        pContext->pBundledContext->PcmInPtr  = fopen("/data/tmp/bundle_pcm_in.pcm", "w");
+        pContext->pBundledContext->PcmOutPtr = fopen("/data/tmp/bundle_pcm_out.pcm", "w");
+
+        if((pContext->pBundledContext->PcmInPtr  == NULL)||
+           (pContext->pBundledContext->PcmOutPtr == NULL)){
+           return -EINVAL;
+        }
+        #endif
+
         /* Saved strength is used to return the exact strength that was used in the set to the get
          * because we map the original strength range of 0:1000 to 1:15, and this will avoid
          * quantisation like effect when returning
          */
-        pContext->pBundledContext->BassStrengthSaved    = 0;  
-        pContext->pBundledContext->VirtStrengthSaved    = 0; 
-        pContext->pBundledContext->CurPreset            = PRESET_CUSTOM;  
-        pContext->pBundledContext->levelSaved           = 0;
-        pContext->pBundledContext->bMuteEnabled         = LVM_FALSE; 
-         
+        pContext->pBundledContext->BassStrengthSaved        = 0;
+        pContext->pBundledContext->VirtStrengthSaved        = 0;
+        pContext->pBundledContext->CurPreset                = PRESET_CUSTOM;
+        pContext->pBundledContext->levelSaved               = 0;
+        pContext->pBundledContext->bMuteEnabled             = LVM_FALSE;
+        pContext->pBundledContext->bStereoPositionEnabled   = LVM_FALSE;
+        pContext->pBundledContext->positionSaved            = 0;
+
         LOGV("\tEffectCreate - Calling LvmBundle_init");
         ret = LvmBundle_init(pContext);
 
@@ -274,7 +269,7 @@
     else{
         pContext->pBundledContext = GlobalSessionMemory[sessionId].pBundledContext;
     }
-    
+
     LOGV("\tEffectCreate - pBundledContext is %p", pContext->pBundledContext);
 
     // Create each Effect
@@ -282,84 +277,86 @@
         // Create Bass Boost
         LOGV("\tEffectCreate - Effect to be created is LVM_BASS_BOOST");
         GlobalSessionMemory[sessionId].bBassInstantiated = LVM_TRUE;
-        
-        pContext->itfe       = &gLvmEffectInterface;        
+
+        pContext->itfe       = &gLvmEffectInterface;
         pContext->EffectType = LVM_BASS_BOOST;
     } else if (memcmp(uuid, &gVirtualizerDescriptor.uuid, sizeof(effect_uuid_t)) == 0){
         // Create Virtualizer
-        LOGV("\tEffectCreate - Effect to be created is LVM_VIRTUALIZER");        
+        LOGV("\tEffectCreate - Effect to be created is LVM_VIRTUALIZER");
         GlobalSessionMemory[sessionId].bVirtualizerInstantiated = LVM_TRUE;
-        
+
         pContext->itfe       = &gLvmEffectInterface;
         pContext->EffectType = LVM_VIRTUALIZER;
     } else if (memcmp(uuid, &gEqualizerDescriptor.uuid, sizeof(effect_uuid_t)) == 0){
         // Create Equalizer
-        LOGV("\tEffectCreate - Effect to be created is LVM_EQUALIZER");        
+        LOGV("\tEffectCreate - Effect to be created is LVM_EQUALIZER");
         GlobalSessionMemory[sessionId].bEqualizerInstantiated = LVM_TRUE;
-        
+
         pContext->itfe       = &gLvmEffectInterface;
         pContext->EffectType = LVM_EQUALIZER;
     } else if (memcmp(uuid, &gVolumeDescriptor.uuid, sizeof(effect_uuid_t)) == 0){
         // Create Volume
-        LOGV("\tEffectCreate - Effect to be created is LVM_VOLUME");        
+        LOGV("\tEffectCreate - Effect to be created is LVM_VOLUME");
         GlobalSessionMemory[sessionId].bVolumeInstantiated = LVM_TRUE;
-        
+
         pContext->itfe       = &gLvmEffectInterface;
         pContext->EffectType = LVM_VOLUME;
-    }       
+    }
     else{
-     	LOGV("\tLVM_ERROR : EffectCreate() invalid UUID");
-        return -EINVAL;   
+        LOGV("\tLVM_ERROR : EffectCreate() invalid UUID");
+        return -EINVAL;
     }
 
     *pInterface = (effect_interface_t)pContext;
-    LOGV("\tEffectCreate end..\n\n");    
+    LOGV("\tEffectCreate end..\n\n");
     return 0;
 } /* end EffectCreate */
 
-
-
 extern "C" int EffectRelease(effect_interface_t interface){
     LOGV("\n\tEffectRelease start %p", interface);
     EffectContext * pContext = (EffectContext *)interface;
 
     if (pContext == NULL){
-    	LOGV("\tLVM_ERROR : EffectRelease called with NULL pointer");
+        LOGV("\tLVM_ERROR : EffectRelease called with NULL pointer");
         return -EINVAL;
-    } 
+    }
 
     // Clear the instantiated flag for the effect
     if(pContext->EffectType == LVM_BASS_BOOST) {
         LOGV("\tEffectRelease LVM_BASS_BOOST Clearing global intstantiated flag");
-        GlobalSessionMemory[pContext->pBundledContext->SessionNo].bBassInstantiated = LVM_FALSE;        
+        GlobalSessionMemory[pContext->pBundledContext->SessionNo].bBassInstantiated = LVM_FALSE;
     } else if(pContext->EffectType == LVM_VIRTUALIZER) {
         LOGV("\tEffectRelease LVM_VIRTUALIZER Clearing global intstantiated flag");
-        GlobalSessionMemory[pContext->pBundledContext->SessionNo].bVirtualizerInstantiated = LVM_FALSE;        
+        GlobalSessionMemory[pContext->pBundledContext->SessionNo].bVirtualizerInstantiated
+            = LVM_FALSE;
     } else if(pContext->EffectType == LVM_EQUALIZER) {
         LOGV("\tEffectRelease LVM_EQUALIZER Clearing global intstantiated flag");
-        GlobalSessionMemory[pContext->pBundledContext->SessionNo].bEqualizerInstantiated = LVM_FALSE;        
+        GlobalSessionMemory[pContext->pBundledContext->SessionNo].bEqualizerInstantiated =LVM_FALSE;
     } else if(pContext->EffectType == LVM_VOLUME) {
         LOGV("\tEffectRelease LVM_VOLUME Clearing global intstantiated flag");
-        GlobalSessionMemory[pContext->pBundledContext->SessionNo].bVolumeInstantiated = LVM_FALSE;        
+        GlobalSessionMemory[pContext->pBundledContext->SessionNo].bVolumeInstantiated = LVM_FALSE;
     } else {
         LOGV("\tLVM_ERROR : EffectRelease : Unsupported effect\n\n\n\n\n\n\n");
     }
-    
+
     // if all effects are no longer instantiaed free the lvm memory and delete BundledEffectContext
     if((GlobalSessionMemory[pContext->pBundledContext->SessionNo].bBassInstantiated == LVM_FALSE)&&
-       (GlobalSessionMemory[pContext->pBundledContext->SessionNo].bVolumeInstantiated == LVM_FALSE)&&
-       (GlobalSessionMemory[pContext->pBundledContext->SessionNo].bEqualizerInstantiated == LVM_FALSE)&&
-       (GlobalSessionMemory[pContext->pBundledContext->SessionNo].bVirtualizerInstantiated == LVM_FALSE))        
+    (GlobalSessionMemory[pContext->pBundledContext->SessionNo].bVolumeInstantiated == LVM_FALSE)&&
+    (GlobalSessionMemory[pContext->pBundledContext->SessionNo].bEqualizerInstantiated ==LVM_FALSE)&&
+    (GlobalSessionMemory[pContext->pBundledContext->SessionNo].bVirtualizerInstantiated==LVM_FALSE))
     {
-       LOGV("\tEffectRelease: All effects are no longer instantiated\n");
-       GlobalSessionMemory[pContext->pBundledContext->SessionNo].bBundledEffectsEnabled = LVM_FALSE;
-       GlobalSessionMemory[pContext->pBundledContext->SessionNo].pBundledContext = LVM_NULL;
-       LOGV("\tEffectRelease: Freeing LVM Bundle memory\n");
-       LvmEffect_free(pContext);
-       LOGV("\tEffectRelease: Deleting LVM Bundle context\n");       
-       delete pContext->pBundledContext;
+        #ifdef LVM_PCM
+        fclose(pContext->pBundledContext->PcmInPtr);
+        fclose(pContext->pBundledContext->PcmOutPtr);
+        #endif
+        LOGV("\tEffectRelease: All effects are no longer instantiated\n");
+        GlobalSessionMemory[pContext->pBundledContext->SessionNo].bBundledEffectsEnabled =LVM_FALSE;
+        GlobalSessionMemory[pContext->pBundledContext->SessionNo].pBundledContext = LVM_NULL;
+        LOGV("\tEffectRelease: Freeing LVM Bundle memory\n");
+        LvmEffect_free(pContext);
+        LOGV("\tEffectRelease: Deleting LVM Bundle context\n");
+        delete pContext->pBundledContext;
     }
-    
     // free the effect context for current effect
     delete pContext;
 
@@ -368,21 +365,6 @@
 
 } /* end EffectRelease */
 
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
 void LvmGlobalBundle_init(){
     LOGV("\tLvmGlobalBundle_init start");
     for(int i=0; i<LVM_MAX_SESSIONS; i++){
@@ -413,22 +395,22 @@
 
     LOGV("\tLvmBundle_init start");
 
-    pContext->config.inputCfg.accessMode                           = EFFECT_BUFFER_ACCESS_READ;
-    pContext->config.inputCfg.channels                             = CHANNEL_STEREO;
-    pContext->config.inputCfg.format                               = SAMPLE_FORMAT_PCM_S15;
-    pContext->config.inputCfg.samplingRate                         = 44100;
-    pContext->config.inputCfg.bufferProvider.getBuffer             = NULL;
-    pContext->config.inputCfg.bufferProvider.releaseBuffer         = NULL;
-    pContext->config.inputCfg.bufferProvider.cookie                = NULL;
-    pContext->config.inputCfg.mask                                 = EFFECT_CONFIG_ALL;
-    pContext->config.outputCfg.accessMode                          = EFFECT_BUFFER_ACCESS_ACCUMULATE;
-    pContext->config.outputCfg.channels                            = CHANNEL_STEREO;
-    pContext->config.outputCfg.format                              = SAMPLE_FORMAT_PCM_S15;
-    pContext->config.outputCfg.samplingRate                        = 44100;
-    pContext->config.outputCfg.bufferProvider.getBuffer            = NULL;
-    pContext->config.outputCfg.bufferProvider.releaseBuffer        = NULL;
-    pContext->config.outputCfg.bufferProvider.cookie               = NULL;
-    pContext->config.outputCfg.mask                                = EFFECT_CONFIG_ALL;
+    pContext->config.inputCfg.accessMode                    = EFFECT_BUFFER_ACCESS_READ;
+    pContext->config.inputCfg.channels                      = CHANNEL_STEREO;
+    pContext->config.inputCfg.format                        = SAMPLE_FORMAT_PCM_S15;
+    pContext->config.inputCfg.samplingRate                  = 44100;
+    pContext->config.inputCfg.bufferProvider.getBuffer      = NULL;
+    pContext->config.inputCfg.bufferProvider.releaseBuffer  = NULL;
+    pContext->config.inputCfg.bufferProvider.cookie         = NULL;
+    pContext->config.inputCfg.mask                          = EFFECT_CONFIG_ALL;
+    pContext->config.outputCfg.accessMode                   = EFFECT_BUFFER_ACCESS_ACCUMULATE;
+    pContext->config.outputCfg.channels                     = CHANNEL_STEREO;
+    pContext->config.outputCfg.format                       = SAMPLE_FORMAT_PCM_S15;
+    pContext->config.outputCfg.samplingRate                 = 44100;
+    pContext->config.outputCfg.bufferProvider.getBuffer     = NULL;
+    pContext->config.outputCfg.bufferProvider.releaseBuffer = NULL;
+    pContext->config.outputCfg.bufferProvider.cookie        = NULL;
+    pContext->config.outputCfg.mask                         = EFFECT_CONFIG_ALL;
 
     CHECK_ARG(pContext != NULL);
 
@@ -442,7 +424,6 @@
                 "-> Called pContext->pBassBoost->free()");
     }
 
-    #ifdef LVM_BUNDLE
     LVM_ReturnStatus_en     LvmStatus=LVM_SUCCESS;          /* Function call status */
     LVM_ControlParams_t     params;                         /* Control Parameters */
     LVM_InstParams_t        InstParams;                     /* Instance parameters */
@@ -453,7 +434,7 @@
     bool                    bMallocFailure = LVM_FALSE;
 
     /* Set the capabilities */
-    InstParams.BufferMode       = LVM_MANAGED_BUFFERS;
+    InstParams.BufferMode       = LVM_UNMANAGED_BUFFERS;
     InstParams.MaxBlockSize     = MAX_CALL_SIZE;
     InstParams.EQNB_NumBands    = MAX_NUM_BANDS;
     InstParams.PSA_Included     = LVM_PSA_ON;
@@ -474,11 +455,11 @@
             MemTab.Region[i].pBaseAddress = malloc(MemTab.Region[i].Size);
 
             if (MemTab.Region[i].pBaseAddress == LVM_NULL){
-                LOGV("\tLVM_ERROR : CreateInstance Failed to allocate %ld bytes for region %u\n",
+                LOGV("\tLVM_ERROR :LvmBundle_init CreateInstance Failed to allocate %ld bytes for region %u\n",
                         MemTab.Region[i].Size, i );
                 bMallocFailure = LVM_TRUE;
             }else{
-                LOGV("\tCreateInstance allocated %ld bytes for region %u at %p\n",
+                LOGV("\tLvmBundle_init CreateInstance allocated %ld bytes for region %u at %p\n",
                         MemTab.Region[i].Size, i, MemTab.Region[i].pBaseAddress);
             }
         }
@@ -490,29 +471,31 @@
     if(bMallocFailure == LVM_TRUE){
         for (int i=0; i<LVM_NR_MEMORY_REGIONS; i++){
             if (MemTab.Region[i].pBaseAddress == LVM_NULL){
-                LOGV("\tLVM_ERROR : CreateInstance Failed to allocate %ld bytes for region %u - Not freeing\n",
-                        MemTab.Region[i].Size, i );
+                LOGV("\tLVM_ERROR :LvmBundle_init CreateInstance Failed to allocate %ld bytes for region %u - +"
+                     "Not freeing\n", MemTab.Region[i].Size, i );
             }else{
-                LOGV("\tLVM_ERROR : CreateInstance Failed: but allocated %ld bytes for region %u at %p- free\n",
-                        MemTab.Region[i].Size, i, MemTab.Region[i].pBaseAddress);
+                LOGV("\tLVM_ERROR :LvmBundle_init CreateInstance Failed: but allocated %ld bytes "
+                     "for region %u at %p- free\n",
+                     MemTab.Region[i].Size, i, MemTab.Region[i].pBaseAddress);
                 free(MemTab.Region[i].pBaseAddress);
             }
         }
         return -EINVAL;
     }
-    LOGV("\tCreateInstance Succesfully malloc'd memory\n");
+    LOGV("\tLvmBundle_init CreateInstance Succesfully malloc'd memory\n");
 
     /* Initialise */
-    pContext->pBundledContext->hInstance = LVM_NULL;                        /* Initialise to NULL */
+    pContext->pBundledContext->hInstance = LVM_NULL;
 
-    LvmStatus = LVM_GetInstanceHandle(&pContext->pBundledContext->hInstance,/* Init sets the instance handle */
+    /* Init sets the instance handle */
+    LvmStatus = LVM_GetInstanceHandle(&pContext->pBundledContext->hInstance,
                                       &MemTab,
                                       &InstParams);
 
     LVM_ERROR_CHECK(LvmStatus, "LVM_GetInstanceHandle", "LvmBundle_init")
     if(LvmStatus != LVM_SUCCESS) return -EINVAL;
 
-    LOGV("\tCreateInstance Succesfully called LVM_GetInstanceHandle\n");
+    LOGV("\tLvmBundle_init CreateInstance Succesfully called LVM_GetInstanceHandle\n");
 
     /* Set the initial process parameters */
     /* General parameters */
@@ -521,6 +504,8 @@
     params.SourceFormat           = LVM_STEREO;
     params.SpeakerType            = LVM_HEADPHONES;
 
+    pContext->pBundledContext->SampleRate = LVM_FS_44100;
+
     /* Concert Sound parameters */
     params.VirtualizerOperatingMode   = LVM_MODE_OFF;
     params.VirtualizerType            = LVM_CONCERTSOUND;
@@ -531,11 +516,12 @@
     params.EQNB_OperatingMode     = LVM_EQNB_OFF;
     params.EQNB_NBands            = FIVEBAND_NUMBANDS;
     params.pEQNB_BandDefinition   = &BandDefs[0];
+
     for (int i=0; i<FIVEBAND_NUMBANDS; i++)
     {
         BandDefs[i].Frequency = EQNB_5BandPresetsFrequencies[i];
         BandDefs[i].QFactor   = EQNB_5BandPresetsQFactors[i];
-        BandDefs[i].Gain      = EQNB_5BandNormalPresets[i];
+        BandDefs[i].Gain      = EQNB_5BandSoftPresets[i];
     }
 
     /* Volume Control parameters */
@@ -560,13 +546,14 @@
     params.PSA_Enable             = LVM_PSA_OFF;
     params.PSA_PeakDecayRate      = LVM_PSA_SPEED_MEDIUM;
 
-    LvmStatus = LVM_SetControlParameters(pContext->pBundledContext->hInstance,     /* Activate the initial settings */
+    /* Activate the initial settings */
+    LvmStatus = LVM_SetControlParameters(pContext->pBundledContext->hInstance,
                                          &params);
 
     LVM_ERROR_CHECK(LvmStatus, "LVM_SetControlParameters", "LvmBundle_init")
     if(LvmStatus != LVM_SUCCESS) return -EINVAL;
 
-    LOGV("\tCreateInstance Succesfully called LVM_SetControlParameters\n");
+    LOGV("\tLvmBundle_init CreateInstance Succesfully called LVM_SetControlParameters\n");
 
     /* Set the headroom parameters */
     HeadroomBandDef[0].Limit_Low          = 20;
@@ -585,15 +572,11 @@
     LVM_ERROR_CHECK(LvmStatus, "LVM_SetHeadroomParams", "LvmBundle_init")
     if(LvmStatus != LVM_SUCCESS) return -EINVAL;
 
-    LOGV("\tCreateInstance Succesfully called LVM_SetHeadroomParams\n");
-    #endif    /* end LVM_BUNDLE */
-
+    LOGV("\tLvmBundle_init CreateInstance Succesfully called LVM_SetHeadroomParams\n");
     LOGV("\tLvmBundle_init End");
     return 0;
 }   /* end LvmBundle_init */
 
-
-
 //----------------------------------------------------------------------------
 // LvmBundle_process()
 //----------------------------------------------------------------------------
@@ -613,59 +596,71 @@
 //----------------------------------------------------------------------------
 
 int LvmBundle_process(LVM_INT16        *pIn,
-             LVM_INT16        *pOut,
-             int              frameCount,
-             EffectContext *pContext){
+                      LVM_INT16        *pOut,
+                      int              frameCount,
+                      EffectContext    *pContext){
 
     LVM_ControlParams_t     ActiveParams;                           /* Current control Parameters */
     LVM_ReturnStatus_en     LvmStatus = LVM_SUCCESS;                /* Function call status */
 
+    LVM_INT16               *pOutTmp;
+    if (pContext->config.outputCfg.accessMode == EFFECT_BUFFER_ACCESS_WRITE){
+        pOutTmp = pOut;
+    }else if (pContext->config.outputCfg.accessMode == EFFECT_BUFFER_ACCESS_ACCUMULATE){
+        pOutTmp = (LVM_INT16 *)malloc(frameCount * sizeof(LVM_INT16) * 2);
+        if(pOutTmp == NULL){
+            LOGV("\tLVM_ERROR : LvmBundle_process failed to allocate memory for "
+            "EFFECT_BUFFER_ACCESS_ACCUMULATE mode");
+            return -EINVAL;
+        }
+    }else{
+        LOGV("LVM_ERROR : LvmBundle_process invalid access mode");
+        return -EINVAL;
+    }
 
-    #ifdef LVM_BUNDLE
-	LVM_INT16				*pOutTmp;
-	if (pContext->config.outputCfg.accessMode == EFFECT_BUFFER_ACCESS_WRITE){
-		//LOGV("\tprocess: mBehavior is EFFECT_BUFFER_ACCESS_WRITE %d\n",
-		//		pContext->config.outputCfg.accessMode);
-		pOutTmp = pOut;
-	}else if (pContext->config.outputCfg.accessMode == EFFECT_BUFFER_ACCESS_ACCUMULATE){
-		//LOGV("\tprocess: mBehavior is EFFECT_BUFFER_ACCESS_ACCUMULATE %d\n",
-		//		pContext->config.outputCfg.accessMode);
-		pOutTmp = (LVM_INT16 *)malloc(frameCount * sizeof(LVM_INT16) * 2);
-		if(pOutTmp == NULL){
-			LOGV("\tLVM_ERROR : LvmBundle_process failed to allocate memory for EFFECT_BUFFER_ACCESS_ACCUMULATE mode");
-			return -EINVAL;
-		}
-	}else{
-		LOGV("LVM_ERROR : LvmBundle_process invalid access mode");
-		return -EINVAL;
-	}
-	
-	/* Process the samples */
-    LvmStatus = LVM_GetControlParameters(pContext->pBundledContext->hInstance,  /* Get the current settings */
+    /* Get the current settings */
+    LvmStatus = LVM_GetControlParameters(pContext->pBundledContext->hInstance,
                                          &ActiveParams);
 
-    LVM_ERROR_CHECK(LvmStatus, "LVM_GetControlParameters", "LvmEffect_enable")
+    LVM_ERROR_CHECK(LvmStatus, "LVM_GetControlParameters", "LvmBundle_process")
     if(LvmStatus != LVM_SUCCESS) return -EINVAL;
-    LOGV("\t%d %d %d\n",ActiveParams.BE_OperatingMode, ActiveParams.VirtualizerOperatingMode, ActiveParams.EQNB_OperatingMode);
 
-	
+    pContext->pBundledContext->frameCount++;
+    if(pContext->pBundledContext->frameCount == 100)
+    {
+        //LOGV("\tBB: %d VIRT: %d EQ: %d, session (%d), context is %p\n",
+        //ActiveParams.BE_OperatingMode,
+        //ActiveParams.VirtualizerOperatingMode, ActiveParams.EQNB_OperatingMode,
+        //pContext->pBundledContext->SessionNo, pContext->pBundledContext);
+        pContext->pBundledContext->frameCount = 0;
+    }
+
+    #ifdef LVM_PCM
+    fwrite(pIn, frameCount*sizeof(LVM_INT16)*2, 1, pContext->pBundledContext->PcmInPtr);
+    fflush(pContext->pBundledContext->PcmInPtr);
+    #endif
+
+    /* Process the samples */
     LvmStatus = LVM_Process(pContext->pBundledContext->hInstance, /* Instance handle */
                             pIn,                                  /* Input buffer */
                             pOutTmp,                              /* Output buffer */
                             (LVM_UINT16)frameCount,               /* Number of samples to read */
                             0);                                   /* Audo Time */
+
     LVM_ERROR_CHECK(LvmStatus, "LVM_Process", "LvmBundle_process")
     if(LvmStatus != LVM_SUCCESS) return -EINVAL;
 
-	if (pContext->config.outputCfg.accessMode == EFFECT_BUFFER_ACCESS_ACCUMULATE){
-		for (int i=0; i<frameCount*2; i++){
-			pOut[i] +=  pOutTmp[i];
-		}
-		free(pOutTmp);
-	}
-    #else
-    memcpy(pOut, pIn, frameCount*sizeof(LVM_INT16)*2); // 2 is for stereo input
-    #endif    /* end LVM_BUNDLE */
+    #ifdef LVM_PCM
+    fwrite(pOutTmp, frameCount*sizeof(LVM_INT16)*2, 1, pContext->pBundledContext->PcmOutPtr);
+    fflush(pContext->pBundledContext->PcmOutPtr);
+    #endif
+
+    if (pContext->config.outputCfg.accessMode == EFFECT_BUFFER_ACCESS_ACCUMULATE){
+        for (int i=0; i<frameCount*2; i++){
+            pOut[i] +=  pOutTmp[i];
+        }
+        free(pOutTmp);
+    }
     return 0;
 }    /* end LvmBundle_process */
 
@@ -682,46 +677,44 @@
 //----------------------------------------------------------------------------
 
 int LvmEffect_enable(EffectContext *pContext){
-    LOGV("\tLvmEffect_enable start");
-   
-    #ifdef LVM_BUNDLE
+    //LOGV("\tLvmEffect_enable start");
+
     LVM_ControlParams_t     ActiveParams;                           /* Current control Parameters */
     LVM_ReturnStatus_en     LvmStatus = LVM_SUCCESS;                /* Function call status */
 
-    LvmStatus = LVM_GetControlParameters(pContext->pBundledContext->hInstance,  /* Get the current settings */
+    /* Get the current settings */
+    LvmStatus = LVM_GetControlParameters(pContext->pBundledContext->hInstance,
                                          &ActiveParams);
 
     LVM_ERROR_CHECK(LvmStatus, "LVM_GetControlParameters", "LvmEffect_enable")
     if(LvmStatus != LVM_SUCCESS) return -EINVAL;
-    LOGV("\tLvmEffect_enable Succesfully called LVM_GetControlParameters\n");
+    //LOGV("\tLvmEffect_enable Succesfully called LVM_GetControlParameters\n");
 
     if(pContext->EffectType == LVM_BASS_BOOST) {
-        LOGV("\tLvmEffect_enable : Enabling LVM_BASS_BOOST");    
+        LOGV("\tLvmEffect_enable : Enabling LVM_BASS_BOOST");
         ActiveParams.BE_OperatingMode       = LVM_BE_ON;
     }
     if(pContext->EffectType == LVM_VIRTUALIZER) {
-        LOGV("\tLvmEffect_enable : Enabling LVM_VIRTUALIZER");    
+        LOGV("\tLvmEffect_enable : Enabling LVM_VIRTUALIZER");
         ActiveParams.VirtualizerOperatingMode   = LVM_MODE_ON;
     }
     if(pContext->EffectType == LVM_EQUALIZER) {
-        LOGV("\tLvmEffect_enable : Enabling LVM_EQUALIZER");    
+        LOGV("\tLvmEffect_enable : Enabling LVM_EQUALIZER");
         ActiveParams.EQNB_OperatingMode     = LVM_EQNB_ON;
     }
     if(pContext->EffectType == LVM_VOLUME) {
-        LOGV("\tLvmEffect_enable : Enabling LVM_VOLUME");    
-    }    
-    
+        LOGV("\tLvmEffect_enable : Enabling LVM_VOLUME");
+    }
+
     LvmStatus = LVM_SetControlParameters(pContext->pBundledContext->hInstance, &ActiveParams);
     LVM_ERROR_CHECK(LvmStatus, "LVM_SetControlParameters", "LvmEffect_enable")
     if(LvmStatus != LVM_SUCCESS) return -EINVAL;
-    LOGV("\tLvmEffect_enable Succesfully called LVM_SetControlParameters\n");    
-    #endif    /* end LVM_BUNDLE */    
-    
-    LOGV("\tLvmEffect_enable end");    
+
+    //LOGV("\tLvmEffect_enable Succesfully called LVM_SetControlParameters\n");
+    //LOGV("\tLvmEffect_enable end");
     return 0;
 }
 
-
 //----------------------------------------------------------------------------
 // LvmEffect_disable()
 //----------------------------------------------------------------------------
@@ -735,46 +728,43 @@
 //----------------------------------------------------------------------------
 
 int LvmEffect_disable(EffectContext *pContext){
-    LOGV("\tLvmEffect_disable start");
-   
-    #ifdef LVM_BUNDLE
+    //LOGV("\tLvmEffect_disable start");
+
     LVM_ControlParams_t     ActiveParams;                           /* Current control Parameters */
     LVM_ReturnStatus_en     LvmStatus = LVM_SUCCESS;                /* Function call status */
-
-    LvmStatus = LVM_GetControlParameters(pContext->pBundledContext->hInstance,  /* Get the current settings */
+    /* Get the current settings */
+    LvmStatus = LVM_GetControlParameters(pContext->pBundledContext->hInstance,
                                          &ActiveParams);
 
     LVM_ERROR_CHECK(LvmStatus, "LVM_GetControlParameters", "LvmEffect_disable")
     if(LvmStatus != LVM_SUCCESS) return -EINVAL;
-    LOGV("\tLvmEffect_disable Succesfully called LVM_GetControlParameters\n");
+    //LOGV("\tLvmEffect_disable Succesfully called LVM_GetControlParameters\n");
 
     if(pContext->EffectType == LVM_BASS_BOOST) {
-        LOGV("\tLvmEffect_disable : Disabling LVM_BASS_BOOST");    
+        LOGV("\tLvmEffect_disable : Disabling LVM_BASS_BOOST");
         ActiveParams.BE_OperatingMode       = LVM_BE_OFF;
     }
     if(pContext->EffectType == LVM_VIRTUALIZER) {
-        LOGV("\tLvmEffect_enable : Enabling LVM_VIRTUALIZER");    
+        LOGV("\tLvmEffect_disable : Enabling LVM_VIRTUALIZER");
         ActiveParams.VirtualizerOperatingMode   = LVM_MODE_OFF;
     }
     if(pContext->EffectType == LVM_EQUALIZER) {
-        LOGV("\tLvmEffect_enable : Enabling LVM_EQUALIZER");    
+        LOGV("\tLvmEffect_disable : Enabling LVM_EQUALIZER");
         ActiveParams.EQNB_OperatingMode     = LVM_EQNB_OFF;
     }
     if(pContext->EffectType == LVM_VOLUME) {
-        LOGV("\tLvmEffect_enable : Enabling LVM_VOLUME");    
-    } 
-    
+        LOGV("\tLvmEffect_disable : Enabling LVM_VOLUME");
+    }
+
     LvmStatus = LVM_SetControlParameters(pContext->pBundledContext->hInstance, &ActiveParams);
     LVM_ERROR_CHECK(LvmStatus, "LVM_SetControlParameters", "LvmEffect_disable")
     if(LvmStatus != LVM_SUCCESS) return -EINVAL;
-    LOGV("\tLvmEffect_enable Succesfully called LVM_SetControlParameters\n");    
-    #endif    /* end LVM_BUNDLE */    
-    
-    LOGV("\tLvmEffect_enable end");    
+
+    //LOGV("\tLvmEffect_disable Succesfully called LVM_SetControlParameters\n");
+    //LOGV("\tLvmEffect_disable end");
     return 0;
 }
 
-
 //----------------------------------------------------------------------------
 // LvmEffect_free()
 //----------------------------------------------------------------------------
@@ -788,7 +778,6 @@
 //----------------------------------------------------------------------------
 
 void LvmEffect_free(EffectContext *pContext){
-    #ifdef LVM_BUNDLE
     LVM_ReturnStatus_en     LvmStatus=LVM_SUCCESS;         /* Function call status */
     LVM_ControlParams_t     params;                        /* Control Parameters */
     LVM_MemTab_t            MemTab;
@@ -803,21 +792,20 @@
     for (int i=0; i<LVM_NR_MEMORY_REGIONS; i++){
         if (MemTab.Region[i].Size != 0){
             if (MemTab.Region[i].pBaseAddress != NULL){
-                LOGV("\tfree() - START freeing %ld bytes for region %u at %p\n",
+                LOGV("\tLvmEffect_free - START freeing %ld bytes for region %u at %p\n",
                         MemTab.Region[i].Size, i, MemTab.Region[i].pBaseAddress);
 
                 free(MemTab.Region[i].pBaseAddress);
 
-                LOGV("\tfree() - END   freeing %ld bytes for region %u at %p\n",
+                LOGV("\tLvmEffect_free - END   freeing %ld bytes for region %u at %p\n",
                         MemTab.Region[i].Size, i, MemTab.Region[i].pBaseAddress);
             }else{
-                LOGV("\tLVM_ERROR : free() - trying to free with NULL pointer %ld bytes "
+                LOGV("\tLVM_ERROR : LvmEffect_free - trying to free with NULL pointer %ld bytes "
                         "for region %u at %p ERROR\n",
                         MemTab.Region[i].Size, i, MemTab.Region[i].pBaseAddress);
             }
         }
     }
-    #endif    /* end LVM_BUNDLE */
 }    /* end LvmEffect_free */
 
 //----------------------------------------------------------------------------
@@ -835,7 +823,8 @@
 //----------------------------------------------------------------------------
 
 int Effect_configure(EffectContext *pContext, effect_config_t *pConfig){
-    LOGV("\tEffect_configure start");
+    LVM_Fs_en   SampleRate;
+    //LOGV("\tEffect_configure start");
 
     CHECK_ARG(pContext != NULL);
     CHECK_ARG(pConfig != NULL);
@@ -848,36 +837,59 @@
               || pConfig->outputCfg.accessMode == EFFECT_BUFFER_ACCESS_ACCUMULATE);
     CHECK_ARG(pConfig->inputCfg.format == SAMPLE_FORMAT_PCM_S15);
 
-    LOGV("\tEffect_configure calling memcpy");
     memcpy(&pContext->config, pConfig, sizeof(effect_config_t));
-    LOGV("\tEffect_configure End");
+
+    switch (pConfig->inputCfg.samplingRate) {
+    case 8000:
+        SampleRate = LVM_FS_8000;
+        break;
+    case 16000:
+        SampleRate = LVM_FS_16000;
+        break;
+    case 22050:
+        SampleRate = LVM_FS_22050;
+        break;
+    case 32000:
+        SampleRate = LVM_FS_32000;
+        break;
+    case 44100:
+        SampleRate = LVM_FS_44100;
+        break;
+    case 48000:
+        SampleRate = LVM_FS_48000;
+        break;
+    default:
+        LOGV("\tEffect_Configure invalid sampling rate %d", pConfig->inputCfg.samplingRate);
+        return -EINVAL;
+    }
+
+    if(pContext->pBundledContext->SampleRate != SampleRate){
+
+        LVM_ControlParams_t     ActiveParams;
+        LVM_ReturnStatus_en     LvmStatus = LVM_SUCCESS;
+
+        LOGV("\tEffect_configure change sampling rate to %d", SampleRate);
+
+        /* Get the current settings */
+        LvmStatus = LVM_GetControlParameters(pContext->pBundledContext->hInstance,
+                                         &ActiveParams);
+
+        LVM_ERROR_CHECK(LvmStatus, "LVM_GetControlParameters", "Effect_configure")
+        if(LvmStatus != LVM_SUCCESS) return -EINVAL;
+
+        LvmStatus = LVM_SetControlParameters(pContext->pBundledContext->hInstance, &ActiveParams);
+
+        LVM_ERROR_CHECK(LvmStatus, "LVM_SetControlParameters", "Effect_configure")
+        LOGV("\tEffect_configure Succesfully called LVM_SetControlParameters\n");
+
+    }else{
+        //LOGV("\tEffect_configure keep sampling rate at %d", SampleRate);
+    }
+
+    //LOGV("\tEffect_configure End....");
     return 0;
 }   /* end Effect_configure */
 
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
 //----------------------------------------------------------------------------
 // BassGetStrength()
 //----------------------------------------------------------------------------
@@ -893,31 +905,29 @@
 //----------------------------------------------------------------------------
 
 uint32_t BassGetStrength(EffectContext *pContext){
-    LOGV("\tBassGetStrength() (0-1000) -> %d\n", pContext->pBundledContext->BassStrengthSaved);
+    //LOGV("\tBassGetStrength() (0-1000) -> %d\n", pContext->pBundledContext->BassStrengthSaved);
 
-    #ifdef LVM_BUNDLE
     LVM_ControlParams_t     ActiveParams;                           /* Current control Parameters */
     LVM_ReturnStatus_en     LvmStatus = LVM_SUCCESS;                /* Function call status */
-
-    LvmStatus = LVM_GetControlParameters(pContext->pBundledContext->hInstance,  /* Get the current settings */
+    /* Get the current settings */
+    LvmStatus = LVM_GetControlParameters(pContext->pBundledContext->hInstance,
                                          &ActiveParams);
 
     LVM_ERROR_CHECK(LvmStatus, "LVM_GetControlParameters", "BassGetStrength")
     if(LvmStatus != LVM_SUCCESS) return -EINVAL;
 
-    LOGV("\tBassGetStrength Succesfully returned from LVM_GetControlParameters\n");
+    //LOGV("\tBassGetStrength Succesfully returned from LVM_GetControlParameters\n");
 
     /* Check that the strength returned matches the strength that was set earlier */
-    if(ActiveParams.BE_EffectLevel != (LVM_INT16)((15*pContext->pBundledContext->BassStrengthSaved)/1000)){
+    if(ActiveParams.BE_EffectLevel !=
+       (LVM_INT16)((15*pContext->pBundledContext->BassStrengthSaved)/1000)){
         LOGV("\tLVM_ERROR : BassGetStrength module strength does not match savedStrength %d %d\n",
                 ActiveParams.BE_EffectLevel, pContext->pBundledContext->BassStrengthSaved);
         return -EINVAL;
     }
 
-    LOGV("\tBassGetStrength() (0-15)   -> %d\n", ActiveParams.BE_EffectLevel );
-    #endif    /* end LVM_BUNDLE */
-
-    LOGV("\tBassGetStrength() (saved)  -> %d\n", pContext->pBundledContext->BassStrengthSaved );
+    //LOGV("\tBassGetStrength() (0-15)   -> %d\n", ActiveParams.BE_EffectLevel );
+    //LOGV("\tBassGetStrength() (saved)  -> %d\n", pContext->pBundledContext->BassStrengthSaved );
     return pContext->pBundledContext->BassStrengthSaved;
 }    /* end BassGetStrength */
 
@@ -934,11 +944,10 @@
 //----------------------------------------------------------------------------
 
 void BassSetStrength(EffectContext *pContext, uint32_t strength){
-    LOGV("\tBassSetStrength(%d)", strength);
+    //LOGV("\tBassSetStrength(%d)", strength);
 
     pContext->pBundledContext->BassStrengthSaved = (int)strength;
 
-    #ifdef LVM_BUNDLE
     LVM_ControlParams_t     ActiveParams;              /* Current control Parameters */
     LVM_ReturnStatus_en     LvmStatus=LVM_SUCCESS;     /* Function call status */
 
@@ -947,21 +956,19 @@
                                          &ActiveParams);
 
     LVM_ERROR_CHECK(LvmStatus, "LVM_GetControlParameters", "BassSetStrength")
-    LOGV("\tsetStrength Succesfully returned from LVM_GetControlParameters\n");
+    //LOGV("\tBassSetStrength Succesfully returned from LVM_GetControlParameters\n");
 
     /* Bass Enhancement parameters */
-//    ActiveParams.BE_OperatingMode  = LVM_BE_ON;
     ActiveParams.BE_EffectLevel    = (LVM_INT16)((15*strength)/1000);
     ActiveParams.BE_CentreFreq     = LVM_BE_CENTRE_90Hz;
 
-    LOGV("\tBassSetStrength() (0-15)   -> %d\n", ActiveParams.BE_EffectLevel );
+    //LOGV("\tBassSetStrength() (0-15)   -> %d\n", ActiveParams.BE_EffectLevel );
 
     /* Activate the initial settings */
     LvmStatus = LVM_SetControlParameters(pContext->pBundledContext->hInstance, &ActiveParams);
 
     LVM_ERROR_CHECK(LvmStatus, "LVM_SetControlParameters", "BassSetStrength")
-    LOGV("\tBassSetStrength Succesfully called LVM_SetControlParameters\n");
-    #endif    /* end LVM_BUNDLE */
+    //LOGV("\tBassSetStrength Succesfully called LVM_SetControlParameters\n");
 }    /* end BassSetStrength */
 
 //----------------------------------------------------------------------------
@@ -970,7 +977,7 @@
 // Purpose:
 // get the effect strength currently being used, what is actually returned is the strengh that was
 // previously used in the set, this is because the app uses a strength in the range 0-1000 while
-// the Virtualizer uses 1-100, so to avoid a quantisation the original set value is used. However the
+// the Virtualizer uses 1-100, so to avoid a quantisation the original set value is used.However the
 // actual used value is checked to make sure it corresponds to the one being returned
 //
 // Inputs:
@@ -979,9 +986,8 @@
 //----------------------------------------------------------------------------
 
 uint32_t VirtualizerGetStrength(EffectContext *pContext){
-    LOGV("\tVirtualizerGetStrength() (0-1000) -> %d\n", pContext->pBundledContext->VirtStrengthSaved );
+    //LOGV("\tVirtualizerGetStrength (0-1000) -> %d\n",pContext->pBundledContext->VirtStrengthSaved);
 
-    #ifdef LVM_BUNDLE
     LVM_ControlParams_t     ActiveParams;                           /* Current control Parameters */
     LVM_ReturnStatus_en     LvmStatus = LVM_SUCCESS;                /* Function call status */
 
@@ -990,10 +996,8 @@
     LVM_ERROR_CHECK(LvmStatus, "LVM_GetControlParameters", "VirtualizerGetStrength")
     if(LvmStatus != LVM_SUCCESS) return -EINVAL;
 
-    LOGV("\tVirtualizerGetStrength Succesfully returned from LVM_GetControlParameters\n");
-    LOGV("\tVirtualizerGetStrength() (0-100)   -> %d\n", ActiveParams.VirtualizerReverbLevel*10);
-    #endif    /* end LVM_BUNDLE */
-
+    //LOGV("\tVirtualizerGetStrength Succesfully returned from LVM_GetControlParameters\n");
+    //LOGV("\tVirtualizerGetStrength() (0-100)   -> %d\n", ActiveParams.VirtualizerReverbLevel*10);
     return ActiveParams.VirtualizerReverbLevel*10;
 }    /* end getStrength */
 
@@ -1010,31 +1014,28 @@
 //----------------------------------------------------------------------------
 
 void VirtualizerSetStrength(EffectContext *pContext, uint32_t strength){
-    LOGV("\tVirtualizerSetStrength(%d)", strength);
-
-    pContext->pBundledContext->VirtStrengthSaved = (int)strength;
-
-    #ifdef LVM_BUNDLE
+    //LOGV("\tVirtualizerSetStrength(%d)", strength);
     LVM_ControlParams_t     ActiveParams;              /* Current control Parameters */
     LVM_ReturnStatus_en     LvmStatus=LVM_SUCCESS;     /* Function call status */
 
+    pContext->pBundledContext->VirtStrengthSaved = (int)strength;
+
     /* Get the current settings */
     LvmStatus = LVM_GetControlParameters(pContext->pBundledContext->hInstance,&ActiveParams);
 
     LVM_ERROR_CHECK(LvmStatus, "LVM_GetControlParameters", "VirtualizerSetStrength")
-    LOGV("\tVirtualizerSetStrength Succesfully returned from LVM_GetControlParameters\n");
+    //LOGV("\tVirtualizerSetStrength Succesfully returned from LVM_GetControlParameters\n");
 
     /* Virtualizer parameters */
     ActiveParams.VirtualizerReverbLevel    = (LVM_INT16)(strength/10);
 
-    LOGV("\tVirtualizerSetStrength() (0-1000)   -> %d\n", strength );
-    LOGV("\tVirtualizerSetStrength() (0- 100)   -> %d\n", ActiveParams.VirtualizerReverbLevel );
+    //LOGV("\tVirtualizerSetStrength() (0-1000)   -> %d\n", strength );
+    //LOGV("\tVirtualizerSetStrength() (0- 100)   -> %d\n", ActiveParams.VirtualizerReverbLevel );
 
     /* Activate the initial settings */
     LvmStatus = LVM_SetControlParameters(pContext->pBundledContext->hInstance, &ActiveParams);
     LVM_ERROR_CHECK(LvmStatus, "LVM_SetControlParameters", "VirtualizerSetStrength")
-    LOGV("\tVirtualizerSetStrength Succesfully called LVM_SetControlParameters\n");
-    #endif    /* end LVM_BUNDLE */
+    //LOGV("\tVirtualizerSetStrength Succesfully called LVM_SetControlParameters\n");
 }    /* end setStrength */
 
 //----------------------------------------------------------------------------
@@ -1051,26 +1052,22 @@
 //----------------------------------------------------------------------------
 int32_t EqualizerGetBandLevel(EffectContext *pContext, int32_t band){
 
-	int32_t Gain =0;
+    int32_t Gain =0;
+    LVM_ControlParams_t     ActiveParams;                           /* Current control Parameters */
+    LVM_ReturnStatus_en     LvmStatus = LVM_SUCCESS;                /* Function call status */
+    LVM_EQNB_BandDef_t      *BandDef;
+    /* Get the current settings */
+    LvmStatus = LVM_GetControlParameters(pContext->pBundledContext->hInstance,
+                                         &ActiveParams);
 
-	#ifdef LVM_BUNDLE
-	LVM_ControlParams_t     ActiveParams;                           /* Current control Parameters */
-	LVM_ReturnStatus_en     LvmStatus = LVM_SUCCESS;                /* Function call status */
-	LVM_EQNB_BandDef_t      *BandDef;
+    LVM_ERROR_CHECK(LvmStatus, "LVM_GetControlParameters", "EqualizerGetBandLevel")
 
-	LvmStatus = LVM_GetControlParameters(pContext->pBundledContext->hInstance,        /* Get the current settings */
-										 &ActiveParams);
+    BandDef = ActiveParams.pEQNB_BandDefinition;
+    Gain    = (int32_t)BandDef[band].Gain*100;    // Convert to millibels
 
-	LVM_ERROR_CHECK(LvmStatus, "LVM_GetControlParameters", "getBandLevel")
-
-	BandDef = ActiveParams.pEQNB_BandDefinition;
-	Gain    = (int32_t)BandDef[band].Gain*100;    // Convert to millibels
-
-	LOGV("\tgetBandLevel() -> %d\n", Gain );
-	LOGV("\tgetBandLevel Succesfully returned from LVM_GetControlParameters\n");
-	#endif    /* end LVM_BUNDLE */
-
-	return Gain;
+    //LOGV("\tEqualizerGetBandLevel -> %d\n", Gain );
+    //LOGV("\tEqualizerGetBandLevel Succesfully returned from LVM_GetControlParameters\n");
+    return Gain;
 }
 
 //----------------------------------------------------------------------------
@@ -1088,41 +1085,33 @@
 //
 //---------------------------------------------------------------------------
 void EqualizerSetBandLevel(EffectContext *pContext, int band, int Gain){
-	int gainRounded;
-	if(Gain > 0){
-		gainRounded = (int)((Gain+50)/100);
-	}else{
-		gainRounded = (int)((Gain-50)/100);
-	}
-    LOGV("\tsetBandLevel(%d)->(%d)", Gain, gainRounded);
+    int gainRounded;
+    if(Gain > 0){
+        gainRounded = (int)((Gain+50)/100);
+    }else{
+        gainRounded = (int)((Gain-50)/100);
+    }
+    //LOGV("\tEqualizerSetBandLevel(%d)->(%d)", Gain, gainRounded);
 
-    #ifdef LVM_BUNDLE
+
     LVM_ControlParams_t     ActiveParams;              /* Current control Parameters */
     LVM_ReturnStatus_en     LvmStatus=LVM_SUCCESS;     /* Function call status */
-	LVM_EQNB_BandDef_t      *BandDef;
+    LVM_EQNB_BandDef_t      *BandDef;
 
     /* Get the current settings */
     LvmStatus = LVM_GetControlParameters(pContext->pBundledContext->hInstance, &ActiveParams);
-    LVM_ERROR_CHECK(LvmStatus, "LVM_GetControlParameters", "setBandLevel")
-    LOGV("\tsetBandLevel Succesfully returned from LVM_GetControlParameters\n");
-    LOGV("\tsetBandLevel() just Got -> %d\n", ActiveParams.pEQNB_BandDefinition[band].Gain);
+    LVM_ERROR_CHECK(LvmStatus, "LVM_GetControlParameters", "EqualizerSetBandLevel")
+    //LOGV("\tEqualizerSetBandLevel Succesfully returned from LVM_GetControlParameters\n");
+    //LOGV("\tEqualizerSetBandLevel just Got -> %d\n", ActiveParams.pEQNB_BandDefinition[band].Gain);
 
     /* Set local EQ parameters */
-	BandDef = ActiveParams.pEQNB_BandDefinition;
-	ActiveParams.pEQNB_BandDefinition[band].Gain = gainRounded;
+    BandDef = ActiveParams.pEQNB_BandDefinition;
+    ActiveParams.pEQNB_BandDefinition[band].Gain = gainRounded;
 
     /* Activate the initial settings */
     LvmStatus = LVM_SetControlParameters(pContext->pBundledContext->hInstance, &ActiveParams);
-    LVM_ERROR_CHECK(LvmStatus, "LVM_SetControlParameters", "setBandLevel")
-    LOGV("\tsetBandLevel() just Set -> %d\n", ActiveParams.pEQNB_BandDefinition[band].Gain);
-
-    /* Get the current settings to check they were applied ok, might not work as process not called*/
-    LvmStatus = LVM_GetControlParameters(pContext->pBundledContext->hInstance, &ActiveParams);
-    LVM_ERROR_CHECK(LvmStatus, "LVM_GetControlParameters", "setBandLevel")
-    LOGV("\tLVM_ERROR : remove this test setBandLevel Succesfully returned from LVM_GetControlParameters\n");
-    LOGV("\tsetBandLevel() just Got -> %d\n", ActiveParams.pEQNB_BandDefinition[band].Gain);
-    LOGV("\tsetBandLevel Succesfully called LVM_SetControlParameters\n");
-    #endif    /* end LVM_BUNDLE */
+    LVM_ERROR_CHECK(LvmStatus, "LVM_SetControlParameters", "EqualizerSetBandLevel")
+    //LOGV("\tEqualizerSetBandLevel just Set -> %d\n", ActiveParams.pEQNB_BandDefinition[band].Gain);
 
     pContext->pBundledContext->CurPreset = PRESET_CUSTOM;
     return;
@@ -1140,26 +1129,23 @@
 //
 //----------------------------------------------------------------------------
 int32_t EqualizerGetCentreFrequency(EffectContext *pContext, int32_t band){
-	int32_t Frequency =0;
+    int32_t Frequency =0;
 
-	#ifdef LVM_BUNDLE
-	LVM_ControlParams_t     ActiveParams;                           /* Current control Parameters */
-	LVM_ReturnStatus_en     LvmStatus = LVM_SUCCESS;                /* Function call status */
-	LVM_EQNB_BandDef_t      *BandDef;
+    LVM_ControlParams_t     ActiveParams;                           /* Current control Parameters */
+    LVM_ReturnStatus_en     LvmStatus = LVM_SUCCESS;                /* Function call status */
+    LVM_EQNB_BandDef_t      *BandDef;
+    /* Get the current settings */
+    LvmStatus = LVM_GetControlParameters(pContext->pBundledContext->hInstance,
+                                         &ActiveParams);
 
-	LvmStatus = LVM_GetControlParameters(pContext->pBundledContext->hInstance,        /* Get the current settings */
-										 &ActiveParams);
+    LVM_ERROR_CHECK(LvmStatus, "LVM_GetControlParameters", "EqualizerGetCentreFrequency")
 
-	LVM_ERROR_CHECK(LvmStatus, "LVM_GetControlParameters", "getCentreFrequency")
+    BandDef   = ActiveParams.pEQNB_BandDefinition;
+    Frequency = (int32_t)BandDef[band].Frequency*1000;     // Convert to millibels
 
-	BandDef   = ActiveParams.pEQNB_BandDefinition;
-	Frequency = (int32_t)BandDef[band].Frequency*1000;     // Convert to millibels
-
-	LOGV("\tgetCentreFrequency() -> %d\n", Frequency );
-	LOGV("\tgetCentreFrequency Succesfully returned from LVM_GetControlParameters\n");
-	#endif    /* end LVM_BUNDLE */
-
-	return Frequency;
+    //LOGV("\tEqualizerGetCentreFrequency -> %d\n", Frequency );
+    //LOGV("\tEqualizerGetCentreFrequency Succesfully returned from LVM_GetControlParameters\n");
+    return Frequency;
 }
 
 //----------------------------------------------------------------------------
@@ -1180,10 +1166,11 @@
 //  pLow:       lower band range
 //  pLow:       upper band range
 //----------------------------------------------------------------------------
-int32_t EqualizerGetBandFreqRange(EffectContext *pContext, int32_t band, uint32_t *pLow, uint32_t *pHi){
-	*pLow = bandFreqRange[band][0];
-	*pHi  = bandFreqRange[band][1];
-	return 0;
+int32_t EqualizerGetBandFreqRange(EffectContext *pContext, int32_t band, uint32_t *pLow,
+                                  uint32_t *pHi){
+    *pLow = bandFreqRange[band][0];
+    *pHi  = bandFreqRange[band][1];
+    return 0;
 }
 
 //----------------------------------------------------------------------------
@@ -1206,16 +1193,16 @@
 int32_t EqualizerGetBand(EffectContext *pContext, uint32_t targetFreq){
     int band = 0;
 
-	if(targetFreq < bandFreqRange[0][0]){
-		return -EINVAL;
-	}else if(targetFreq == bandFreqRange[0][0]){
-		return 0;
-	}
-	for(int i=0; i<FIVEBAND_NUMBANDS;i++){
-		if((targetFreq > bandFreqRange[i][0])&&(targetFreq <= bandFreqRange[i][1])){
-			band = i;
-		}
-	}
+    if(targetFreq < bandFreqRange[0][0]){
+        return -EINVAL;
+    }else if(targetFreq == bandFreqRange[0][0]){
+        return 0;
+    }
+    for(int i=0; i<FIVEBAND_NUMBANDS;i++){
+        if((targetFreq > bandFreqRange[i][0])&&(targetFreq <= bandFreqRange[i][1])){
+            band = i;
+        }
+    }
     return band;
 }
 
@@ -1233,7 +1220,7 @@
 //
 //----------------------------------------------------------------------------
 int32_t EqualizerGetPreset(EffectContext *pContext){
-	return pContext->pBundledContext->CurPreset;
+    return pContext->pBundledContext->CurPreset;
 }
 
 //----------------------------------------------------------------------------
@@ -1251,36 +1238,35 @@
 //----------------------------------------------------------------------------
 void EqualizerSetPreset(EffectContext *pContext, int preset){
 
-    LOGV("\tsetPreset(%d)", preset);
+    //LOGV("\tEqualizerSetPreset(%d)", preset);
     pContext->pBundledContext->CurPreset = preset;
 
-    #ifdef LVM_BUNDLE
     LVM_ControlParams_t     ActiveParams;              /* Current control Parameters */
     LVM_ReturnStatus_en     LvmStatus=LVM_SUCCESS;     /* Function call status */
 
     /* Get the current settings */
     LvmStatus = LVM_GetControlParameters(pContext->pBundledContext->hInstance, &ActiveParams);
-    LVM_ERROR_CHECK(LvmStatus, "LVM_GetControlParameters", "setPreset")
-    LOGV("\tsetPreset Succesfully returned from LVM_GetControlParameters\n");
+    LVM_ERROR_CHECK(LvmStatus, "LVM_GetControlParameters", "EqualizerSetPreset")
+    //LOGV("\tEqualizerSetPreset Succesfully returned from LVM_GetControlParameters\n");
 
     //ActiveParams.pEQNB_BandDefinition = &BandDefs[0];
     for (int i=0; i<FIVEBAND_NUMBANDS; i++)
     {
-    	ActiveParams.pEQNB_BandDefinition[i].Frequency = EQNB_5BandPresetsFrequencies[i];
-    	ActiveParams.pEQNB_BandDefinition[i].QFactor   = EQNB_5BandPresetsQFactors[i];
-    	ActiveParams.pEQNB_BandDefinition[i].Gain
-    	= EQNB_5BandNormalPresets[i + preset * FIVEBAND_NUMBANDS];
+        ActiveParams.pEQNB_BandDefinition[i].Frequency = EQNB_5BandPresetsFrequencies[i];
+        ActiveParams.pEQNB_BandDefinition[i].QFactor   = EQNB_5BandPresetsQFactors[i];
+        ActiveParams.pEQNB_BandDefinition[i].Gain
+        = EQNB_5BandSoftPresets[i + preset * FIVEBAND_NUMBANDS];
     }
     /* Activate the new settings */
     LvmStatus = LVM_SetControlParameters(pContext->pBundledContext->hInstance, &ActiveParams);
-    LVM_ERROR_CHECK(LvmStatus, "LVM_SetControlParameters", "setPreset")
-    LOGV("\tsetPreset Succesfully called LVM_SetControlParameters\n");
-    #endif    /* end LVM_BUNDLE */
+    LVM_ERROR_CHECK(LvmStatus, "LVM_SetControlParameters", "EqualizerSetPreset")
 
+    //LOGV("\tEqualizerSetPreset Succesfully called LVM_SetControlParameters\n");
     return;
 }
+
 int32_t EqualizerGetNumPresets(){
-	return 10;
+    return sizeof(gEqualizerPresets) / sizeof(PresetConfig);
 }
 
 //----------------------------------------------------------------------------
@@ -1295,14 +1281,14 @@
 //
 //-------------------------------------------------------------------------
 const char * EqualizerGetPresetName(int32_t preset){
-    LOGV("\tEqualizerGetPresetName start(%d)", preset);
+    //LOGV("\tEqualizerGetPresetName start(%d)", preset);
     if (preset == PRESET_CUSTOM) {
         return "Custom";
     } else {
         return gEqualizerPresets[preset].name;
     }
-    LOGV("\tEqualizerGetPresetName end(%d)", preset);
-	return 0;
+    //LOGV("\tEqualizerGetPresetName end(%d)", preset);
+    return 0;
 }
 
 //----------------------------------------------------------------------------
@@ -1317,30 +1303,35 @@
 //----------------------------------------------------------------------------
 
 int VolumeSetVolumeLevel(EffectContext *pContext, int16_t level){
-    LOGV("\tVolumeSetVolumeLevel start(%d)", level);
 
-    #ifdef LVM_BUNDLE
     LVM_ControlParams_t     ActiveParams;              /* Current control Parameters */
     LVM_ReturnStatus_en     LvmStatus=LVM_SUCCESS;     /* Function call status */
 
+    //LOGV("\tVolumeSetVolumeLevel Level to be set is %d %d\n", level, (LVM_INT16)(level/100));
     /* Get the current settings */
     LvmStatus = LVM_GetControlParameters(pContext->pBundledContext->hInstance, &ActiveParams);
     LVM_ERROR_CHECK(LvmStatus, "LVM_GetControlParameters", "VolumeSetVolumeLevel")
     if(LvmStatus != LVM_SUCCESS) return -EINVAL;
-    LOGV("\tVolumeSetVolumeLevel Succesfully returned from LVM_GetControlParameters\n");
+    //LOGV("\tVolumeSetVolumeLevel Succesfully returned from LVM_GetControlParameters got: %d\n",
+    //ActiveParams.VC_EffectLevel);
 
     /* Volume parameters */
     ActiveParams.VC_EffectLevel  = (LVM_INT16)(level/100);
-    LOGV("\tVolumeSetVolumeLevel() (-96dB -> 0dB)   -> %d\n", ActiveParams.VC_EffectLevel );
+    //LOGV("\tVolumeSetVolumeLevel() (-96dB -> 0dB)   -> %d\n", ActiveParams.VC_EffectLevel );
 
     /* Activate the initial settings */
     LvmStatus = LVM_SetControlParameters(pContext->pBundledContext->hInstance, &ActiveParams);
     LVM_ERROR_CHECK(LvmStatus, "LVM_SetControlParameters", "VolumeSetVolumeLevel")
     if(LvmStatus != LVM_SUCCESS) return -EINVAL;
 
-    LOGV("\tVolumeSetVolumeLevel Succesfully called LVM_SetControlParameters\n");
-    LOGV("\tVolumeSetVolumeLevel end");
-    #endif    /* end LVM_BUNDLE */
+    //LOGV("\tVolumeSetVolumeLevel Succesfully called LVM_SetControlParameters\n");
+
+    /* Get the current settings */
+    LvmStatus = LVM_GetControlParameters(pContext->pBundledContext->hInstance, &ActiveParams);
+    LVM_ERROR_CHECK(LvmStatus, "LVM_GetControlParameters", "VolumeSetVolumeLevel")
+    if(LvmStatus != LVM_SUCCESS) return -EINVAL;
+
+    //LOGV("\tVolumeSetVolumeLevel just set (-96dB -> 0dB)   -> %d\n", ActiveParams.VC_EffectLevel );
     return 0;
 }    /* end setVolumeLevel */
 
@@ -1356,8 +1347,8 @@
 
 int VolumeGetVolumeLevel(EffectContext *pContext, int16_t *level){
 
-    LOGV("\tVolumeGetVolumeLevel start");
-    #ifdef LVM_BUNDLE
+    //LOGV("\tVolumeGetVolumeLevel start");
+
     LVM_ControlParams_t     ActiveParams;                           /* Current control Parameters */
     LVM_ReturnStatus_en     LvmStatus = LVM_SUCCESS;                /* Function call status */
 
@@ -1365,12 +1356,11 @@
     LVM_ERROR_CHECK(LvmStatus, "LVM_GetControlParameters", "VolumeGetVolumeLevel")
     if(LvmStatus != LVM_SUCCESS) return -EINVAL;
 
-    LOGV("\tVolumeGetVolumeLevel() (-96dB -> 0dB) -> %d\n", ActiveParams.VC_EffectLevel );
-    LOGV("\tVolumeGetVolumeLevel Succesfully returned from LVM_GetControlParameters\n");
-    #endif    /* end LVM_BUNDLE */
+    //LOGV("\tVolumeGetVolumeLevel() (-96dB -> 0dB) -> %d\n", ActiveParams.VC_EffectLevel );
+    //LOGV("\tVolumeGetVolumeLevel Succesfully returned from LVM_GetControlParameters\n");
 
     *level = ActiveParams.VC_EffectLevel*100;     // Convert dB to millibels
-    LOGV("\tVolumeGetVolumeLevel end");
+    //LOGV("\tVolumeGetVolumeLevel end");
     return 0;
 }    /* end VolumeGetVolumeLevel */
 
@@ -1386,11 +1376,10 @@
 //----------------------------------------------------------------------------
 
 int32_t VolumeSetMute(EffectContext *pContext, uint32_t mute){
-    LOGV("\tVolumeSetMute start()");
+    //LOGV("\tVolumeSetMute start(%d)", mute);
 
     pContext->pBundledContext->bMuteEnabled = mute;
 
-    #ifdef LVM_BUNDLE
     LVM_ControlParams_t     ActiveParams;              /* Current control Parameters */
     LVM_ReturnStatus_en     LvmStatus=LVM_SUCCESS;     /* Function call status */
 
@@ -1399,15 +1388,15 @@
     LVM_ERROR_CHECK(LvmStatus, "LVM_GetControlParameters", "VolumeSetMute")
     if(LvmStatus != LVM_SUCCESS) return -EINVAL;
 
-    LOGV("\tVolumeSetMute Succesfully returned from LVM_GetControlParameters\n");
-    LOGV("\tVolumeSetMute() to %d, level was %d\n", mute, ActiveParams.BE_EffectLevel );
+    //LOGV("\tVolumeSetMute Succesfully returned from LVM_GetControlParameters\n");
+    //LOGV("\tVolumeSetMute to %d, level was %d\n", mute, ActiveParams.VC_EffectLevel );
 
     /* Set appropriate volume level */
     if(pContext->pBundledContext->bMuteEnabled == LVM_TRUE){
-    	pContext->pBundledContext->levelSaved = ActiveParams.VC_EffectLevel;
-    	ActiveParams.VC_EffectLevel           = -96;
+        pContext->pBundledContext->levelSaved = ActiveParams.VC_EffectLevel;
+        ActiveParams.VC_EffectLevel           = -96;
     }else{
-    	ActiveParams.VC_EffectLevel  = pContext->pBundledContext->levelSaved;
+        ActiveParams.VC_EffectLevel  = pContext->pBundledContext->levelSaved;
     }
 
     /* Activate the initial settings */
@@ -1415,14 +1404,13 @@
     LVM_ERROR_CHECK(LvmStatus, "LVM_SetControlParameters", "VolumeSetMute")
     if(LvmStatus != LVM_SUCCESS) return -EINVAL;
 
-    LOGV("\tVolumeSetMute Succesfully called LVM_SetControlParameters\n");
-    #endif    /* end LVM_BUNDLE */
-    LOGV("\tVolumeSetMute start()");
+    //LOGV("\tVolumeSetMute Succesfully called LVM_SetControlParameters\n");
+    //LOGV("\tVolumeSetMute end");
     return 0;
 }    /* end setMute */
 
 //----------------------------------------------------------------------------
-// VolumeSetMute()
+// VolumeGetMute()
 //----------------------------------------------------------------------------
 // Purpose:
 //
@@ -1434,31 +1422,175 @@
 //----------------------------------------------------------------------------
 
 int32_t VolumeGetMute(EffectContext *pContext, uint32_t *mute){
-    LOGV("\tVolumeGetMute start");
-    if((pContext->pBundledContext->bMuteEnabled == LVM_FALSE)||(pContext->pBundledContext->bMuteEnabled == LVM_TRUE)){
-    	*mute = pContext->pBundledContext->bMuteEnabled;
-    	return 0;
+    //LOGV("\tVolumeGetMute start");
+    if((pContext->pBundledContext->bMuteEnabled == LVM_FALSE)||
+       (pContext->pBundledContext->bMuteEnabled == LVM_TRUE)){
+        *mute = pContext->pBundledContext->bMuteEnabled;
+        return 0;
     }else{
-    	LOGV("\tLVM_ERROR : VolumeGetMute read an invalid value from context %d", pContext->pBundledContext->bMuteEnabled);
-    	return -EINVAL;
+        LOGV("\tLVM_ERROR : VolumeGetMute read an invalid value from context %d",
+              pContext->pBundledContext->bMuteEnabled);
+        return -EINVAL;
     }
-    LOGV("\tVolumeGetMute start");
+    //LOGV("\tVolumeGetMute end");
 }    /* end getMute */
 
+int16_t VolumeConvertStereoPosition(int16_t position){
+    int16_t convertedPosition = 0;
+
+    convertedPosition = (int16_t)(((float)position/1000)*96);
+    return convertedPosition;
+
+}
+
+//----------------------------------------------------------------------------
+// VolumeSetStereoPosition()
+//----------------------------------------------------------------------------
+// Purpose:
+//
+// Inputs:
+//  pContext:       effect engine context
+//  position:       stereo position
+//
+// Outputs:
+//----------------------------------------------------------------------------
+
+int VolumeSetStereoPosition(EffectContext *pContext, int16_t position){
+
+    LVM_ControlParams_t     ActiveParams;              /* Current control Parameters */
+    LVM_ReturnStatus_en     LvmStatus=LVM_SUCCESS;     /* Function call status */
+    LVM_INT16               Balance = 0;
+
+    
+
+    pContext->pBundledContext->positionSaved = position;
+    Balance = VolumeConvertStereoPosition(pContext->pBundledContext->positionSaved);
+
+    //LOGV("\tVolumeSetStereoPosition start pContext->pBundledContext->positionSaved = %d", pContext->pBundledContext->positionSaved);
+
+    if(pContext->pBundledContext->bStereoPositionEnabled == LVM_TRUE){
+
+        //LOGV("\tVolumeSetStereoPosition Position to be set is %d %d\n", position, Balance);
+        pContext->pBundledContext->positionSaved = position;
+        /* Get the current settings */
+        LvmStatus = LVM_GetControlParameters(pContext->pBundledContext->hInstance, &ActiveParams);
+        LVM_ERROR_CHECK(LvmStatus, "LVM_GetControlParameters", "VolumeSetStereoPosition")
+        if(LvmStatus != LVM_SUCCESS) return -EINVAL;
+        //LOGV("\tVolumeSetStereoPosition Succesfully returned from LVM_GetControlParameters got:"
+        //     " %d\n", ActiveParams.VC_Balance);
+
+        /* Volume parameters */
+        ActiveParams.VC_Balance  = Balance;
+        //LOGV("\tVolumeSetStereoPosition() (-96dB -> +96dB)   -> %d\n", ActiveParams.VC_Balance );
+
+        /* Activate the initial settings */
+        LvmStatus = LVM_SetControlParameters(pContext->pBundledContext->hInstance, &ActiveParams);
+        LVM_ERROR_CHECK(LvmStatus, "LVM_SetControlParameters", "VolumeSetStereoPosition")
+        if(LvmStatus != LVM_SUCCESS) return -EINVAL;
+
+        //LOGV("\tVolumeSetStereoPosition Succesfully called LVM_SetControlParameters\n");
+
+        /* Get the current settings */
+        LvmStatus = LVM_GetControlParameters(pContext->pBundledContext->hInstance, &ActiveParams);
+        LVM_ERROR_CHECK(LvmStatus, "LVM_GetControlParameters", "VolumeSetStereoPosition")
+        if(LvmStatus != LVM_SUCCESS) return -EINVAL;
+        //LOGV("\tVolumeSetStereoPosition Succesfully returned from LVM_GetControlParameters got: "
+        //     "%d\n", ActiveParams.VC_Balance);
+    }
+    else{
+        //LOGV("\tVolumeSetStereoPosition Position attempting to set, but not enabled %d %d\n",
+        //position, Balance);
+    }
+    //LOGV("\tVolumeSetStereoPosition end pContext->pBundledContext->positionSaved = %d\n", pContext->pBundledContext->positionSaved);
+    return 0;
+}    /* end VolumeSetStereoPosition */
 
 
+//----------------------------------------------------------------------------
+// VolumeGetStereoPosition()
+//----------------------------------------------------------------------------
+// Purpose:
+//
+// Inputs:
+//  pContext:       effect engine context
+//
+// Outputs:
+//  position:       stereo position
+//----------------------------------------------------------------------------
 
+int32_t VolumeGetStereoPosition(EffectContext *pContext, int16_t *position){
+    //LOGV("\tVolumeGetStereoPosition start");
 
+    LVM_ControlParams_t     ActiveParams;                           /* Current control Parameters */
+    LVM_ReturnStatus_en     LvmStatus = LVM_SUCCESS;                /* Function call status */
+    LVM_INT16               balance;
 
+    //LOGV("\tVolumeGetStereoPosition start pContext->pBundledContext->positionSaved = %d", pContext->pBundledContext->positionSaved);
 
+    LvmStatus = LVM_GetControlParameters(pContext->pBundledContext->hInstance, &ActiveParams);
+    LVM_ERROR_CHECK(LvmStatus, "LVM_GetControlParameters", "VolumeGetStereoPosition")
+    if(LvmStatus != LVM_SUCCESS) return -EINVAL;
 
+    //LOGV("\tVolumeGetStereoPosition -> %d\n", ActiveParams.VC_Balance);
+    //LOGV("\tVolumeGetStereoPosition Succesfully returned from LVM_GetControlParameters\n");
 
+    balance = VolumeConvertStereoPosition(pContext->pBundledContext->positionSaved);
 
+    if(pContext->pBundledContext->bStereoPositionEnabled == LVM_TRUE){
+        if(balance != ActiveParams.VC_Balance){
+            return -EINVAL;
+        }
+    }
+    *position = (LVM_INT16)pContext->pBundledContext->positionSaved;     // Convert dB to millibels
+    //LOGV("\tVolumeGetStereoPosition end returning pContext->pBundledContext->positionSaved = %d\n", pContext->pBundledContext->positionSaved);
+    return 0;
+}    /* end VolumeGetStereoPosition */
 
+//----------------------------------------------------------------------------
+// VolumeEnableStereoPosition()
+//----------------------------------------------------------------------------
+// Purpose:
+//
+// Inputs:
+//  pContext:   effect engine context
+//  mute:       enable/disable flag
+//
+//----------------------------------------------------------------------------
 
+int32_t VolumeEnableStereoPosition(EffectContext *pContext, uint32_t enabled){
+    //LOGV("\tVolumeEnableStereoPosition start()");
 
+    pContext->pBundledContext->bStereoPositionEnabled = enabled;
 
+    LVM_ControlParams_t     ActiveParams;              /* Current control Parameters */
+    LVM_ReturnStatus_en     LvmStatus=LVM_SUCCESS;     /* Function call status */
 
+    /* Get the current settings */
+    LvmStatus = LVM_GetControlParameters(pContext->pBundledContext->hInstance, &ActiveParams);
+    LVM_ERROR_CHECK(LvmStatus, "LVM_GetControlParameters", "VolumeEnableStereoPosition")
+    if(LvmStatus != LVM_SUCCESS) return -EINVAL;
+
+    //LOGV("\tVolumeEnableStereoPosition Succesfully returned from LVM_GetControlParameters\n");
+    //LOGV("\tVolumeEnableStereoPosition to %d, position was %d\n",
+    //     enabled, ActiveParams.VC_Balance );
+
+    /* Set appropriate stereo position */
+    if(pContext->pBundledContext->bStereoPositionEnabled == LVM_FALSE){
+        ActiveParams.VC_Balance = 0;
+    }else{
+        ActiveParams.VC_Balance  =
+                            VolumeConvertStereoPosition(pContext->pBundledContext->positionSaved);
+    }
+
+    /* Activate the initial settings */
+    LvmStatus = LVM_SetControlParameters(pContext->pBundledContext->hInstance, &ActiveParams);
+    LVM_ERROR_CHECK(LvmStatus, "LVM_SetControlParameters", "VolumeEnableStereoPosition")
+    if(LvmStatus != LVM_SUCCESS) return -EINVAL;
+
+    //LOGV("\tVolumeEnableStereoPosition Succesfully called LVM_SetControlParameters\n");
+    //LOGV("\tVolumeEnableStereoPosition end()\n");
+    return 0;
+}    /* end VolumeEnableStereoPosition */
 
 //----------------------------------------------------------------------------
 // BassBoost_getParameter()
@@ -1482,24 +1614,18 @@
 //----------------------------------------------------------------------------
 
 int BassBoost_getParameter(EffectContext     *pContext,
-                           int32_t              *pParam,
-                           size_t               *pValueSize,
-                           void                 *pValue){
+                           int32_t           *pParam,
+                           size_t            *pValueSize,
+                           void              *pValue){
     int status = 0;
     int32_t param = *pParam++;
     int32_t param2;
     char *name;
 
-    LOGV("\tBassBoost_getParameter start");
+    //LOGV("\tBassBoost_getParameter start");
 
     switch (param){
         case BASSBOOST_PARAM_STRENGTH_SUP:
-            //if (*pValueSize != sizeof(uint32_t)){
-            //    LOGV("\tLVM_ERROR : BassBoost_getParameter() invalid pValueSize1 %d", *pValueSize);
-            //    return -EINVAL;
-            //}
-            //*pValueSize = sizeof(uint32_t);
-            //break;
         case BASSBOOST_PARAM_STRENGTH:
             if (*pValueSize != sizeof(int16_t)){
                 LOGV("\tLVM_ERROR : BassBoost_getParameter() invalid pValueSize2 %d", *pValueSize);
@@ -1509,7 +1635,7 @@
             break;
 
         default:
-        	LOGV("\tLVM_ERROR : BassBoost_getParameter() invalid param %d", param);
+            LOGV("\tLVM_ERROR : BassBoost_getParameter() invalid param %d", param);
             return -EINVAL;
     }
 
@@ -1517,15 +1643,15 @@
         case BASSBOOST_PARAM_STRENGTH_SUP:
             *(uint32_t *)pValue = 1;
 
-            LOGV("\tBassBoost_getParameter() BASSBOOST_PARAM_STRENGTH_SUP Value is %d",
-                    *(uint32_t *)pValue);
+            //LOGV("\tBassBoost_getParameter() BASSBOOST_PARAM_STRENGTH_SUP Value is %d",
+            //        *(uint32_t *)pValue);
             break;
 
         case BASSBOOST_PARAM_STRENGTH:
             *(int16_t *)pValue = BassGetStrength(pContext);
 
-            LOGV("\tBassBoost_getParameter() BASSBOOST_PARAM_STRENGTH Value is %d",
-                    *(int16_t *)pValue);
+            //LOGV("\tBassBoost_getParameter() BASSBOOST_PARAM_STRENGTH Value is %d",
+            //        *(int16_t *)pValue);
             break;
 
         default:
@@ -1534,11 +1660,10 @@
             break;
     }
 
-    LOGV("\tBassBoost_getParameter end");
+    //LOGV("\tBassBoost_getParameter end");
     return status;
 } /* end BassBoost_getParameter */
 
-
 //----------------------------------------------------------------------------
 // BassBoost_setParameter()
 //----------------------------------------------------------------------------
@@ -1558,22 +1683,22 @@
     int status = 0;
     int16_t strength;
 
-    LOGV("\tBassBoost_setParameter start");
+    //LOGV("\tBassBoost_setParameter start");
 
     switch (*pParam){
         case BASSBOOST_PARAM_STRENGTH:
             strength = *(int16_t *)pValue;
-            LOGV("\tBassBoost_setParameter() BASSBOOST_PARAM_STRENGTH value is %d", strength);
-            LOGV("\tBassBoost_setParameter() Calling pBassBoost->BassSetStrength");
+            //LOGV("\tBassBoost_setParameter() BASSBOOST_PARAM_STRENGTH value is %d", strength);
+            //LOGV("\tBassBoost_setParameter() Calling pBassBoost->BassSetStrength");
             BassSetStrength(pContext, (int32_t)strength);
-            LOGV("\tBassBoost_setParameter() Called pBassBoost->BassSetStrength");
+            //LOGV("\tBassBoost_setParameter() Called pBassBoost->BassSetStrength");
            break;
         default:
             LOGV("\tLVM_ERROR : BassBoost_setParameter() invalid param %d", *pParam);
             break;
     }
 
-    LOGV("\tBassBoost_setParameter end");
+    //LOGV("\tBassBoost_setParameter end");
     return status;
 } /* end BassBoost_setParameter */
 
@@ -1607,19 +1732,13 @@
     int32_t param2;
     char *name;
 
-    LOGV("\tVirtualizer_getParameter start");
+    //LOGV("\tVirtualizer_getParameter start");
 
     switch (param){
         case VIRTUALIZER_PARAM_STRENGTH_SUP:
-            //if (*pValueSize != sizeof(uint32_t)){
-            //    LOGV("\tLVM_ERROR : Virtualizer_getParameter() invalid pValueSize1 %d", *pValueSize);
-            //    return -EINVAL;
-            //}
-            //*pValueSize = sizeof(uint32_t);
-            //break;
         case VIRTUALIZER_PARAM_STRENGTH:
             if (*pValueSize != sizeof(int16_t)){
-                LOGV("\tLVM_ERROR : Virtualizer_getParameter() invalid pValueSize2 %d", *pValueSize);
+                LOGV("\tLVM_ERROR : Virtualizer_getParameter() invalid pValueSize2 %d",*pValueSize);
                 return -EINVAL;
             }
             *pValueSize = sizeof(int16_t);
@@ -1634,15 +1753,15 @@
         case VIRTUALIZER_PARAM_STRENGTH_SUP:
             *(uint32_t *)pValue = 1;
 
-            LOGV("\tVirtualizer_getParameter() VIRTUALIZER_PARAM_STRENGTH_SUP Value is %d",
-                    *(uint32_t *)pValue);
+            //LOGV("\tVirtualizer_getParameter() VIRTUALIZER_PARAM_STRENGTH_SUP Value is %d",
+            //        *(uint32_t *)pValue);
             break;
 
         case VIRTUALIZER_PARAM_STRENGTH:
             *(int16_t *)pValue = VirtualizerGetStrength(pContext);
 
-            LOGV("\tVirtualizer_getParameter() VIRTUALIZER_PARAM_STRENGTH Value is %d",
-                    *(int16_t *)pValue);
+            //LOGV("\tVirtualizer_getParameter() VIRTUALIZER_PARAM_STRENGTH Value is %d",
+            //        *(int16_t *)pValue);
             break;
 
         default:
@@ -1651,11 +1770,10 @@
             break;
     }
 
-    LOGV("\tVirtualizer_getParameter end");
+    //LOGV("\tVirtualizer_getParameter end");
     return status;
 } /* end Virtualizer_getParameter */
 
-
 //----------------------------------------------------------------------------
 // Virtualizer_setParameter()
 //----------------------------------------------------------------------------
@@ -1675,22 +1793,22 @@
     int status = 0;
     int16_t strength;
 
-    LOGV("\tVirtualizer_setParameter start");
+    //LOGV("\tVirtualizer_setParameter start");
 
     switch (*pParam){
         case VIRTUALIZER_PARAM_STRENGTH:
             strength = *(int16_t *)pValue;
-            LOGV("\tVirtualizer_setParameter() VIRTUALIZER_PARAM_STRENGTH value is %d", strength);
-            LOGV("\tVirtualizer_setParameter() Calling pVirtualizer->setStrength");
+            //LOGV("\tVirtualizer_setParameter() VIRTUALIZER_PARAM_STRENGTH value is %d", strength);
+            //LOGV("\tVirtualizer_setParameter() Calling pVirtualizer->setStrength");
             VirtualizerSetStrength(pContext, (int32_t)strength);
-            LOGV("\tVirtualizer_setParameter() Called pVirtualizer->setStrength");
+            //LOGV("\tVirtualizer_setParameter() Called pVirtualizer->setStrength");
            break;
         default:
             LOGV("\tLVM_ERROR : Virtualizer_setParameter() invalid param %d", *pParam);
             break;
     }
 
-    LOGV("\tVirtualizer_setParameter end");
+    //LOGV("\tVirtualizer_setParameter end");
     return status;
 } /* end Virtualizer_setParameter */
 
@@ -1724,14 +1842,14 @@
     int32_t param2;
     char *name;
 
-    LOGV("\tEqualizer_getParameter start");
+    //LOGV("\tEqualizer_getParameter start");
 
     switch (param) {
     case EQ_PARAM_NUM_BANDS:
     case EQ_PARAM_CUR_PRESET:
     case EQ_PARAM_GET_NUM_OF_PRESETS:
         if (*pValueSize < sizeof(int16_t)) {
-        	LOGV("\tLVM_ERROR : Equalizer_getParameter() invalid pValueSize 1  %d", *pValueSize);
+            LOGV("\tLVM_ERROR : Equalizer_getParameter() invalid pValueSize 1  %d", *pValueSize);
             return -EINVAL;
         }
         *pValueSize = sizeof(int16_t);
@@ -1740,7 +1858,7 @@
     case EQ_PARAM_LEVEL_RANGE:
     case EQ_PARAM_BAND_FREQ_RANGE:
         if (*pValueSize < 2 * sizeof(int32_t)) {
-        	LOGV("\tLVM_ERROR : Equalizer_getParameter() invalid pValueSize 2  %d", *pValueSize);
+            LOGV("\tLVM_ERROR : Equalizer_getParameter() invalid pValueSize 2  %d", *pValueSize);
             return -EINVAL;
         }
         *pValueSize = 2 * sizeof(int32_t);
@@ -1749,7 +1867,7 @@
     case EQ_PARAM_GET_BAND:
     case EQ_PARAM_CENTER_FREQ:
         if (*pValueSize < sizeof(int32_t)) {
-        	LOGV("\tLVM_ERROR : Equalizer_getParameter() invalid pValueSize 1  %d", *pValueSize);
+            LOGV("\tLVM_ERROR : Equalizer_getParameter() invalid pValueSize 1  %d", *pValueSize);
             return -EINVAL;
         }
         *pValueSize = sizeof(int32_t);
@@ -1759,20 +1877,21 @@
         break;
 
     default:
-    	LOGV("\tLVM_ERROR : Equalizer_getParameter unknown param %d", param);
+        LOGV("\tLVM_ERROR : Equalizer_getParameter unknown param %d", param);
         return -EINVAL;
     }
 
     switch (param) {
     case EQ_PARAM_NUM_BANDS:
         *(int16_t *)pValue = FIVEBAND_NUMBANDS;
-        LOGV("\tEqualizer_getParameter() EQ_PARAM_NUM_BANDS %d", *(int16_t *)pValue);
+        //LOGV("\tEqualizer_getParameter() EQ_PARAM_NUM_BANDS %d", *(int16_t *)pValue);
         break;
 
     case EQ_PARAM_LEVEL_RANGE:
         *(int32_t *)pValue = -1500;
         *((int32_t *)pValue + 1) = 1500;
-        LOGV("\tEqualizer_getParameter() EQ_PARAM_LEVEL_RANGE min %d, max %d", *(int32_t *)pValue, *((int32_t *)pValue + 1));
+        //LOGV("\tEqualizer_getParameter() EQ_PARAM_LEVEL_RANGE min %d, max %d",
+        //      *(int32_t *)pValue, *((int32_t *)pValue + 1));
         break;
 
     case EQ_PARAM_BAND_LEVEL:
@@ -1782,7 +1901,8 @@
             break;
         }
         *(int32_t *)pValue = EqualizerGetBandLevel(pContext, param2);
-        LOGV("\tEqualizer_getParameter() EQ_PARAM_BAND_LEVEL band %d, level %d", param2, *(int32_t *)pValue);
+        //LOGV("\tEqualizer_getParameter() EQ_PARAM_BAND_LEVEL band %d, level %d",
+        //      param2, *(int32_t *)pValue);
         break;
 
     case EQ_PARAM_CENTER_FREQ:
@@ -1792,7 +1912,8 @@
             break;
         }
         *(int32_t *)pValue = EqualizerGetCentreFrequency(pContext, param2);
-        LOGV("\tEqualizer_getParameter() EQ_PARAM_CENTER_FREQ band %d, frequency %d", param2, *(int32_t *)pValue);
+        //LOGV("\tEqualizer_getParameter() EQ_PARAM_CENTER_FREQ band %d, frequency %d",
+        //      param2, *(int32_t *)pValue);
         break;
 
     case EQ_PARAM_BAND_FREQ_RANGE:
@@ -1802,23 +1923,25 @@
             break;
         }
         EqualizerGetBandFreqRange(pContext, param2, (uint32_t *)pValue, ((uint32_t *)pValue + 1));
-        LOGV("\tEqualizer_getParameter() EQ_PARAM_BAND_FREQ_RANGE band %d, min %d, max %d", param2, *(int32_t *)pValue, *((int32_t *)pValue + 1));
+        //LOGV("\tEqualizer_getParameter() EQ_PARAM_BAND_FREQ_RANGE band %d, min %d, max %d",
+        //      param2, *(int32_t *)pValue, *((int32_t *)pValue + 1));
         break;
 
     case EQ_PARAM_GET_BAND:
         param2 = *pParam;
         *(int32_t *)pValue = EqualizerGetBand(pContext, param2);
-        LOGV("\tEqualizer_getParameter() EQ_PARAM_GET_BAND frequency %d, band %d", param2, *(int32_t *)pValue);
+        //LOGV("\tEqualizer_getParameter() EQ_PARAM_GET_BAND frequency %d, band %d",
+        //      param2, *(int32_t *)pValue);
         break;
 
     case EQ_PARAM_CUR_PRESET:
         *(int16_t *)pValue = EqualizerGetPreset(pContext);
-        LOGV("\tEqualizer_getParameter() EQ_PARAM_CUR_PRESET %d", *(int32_t *)pValue);
+        //LOGV("\tEqualizer_getParameter() EQ_PARAM_CUR_PRESET %d", *(int32_t *)pValue);
         break;
 
     case EQ_PARAM_GET_NUM_OF_PRESETS:
         *(int16_t *)pValue = EqualizerGetNumPresets();
-        LOGV("\tEqualizer_getParameter() EQ_PARAM_GET_NUM_OF_PRESETS %d", *(int16_t *)pValue);
+        //LOGV("\tEqualizer_getParameter() EQ_PARAM_GET_NUM_OF_PRESETS %d", *(int16_t *)pValue);
         break;
 
     case EQ_PARAM_GET_PRESET_NAME:
@@ -1832,7 +1955,8 @@
         strncpy(name, EqualizerGetPresetName(param2), *pValueSize - 1);
         name[*pValueSize - 1] = 0;
         *pValueSize = strlen(name) + 1;
-        LOGV("\tEqualizer_getParameter() EQ_PARAM_GET_PRESET_NAME preset %d, name %s len %d", param2, gEqualizerPresets[param2].name, *pValueSize);
+        //LOGV("\tEqualizer_getParameter() EQ_PARAM_GET_PRESET_NAME preset %d, name %s len %d",
+        //      param2, gEqualizerPresets[param2].name, *pValueSize);
         break;
 
     default:
@@ -1841,7 +1965,7 @@
         break;
     }
 
-    LOGV("\tEqualizer_getParameter end");
+    //LOGV("\tEqualizer_getParameter end");
     return status;
 } /* end Equalizer_getParameter */
 
@@ -1866,12 +1990,12 @@
     int32_t level;
     int32_t param = *pParam++;
 
-    LOGV("\tEqualizer_setParameter start");
+    //LOGV("\tEqualizer_setParameter start");
     switch (param) {
     case EQ_PARAM_CUR_PRESET:
         preset = *(int16_t *)pValue;
 
-        LOGV("\tEqualizer_setParameter() EQ_PARAM_CUR_PRESET %d", preset);
+        //LOGV("\tEqualizer_setParameter() EQ_PARAM_CUR_PRESET %d", preset);
         if ((preset >= EqualizerGetNumPresets())||(preset < 0)) {
             status = -EINVAL;
             break;
@@ -1881,7 +2005,7 @@
     case EQ_PARAM_BAND_LEVEL:
         band =  *pParam;
         level = *(int32_t *)pValue;
-        LOGV("\tEqualizer_setParameter() EQ_PARAM_BAND_LEVEL band %d, level %d", band, level);
+        //LOGV("\tEqualizer_setParameter() EQ_PARAM_BAND_LEVEL band %d, level %d", band, level);
         if (band >= FIVEBAND_NUMBANDS) {
             status = -EINVAL;
             break;
@@ -1893,7 +2017,7 @@
         break;
     }
 
-    LOGV("\tEqualizer_setParameter end");
+    //LOGV("\tEqualizer_setParameter end");
     return status;
 } /* end Equalizer_setParameter */
 
@@ -1934,7 +2058,7 @@
         case VOLUME_PARAM_LEVEL:
         case VOLUME_PARAM_MAXLEVEL:
         case VOLUME_PARAM_STEREOPOSITION:
-            if (*pValueSize < sizeof(int16_t)){
+            if (*pValueSize != sizeof(int16_t)){
                 LOGV("\tLVM_ERROR : Volume_getParameter() invalid pValueSize 1  %d", *pValueSize);
                 return -EINVAL;
             }
@@ -1951,15 +2075,15 @@
             break;
 
         default:
-        	LOGV("\tLVM_ERROR : EVolume_getParameter unknown param %d", param);
+            LOGV("\tLVM_ERROR : Volume_getParameter unknown param %d", param);
             return -EINVAL;
     }
 
     switch (param){
         case VOLUME_PARAM_LEVEL:
             status = VolumeGetVolumeLevel(pContext, (int16_t *)(pValue));
-			LOGV("\tVolume_getParameter() VOLUME_PARAM_LEVEL Value is %d",
-					*(int16_t *)pValue);
+            LOGV("\tVolume_getParameter() VOLUME_PARAM_LEVEL Value is %d",
+                    *(int16_t *)pValue);
             break;
 
         case VOLUME_PARAM_MAXLEVEL:
@@ -1969,19 +2093,19 @@
             break;
 
         case VOLUME_PARAM_STEREOPOSITION:
-            *(int16_t *)pValue = 0;
+            VolumeGetStereoPosition(pContext, (int16_t *)pValue);
             LOGV("\tVolume_getParameter() VOLUME_PARAM_STEREOPOSITION Value is %d",
                     *(int16_t *)pValue);
             break;
 
         case VOLUME_PARAM_MUTE:
-        	status = VolumeGetMute(pContext, (uint32_t *)pValue);
-			LOGV("\tVolume_getParameter() VOLUME_PARAM_MUTE Value is %d",
-					*(uint32_t *)pValue);
+            status = VolumeGetMute(pContext, (uint32_t *)pValue);
+            LOGV("\tVolume_getParameter() VOLUME_PARAM_MUTE Value is %d",
+                    *(uint32_t *)pValue);
             break;
 
         case VOLUME_PARAM_ENABLESTEREOPOSITION:
-            *(int32_t *)pValue = 0;
+            *(int32_t *)pValue = pContext->pBundledContext->bStereoPositionEnabled;
             LOGV("\tVolume_getParameter() VOLUME_PARAM_ENABLESTEREOPOSITION Value is %d",
                     *(uint32_t *)pValue);
             break;
@@ -1992,7 +2116,7 @@
             break;
     }
 
-    LOGV("\tVolume_getParameter end");
+    //LOGV("\tVolume_getParameter end");
     return status;
 } /* end Volume_getParameter */
 
@@ -2015,7 +2139,9 @@
 int Volume_setParameter (EffectContext *pContext, int32_t *pParam, void *pValue){
     int      status = 0;
     int16_t  level;
+    int16_t  position;
     uint32_t mute;
+    uint32_t positionEnabled;
 
     LOGV("\tVolume_setParameter start");
 
@@ -2029,60 +2155,98 @@
             break;
 
         case VOLUME_PARAM_MUTE:
-        	mute = *(uint32_t *)pValue;
-        	LOGV("\tVolume_setParameter() Calling pVolume->setMute, mute is %d", mute);
-        	LOGV("\tVolume_setParameter() Calling pVolume->setMute");
-        	status = VolumeSetMute(pContext, mute);
-        	LOGV("\tVolume_setParameter() Called pVolume->setMute");
-        	break;
+            mute = *(uint32_t *)pValue;
+            LOGV("\tVolume_setParameter() Calling pVolume->setMute, mute is %d", mute);
+            LOGV("\tVolume_setParameter() Calling pVolume->setMute");
+            status = VolumeSetMute(pContext, mute);
+            LOGV("\tVolume_setParameter() Called pVolume->setMute");
+            break;
 
         case VOLUME_PARAM_ENABLESTEREOPOSITION:
-        	LOGV("\tVolume_setParameter() VOLUME_PARAM_ENABLESTEREOPOSITION called");
-        	break;
+            positionEnabled = *(uint32_t *)pValue;
+            status = VolumeEnableStereoPosition(pContext, positionEnabled);
+            status = VolumeSetStereoPosition(pContext, pContext->pBundledContext->positionSaved);
+            LOGV("\tVolume_setParameter() VOLUME_PARAM_ENABLESTEREOPOSITION called");
+            break;
 
         case VOLUME_PARAM_STEREOPOSITION:
-        	LOGV("\tVolume_setParameter() VOLUME_PARAM_STEREOPOSITION called");
-        	break;
+            position = *(int16_t *)pValue;
+            LOGV("\tVolume_setParameter() VOLUME_PARAM_STEREOPOSITION value is %d", position);
+            LOGV("\tVolume_setParameter() Calling pVolume->VolumeSetStereoPosition");
+            status = VolumeSetStereoPosition(pContext, (int16_t)position);
+            LOGV("\tVolume_setParameter() Called pVolume->VolumeSetStereoPosition");
+            break;
 
         default:
             LOGV("\tLVM_ERROR : Volume_setParameter() invalid param %d", *pParam);
             break;
     }
 
-    LOGV("\tVolume_setParameter end");
+    //LOGV("\tVolume_setParameter end");
     return status;
 } /* end Volume_setParameter */
+
+/****************************************************************************************
+ * Name : LVC_ToDB_s32Tos16()
+ *  Input       : Signed 32-bit integer
+ *  Output      : Signed 16-bit integer
+ *                  MSB (16) = sign bit
+ *                  (15->05) = integer part
+ *                  (04->01) = decimal part
+ *  Returns     : Db value with respect to full scale
+ *  Description :
+ *  Remarks     :
+ ****************************************************************************************/
+
+LVM_INT16 LVC_ToDB_s32Tos16(LVM_INT32 Lin_fix)
+{
+    LVM_INT16   db_fix;
+    LVM_INT16   Shift;
+    LVM_INT16   SmallRemainder;
+    LVM_UINT32  Remainder = (LVM_UINT32)Lin_fix;
+
+    /* Count leading bits, 1 cycle in assembly*/
+    for (Shift = 0; Shift<32; Shift++)
+    {
+        if ((Remainder & 0x80000000U)!=0)
+        {
+            break;
+        }
+        Remainder = Remainder << 1;
+    }
+
+    /*
+     * Based on the approximation equation (for Q11.4 format):
+     *
+     * dB = -96 * Shift + 16 * (8 * Remainder - 2 * Remainder^2)
+     */
+    db_fix    = (LVM_INT16)(-96 * Shift);               /* Six dB steps in Q11.4 format*/
+    SmallRemainder = (LVM_INT16)((Remainder & 0x7fffffff) >> 24);
+    db_fix = (LVM_INT16)(db_fix + SmallRemainder );
+    SmallRemainder = (LVM_INT16)(SmallRemainder * SmallRemainder);
+    db_fix = (LVM_INT16)(db_fix - (LVM_INT16)((LVM_UINT16)SmallRemainder >> 9));
+
+    /* Correct for small offset */
+    db_fix = (LVM_INT16)(db_fix - 5);
+
+    return db_fix;
+}
+
 } // namespace
 } // namespace
 
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
 /* Effect Control Interface Implementation: Process */
 extern "C" int Effect_process(effect_interface_t     self,
-                                 audio_buffer_t         *inBuffer,
-                                 audio_buffer_t         *outBuffer){
+                              audio_buffer_t         *inBuffer,
+                              audio_buffer_t         *outBuffer){
     EffectContext * pContext = (EffectContext *) self;
     int    status = 0;
+    int    lvmStatus = 0;
+    LVM_INT16   *in  = (LVM_INT16 *)inBuffer->raw;
+    LVM_INT16   *out = (LVM_INT16 *)outBuffer->raw;
 
-    //LOGV("\tIn Effect_process");
+    //LOGV("\tEffect_process Start : Enabled = %d     Called = %d",
+    //pContext->pBundledContext->NumberEffectsEnabled,pContext->pBundledContext->NumberEffectsCalled);
 
     if (pContext == NULL){
         LOGV("\tLVM_ERROR : Effect_process() ERROR pContext == NULL");
@@ -2094,85 +2258,122 @@
         LOGV("\tLVM_ERROR : Effect_process() ERROR NULL INPUT POINTER OR FRAME COUNT IS WRONG");
         return -EINVAL;
     }
-
-    if ((pContext->pBundledContext->bBassEnabled == LVM_FALSE)&&(pContext->EffectType == LVM_BASS_BOOST)){
-        LOGV("\tLVM_ERROR : Effect_process() ERROR LVM_BASS_BOOST Effect is not enabled");
-        return -ENODATA;
+    if ((pContext->pBundledContext->bBassEnabled == LVM_FALSE)&&
+        (pContext->EffectType == LVM_BASS_BOOST)){
+        LOGV("\tEffect_process() ERROR LVM_BASS_BOOST Effect is not enabled");
+        status = -ENODATA;
     }
-    if ((pContext->pBundledContext->bVolumeEnabled == LVM_FALSE)&&(pContext->EffectType == LVM_VOLUME)){
-        LOGV("\tLVM_ERROR : Effect_process() ERROR LVM_VOLUME Effect is not enabled");
-        return -ENODATA;
+    if ((pContext->pBundledContext->bVolumeEnabled == LVM_FALSE)&&
+        (pContext->EffectType == LVM_VOLUME)){
+        LOGV("\tEffect_process() ERROR LVM_VOLUME Effect is not enabled");
+        status = -ENODATA;
     }
-    if ((pContext->pBundledContext->bEqualizerEnabled == LVM_FALSE)&&(pContext->EffectType == LVM_EQUALIZER)){
-        LOGV("\tLVM_ERROR : Effect_process() ERROR LVM_EQUALIZER Effect is not enabled");
-        return -ENODATA;
+    if ((pContext->pBundledContext->bEqualizerEnabled == LVM_FALSE)&&
+        (pContext->EffectType == LVM_EQUALIZER)){
+        LOGV("\tEffect_process() ERROR LVM_EQUALIZER Effect is not enabled");
+        status = -ENODATA;
     }
-    if ((pContext->pBundledContext->bVirtualizerEnabled == LVM_FALSE)&&(pContext->EffectType == LVM_VIRTUALIZER)){
-        LOGV("\tLVM_ERROR : Effect_process() ERROR LVM_VIRTUALIZER Effect is not enabled");
-        return -ENODATA;
+    if ((pContext->pBundledContext->bVirtualizerEnabled == LVM_FALSE)&&
+        (pContext->EffectType == LVM_VIRTUALIZER)){
+        LOGV("\tEffect_process() ERROR LVM_VIRTUALIZER Effect is not enabled");
+        status = -ENODATA;
     }
 
-    pContext->pBundledContext->NumberEffectsCalled++;
+    // If this is the last frame of an effect process its output with no effect
+    if(status == -ENODATA){
+        if (pContext->config.outputCfg.accessMode == EFFECT_BUFFER_ACCESS_ACCUMULATE){
+            //LOGV("\tLVM_ERROR : Effect_process() accumulating last frame into output buffer");
+            //LOGV("\tLVM_ERROR : Effect_process() trying copying last frame into output buffer");
+            //LOGV("\tLVM_ERROR : Enabled = %d     Called = %d",
+            //pContext->pBundledContext->NumberEffectsEnabled,
+            //pContext->pBundledContext->NumberEffectsCalled);
 
-    if(pContext->pBundledContext->NumberEffectsCalled == pContext->pBundledContext->NumberEffectsEnabled){
-        LOGV("\tEffect_process() Calling process with %d frames, %d effects enabled,    %d called: Effect %d", outBuffer->frameCount, pContext->pBundledContext->NumberEffectsEnabled, pContext->pBundledContext->NumberEffectsCalled, pContext->EffectType);
+        }else{
+            //LOGV("\tLVM_ERROR : Effect_process() copying last frame into output buffer");
+        }
+    }
+
+    if(status != -ENODATA){
+        pContext->pBundledContext->NumberEffectsCalled++;
+    }
+
+    if(pContext->pBundledContext->NumberEffectsCalled ==
+       pContext->pBundledContext->NumberEffectsEnabled){
+        //LOGV("\tEffect_process Calling process with %d effects enabled, %d called: Effect %d",
+        //pContext->pBundledContext->NumberEffectsEnabled,
+        //pContext->pBundledContext->NumberEffectsCalled, pContext->EffectType);
+
+        if(status == -ENODATA){
+            //LOGV("\tLVM_ERROR : Effect_process() actually processing last frame");
+        }
         pContext->pBundledContext->NumberEffectsCalled = 0;
-        /* Process all the available frames, block processing is handled internalLY by the LVM bundle */
-        status = android::LvmBundle_process(    (LVM_INT16 *)inBuffer->raw,
+        /* Process all the available frames, block processing is
+           handled internalLY by the LVM bundle */
+        lvmStatus = android::LvmBundle_process(    (LVM_INT16 *)inBuffer->raw,
                                                 (LVM_INT16 *)outBuffer->raw,
                                                 outBuffer->frameCount,
                                                 pContext);
-        //LOGV("\tEffect_process() Called  process with %d frames, %d effects enabled,    %d called: Effect %d", outBuffer->frameCount, pContext->pBundledContext->NumberEffectsEnabled, pContext->pBundledContext->NumberEffectsCalled, pContext->EffectType);                                                
+        if(lvmStatus != LVM_SUCCESS){
+            LOGV("\tLVM_ERROR : LvmBundle_process returned error %d", lvmStatus);
+            return lvmStatus;
+        }
     }else{
-        LOGV("\tEffect_process() Not Calling process with %d frames, %d effects enabled, %d called: Effect %d", outBuffer->frameCount, pContext->pBundledContext->NumberEffectsEnabled, pContext->pBundledContext->NumberEffectsCalled, pContext->EffectType);
-        memcpy(outBuffer->raw, inBuffer->raw, outBuffer->frameCount*sizeof(LVM_INT16)*2); // 2 is for stereo input
+        //LOGV("\tEffect_process Not Calling process with %d effects enabled, %d called: Effect %d",
+        //pContext->pBundledContext->NumberEffectsEnabled,
+        //pContext->pBundledContext->NumberEffectsCalled, pContext->EffectType);
+        // 2 is for stereo input
+        memcpy(outBuffer->raw, inBuffer->raw, outBuffer->frameCount*sizeof(LVM_INT16)*2);
     }
+
     return status;
 }   /* end Effect_process */
 
 /* Effect Control Interface Implementation: Command */
 extern "C" int Effect_command(effect_interface_t  self,
-                                 int                 cmdCode,
-                                 int                 cmdSize,
-                                 void                *pCmdData,
-                                 int                 *replySize,
-                                 void                *pReplyData){
+                              int                 cmdCode,
+                              int                 cmdSize,
+                              void                *pCmdData,
+                              int                 *replySize,
+                              void                *pReplyData){
     EffectContext * pContext = (EffectContext *) self;
     int retsize;
     int status = 0;
 
-    LOGV("\t\nEffect_command start");
+    //LOGV("\t\nEffect_command start");
 
     if(pContext->EffectType == LVM_BASS_BOOST){
-        LOGV("\tEffect_command setting command for LVM_BASS_BOOST");
+        //LOGV("\tEffect_command setting command for LVM_BASS_BOOST");
     }
     if(pContext->EffectType == LVM_VIRTUALIZER){
-        LOGV("\tEffect_command setting command for LVM_VIRTUALIZER");
-    } 
+        //LOGV("\tEffect_command setting command for LVM_VIRTUALIZER");
+    }
     if(pContext->EffectType == LVM_EQUALIZER){
-        LOGV("\tEffect_command setting command for LVM_EQUALIZER");
-    } 
+        //LOGV("\tEffect_command setting command for LVM_EQUALIZER");
+    }
     if(pContext->EffectType == LVM_VOLUME){
-        LOGV("\tEffect_command setting command for LVM_VOLUME");
-    }         
+        //LOGV("\tEffect_command setting command for LVM_VOLUME");
+    }
 
     if (pContext == NULL){
         LOGV("\tLVM_ERROR : Effect_command ERROR pContext == NULL");
         return -EINVAL;
     }
 
-    LOGV("\tEffect_command INPUTS are: command %d cmdSize %d",cmdCode, cmdSize);
+    //LOGV("\tEffect_command INPUTS are: command %d cmdSize %d",cmdCode, cmdSize);
 
-    // Incase we disable an effect, next time process is called the number of effect called could be greater
-    pContext->pBundledContext->NumberEffectsCalled = 0;
+    // Incase we disable an effect, next time process is
+    // called the number of effect called could be greater
+    // pContext->pBundledContext->NumberEffectsCalled = 0;
 
-    LOGV("\tEffect_command NumberEffectsCalled = %d, NumberEffectsEnabled = %d", pContext->pBundledContext->NumberEffectsCalled, pContext->pBundledContext->NumberEffectsEnabled);
+    //LOGV("\tEffect_command NumberEffectsCalled = %d, NumberEffectsEnabled = %d",
+    //        pContext->pBundledContext->NumberEffectsCalled,
+    //        pContext->pBundledContext->NumberEffectsEnabled);
 
     switch (cmdCode){
         case EFFECT_CMD_INIT:
-            LOGV("\tEffect_command cmdCode Case: EFFECT_CMD_INIT start");
+            //LOGV("\tEffect_command cmdCode Case: EFFECT_CMD_INIT start");
             if(pContext->EffectType == LVM_BASS_BOOST){
-                LOGV("\tEffect_command cmdCode Case: EFFECT_CMD_INIT for LVM_BASS_BOOST");
+                //LOGV("\tEffect_command cmdCode Case: EFFECT_CMD_INIT for LVM_BASS_BOOST");
 
                 if (pReplyData == NULL || *replySize != sizeof(int)){
                     LOGV("\tLVM_ERROR : BassBoost_command cmdCode Case: "
@@ -2183,7 +2384,7 @@
                 android::BassSetStrength(pContext, 0);
             }
             if(pContext->EffectType == LVM_VIRTUALIZER){
-                LOGV("\tEffect_command cmdCode Case: EFFECT_CMD_INIT for LVM_VIRTUALIZER");
+                //LOGV("\tEffect_command cmdCode Case: EFFECT_CMD_INIT for LVM_VIRTUALIZER");
 
                 if (pReplyData == NULL || *replySize != sizeof(int)){
                     LOGV("\tLVM_ERROR : Virtualizer_command cmdCode Case: "
@@ -2191,10 +2392,10 @@
                     return -EINVAL;
                 }
 
-                android::VirtualizerSetStrength(pContext, 0);  
-            }            
+                android::VirtualizerSetStrength(pContext, 0);
+            }
             if(pContext->EffectType == LVM_EQUALIZER){
-                LOGV("\tEffect_command cmdCode Case: EFFECT_CMD_INIT for LVM_EQUALIZER");
+                //LOGV("\tEffect_command cmdCode Case: EFFECT_CMD_INIT for LVM_EQUALIZER");
 
                 if (pReplyData == NULL || *replySize != sizeof(int)){
                     LOGV("\tLVM_ERROR : Equalizer_command cmdCode Case: "
@@ -2202,11 +2403,11 @@
                     return -EINVAL;
                 }
 
-                android::EqualizerSetPreset(pContext, 0);  
-            }            
+                android::EqualizerSetPreset(pContext, 0);
+            }
             if(pContext->EffectType == LVM_VOLUME){
-                LOGV("\tEffect_command cmdCode Case: "
-                        "EFFECT_CMD_INIT start");
+                //LOGV("\tEffect_command cmdCode Case: "
+                //        "EFFECT_CMD_INIT start");
 
                 if (pReplyData == NULL || *replySize != sizeof(int)){
                     LOGV("\tLVM_ERROR : Volume_command cmdCode Case: "
@@ -2216,13 +2417,13 @@
 
                 status = android::VolumeSetVolumeLevel(pContext, 0);
                 if(status == -EINVAL){
-                	return -EINVAL;
+                    return -EINVAL;
                 }
-            }            
+            }
             break;
-            
+
         case EFFECT_CMD_CONFIGURE:
-            LOGV("\tEffect_command cmdCode Case: EFFECT_CMD_CONFIGURE start");
+            //LOGV("\tEffect_command cmdCode Case: EFFECT_CMD_CONFIGURE start");
             if (pCmdData    == NULL||
                 cmdSize     != sizeof(effect_config_t)||
                 pReplyData  == NULL||
@@ -2232,21 +2433,23 @@
                 return -EINVAL;
             }
             *(int *) pReplyData = android::Effect_configure(pContext, (effect_config_t *) pCmdData);
-            LOGV("\tEffect_command cmdCode Case: EFFECT_CMD_CONFIGURE end");
+            //LOGV("\tEffect_command cmdCode Case: EFFECT_CMD_CONFIGURE end");
             break;
 
         case EFFECT_CMD_RESET:
-            LOGV("\tEffect_command cmdCode Case: EFFECT_CMD_RESET start");
+            //LOGV("\tEffect_command cmdCode Case: EFFECT_CMD_RESET start");
             android::Effect_configure(pContext, &pContext->config);
-            LOGV("\tEffect_command cmdCode Case: EFFECT_CMD_RESET end");
+            //LOGV("\tEffect_command cmdCode Case: EFFECT_CMD_RESET end");
             break;
 
         case EFFECT_CMD_GET_PARAM:{
-            LOGV("\tEffect_command cmdCode Case: EFFECT_CMD_GET_PARAM start");
-            
+            //LOGV("\tEffect_command cmdCode Case: EFFECT_CMD_GET_PARAM start");
+
             if(pContext->EffectType == LVM_BASS_BOOST){
-                if (pCmdData == NULL || cmdSize < (int)(sizeof(effect_param_t) + sizeof(int32_t)) ||
-                        pReplyData == NULL ||*replySize < (int) (sizeof(effect_param_t) + sizeof(int32_t))){
+                if (pCmdData == NULL ||
+                        cmdSize < (int)(sizeof(effect_param_t) + sizeof(int32_t)) ||
+                        pReplyData == NULL ||
+                        *replySize < (int) (sizeof(effect_param_t) + sizeof(int32_t))){
                     LOGV("\tLVM_ERROR : BassBoost_command cmdCode Case: "
                             "EFFECT_CMD_GET_PARAM: ERROR");
                     return -EINVAL;
@@ -2266,16 +2469,18 @@
 
                 *replySize = sizeof(effect_param_t) + voffset + p->vsize;
 
-                LOGV("\tBassBoost_command EFFECT_CMD_GET_PARAM "
-                        "*pCmdData %d, *replySize %d, *pReplyData %d ",
-                        *(int32_t *)((char *)pCmdData + sizeof(effect_param_t)),
-                        *replySize,
-                        *(int16_t *)((char *)pReplyData + sizeof(effect_param_t) + voffset));
+                //LOGV("\tBassBoost_command EFFECT_CMD_GET_PARAM "
+                //        "*pCmdData %d, *replySize %d, *pReplyData %d ",
+                //        *(int32_t *)((char *)pCmdData + sizeof(effect_param_t)),
+                //        *replySize,
+                //        *(int16_t *)((char *)pReplyData + sizeof(effect_param_t) + voffset));
             }
-            
+
             if(pContext->EffectType == LVM_VIRTUALIZER){
-                if (pCmdData == NULL || cmdSize < (int)(sizeof(effect_param_t) + sizeof(int32_t)) ||
-                        pReplyData == NULL ||*replySize < (int) (sizeof(effect_param_t) + sizeof(int32_t))){
+                if (pCmdData == NULL ||
+                        cmdSize < (int)(sizeof(effect_param_t) + sizeof(int32_t)) ||
+                        pReplyData == NULL ||
+                        *replySize < (int) (sizeof(effect_param_t) + sizeof(int32_t))){
                     LOGV("\tLVM_ERROR : Virtualizer_command cmdCode Case: "
                             "EFFECT_CMD_GET_PARAM: ERROR");
                     return -EINVAL;
@@ -2295,44 +2500,50 @@
 
                 *replySize = sizeof(effect_param_t) + voffset + p->vsize;
 
-                LOGV("\tVirtualizer_command EFFECT_CMD_GET_PARAM "
-                        "*pCmdData %d, *replySize %d, *pReplyData %d ",
-                        *(int32_t *)((char *)pCmdData + sizeof(effect_param_t)),
-                        *replySize,
-                        *(int16_t *)((char *)pReplyData + sizeof(effect_param_t) + voffset));            
+                //LOGV("\tVirtualizer_command EFFECT_CMD_GET_PARAM "
+                //        "*pCmdData %d, *replySize %d, *pReplyData %d ",
+                //        *(int32_t *)((char *)pCmdData + sizeof(effect_param_t)),
+                //        *replySize,
+                //        *(int16_t *)((char *)pReplyData + sizeof(effect_param_t) + voffset));
             }
             if(pContext->EffectType == LVM_EQUALIZER){
-                LOGV("\tEqualizer_command cmdCode Case: "
-                        "EFFECT_CMD_GET_PARAM start");
-                if (pCmdData == NULL || cmdSize < (int)(sizeof(effect_param_t) + sizeof(int32_t)) ||
-                    pReplyData == NULL || *replySize < (int) (sizeof(effect_param_t) + sizeof(int32_t))) {
+                //LOGV("\tEqualizer_command cmdCode Case: "
+                //        "EFFECT_CMD_GET_PARAM start");
+                if (pCmdData == NULL ||
+                    cmdSize < (int)(sizeof(effect_param_t) + sizeof(int32_t)) ||
+                    pReplyData == NULL ||
+                    *replySize < (int) (sizeof(effect_param_t) + sizeof(int32_t))) {
                     LOGV("\tLVM_ERROR : Equalizer_command cmdCode Case: "
                             "EFFECT_CMD_GET_PARAM");
                     return -EINVAL;
                 }
                 effect_param_t *p = (effect_param_t *)pCmdData;
-                
+
                 memcpy(pReplyData, pCmdData, sizeof(effect_param_t) + p->psize);
-                
+
                 p = (effect_param_t *)pReplyData;
-                
+
                 int voffset = ((p->psize - 1) / sizeof(int32_t) + 1) * sizeof(int32_t);
-                
+
                 p->status = android::Equalizer_getParameter(pContext, (int32_t *)p->data, &p->vsize,
                         p->data + voffset);
-                        
+
                 *replySize = sizeof(effect_param_t) + voffset + p->vsize;
-                
-                LOGV("\tEqualizer_command EFFECT_CMD_GET_PARAM *pCmdData %d, *replySize %d, *pReplyData %08x %08x",
-                        *(int32_t *)((char *)pCmdData + sizeof(effect_param_t)), *replySize,
-                        *(int32_t *)((char *)pReplyData + sizeof(effect_param_t) + voffset),
-                        *(int32_t *)((char *)pReplyData + sizeof(effect_param_t) + voffset + sizeof(int32_t)));            
+
+                //LOGV("\tEqualizer_command EFFECT_CMD_GET_PARAM *pCmdData %d, *replySize %d, "
+                //       "*pReplyData %08x %08x",
+                //        *(int32_t *)((char *)pCmdData + sizeof(effect_param_t)), *replySize,
+                //        *(int32_t *)((char *)pReplyData + sizeof(effect_param_t) + voffset),
+                //        *(int32_t *)((char *)pReplyData + sizeof(effect_param_t) + voffset +
+                //        sizeof(int32_t)));
             }
             if(pContext->EffectType == LVM_VOLUME){
-                LOGV("\tVolume_command cmdCode Case: "
-                        "EFFECT_CMD_GET_PARAM start");
-                if (pCmdData == NULL || cmdSize < (int)(sizeof(effect_param_t) + sizeof(int32_t)) ||
-                        pReplyData == NULL ||*replySize < (int) (sizeof(effect_param_t) + sizeof(int32_t))){
+                //LOGV("\tVolume_command cmdCode Case: "
+                //        "EFFECT_CMD_GET_PARAM start");
+                if (pCmdData == NULL ||
+                        cmdSize < (int)(sizeof(effect_param_t) + sizeof(int32_t)) ||
+                        pReplyData == NULL ||
+                        *replySize < (int) (sizeof(effect_param_t) + sizeof(int32_t))){
                     LOGV("\tLVM_ERROR : Volume_command cmdCode Case: "
                             "EFFECT_CMD_GET_PARAM: ERROR");
                     return -EINVAL;
@@ -2352,26 +2563,26 @@
 
                 *replySize = sizeof(effect_param_t) + voffset + p->vsize;
 
-                LOGV("\tVolume_command EFFECT_CMD_GET_PARAM "
-                        "*pCmdData %d, *replySize %d, *pReplyData %d ",
-                        *(int32_t *)((char *)pCmdData + sizeof(effect_param_t)),
-                        *replySize,
-                        *(int16_t *)((char *)pReplyData + sizeof(effect_param_t) + voffset));          
-            }            
-            LOGV("\tEffect_command cmdCode Case: EFFECT_CMD_GET_PARAM end");
+                //LOGV("\tVolume_command EFFECT_CMD_GET_PARAM "
+                //        "*pCmdData %d, *replySize %d, *pReplyData %d ",
+                //        *(int32_t *)((char *)pCmdData + sizeof(effect_param_t)),
+                //        *replySize,
+                //        *(int16_t *)((char *)pReplyData + sizeof(effect_param_t) + voffset));
+            }
+            //LOGV("\tEffect_command cmdCode Case: EFFECT_CMD_GET_PARAM end");
         } break;
         case EFFECT_CMD_SET_PARAM:{
-            LOGV("\tEffect_command cmdCode Case: EFFECT_CMD_SET_PARAM start");
+            //LOGV("\tEffect_command cmdCode Case: EFFECT_CMD_SET_PARAM start");
             if(pContext->EffectType == LVM_BASS_BOOST){
-                LOGV("\tBassBoost_command EFFECT_CMD_SET_PARAM param %d, *replySize %d, value %d ",
-                        *(int32_t *)((char *)pCmdData + sizeof(effect_param_t)),
-                        *replySize,
-                        *(int16_t *)((char *)pCmdData + sizeof(effect_param_t) + sizeof(int32_t)));
+                //LOGV("\tBassBoost_command EFFECT_CMD_SET_PARAM param %d, *replySize %d, value %d ",
+                //        *(int32_t *)((char *)pCmdData + sizeof(effect_param_t)),
+                //        *replySize,
+                //        *(int16_t *)((char *)pCmdData + sizeof(effect_param_t) + sizeof(int32_t)));
 
-                if (    pCmdData   == NULL||
-                        cmdSize    != (int)(sizeof(effect_param_t) + sizeof(int32_t) + sizeof(int16_t))||
-                        pReplyData == NULL||
-                        *replySize != sizeof(int32_t)){
+                if (pCmdData   == NULL||
+                    cmdSize    != (int)(sizeof(effect_param_t) + sizeof(int32_t) +sizeof(int16_t))||
+                    pReplyData == NULL||
+                    *replySize != sizeof(int32_t)){
                     LOGV("\tLVM_ERROR : BassBoost_command cmdCode Case: "
                             "EFFECT_CMD_SET_PARAM: ERROR");
                     return -EINVAL;
@@ -2384,27 +2595,27 @@
                     return -EINVAL;
                 }
 
-                LOGV("\tnBassBoost_command cmdSize is %d\n"
-                		"\tsizeof(effect_param_t) is  %d\n"
-                		"\tp->psize is %d\n"
-                		"\tp->vsize is %d"
-                		"\n",
-                		cmdSize, sizeof(effect_param_t), p->psize, p->vsize );
+                //LOGV("\tnBassBoost_command cmdSize is %d\n"
+                //        "\tsizeof(effect_param_t) is  %d\n"
+                //        "\tp->psize is %d\n"
+                //        "\tp->vsize is %d"
+                //        "\n",
+                //        cmdSize, sizeof(effect_param_t), p->psize, p->vsize );
 
                 *(int *)pReplyData = android::BassBoost_setParameter(pContext,
                                                                     (int32_t *)p->data,
                                                                     p->data + p->psize);
             }
             if(pContext->EffectType == LVM_VIRTUALIZER){
-                LOGV("\tVirtualizer_command EFFECT_CMD_SET_PARAM param %d, *replySize %d, value %d ",
-                        *(int32_t *)((char *)pCmdData + sizeof(effect_param_t)),
-                        *replySize,
-                        *(int16_t *)((char *)pCmdData + sizeof(effect_param_t) + sizeof(int32_t)));
+                //LOGV("\tVirtualizer_command EFFECT_CMD_SET_PARAM param %d, *replySize %d, value %d",
+                //        *(int32_t *)((char *)pCmdData + sizeof(effect_param_t)),
+                //        *replySize,
+                //        *(int16_t *)((char *)pCmdData + sizeof(effect_param_t) + sizeof(int32_t)));
 
-                if (    pCmdData   == NULL||
-                        cmdSize    != (int)(sizeof(effect_param_t) + sizeof(int32_t) + sizeof(int16_t))||
-                        pReplyData == NULL||
-                        *replySize != sizeof(int32_t)){
+                if (pCmdData   == NULL||
+                    cmdSize    != (int)(sizeof(effect_param_t) + sizeof(int32_t) +sizeof(int16_t))||
+                    pReplyData == NULL||
+                    *replySize != sizeof(int32_t)){
                     LOGV("\tLVM_ERROR : Virtualizer_command cmdCode Case: "
                             "EFFECT_CMD_SET_PARAM: ERROR");
                     return -EINVAL;
@@ -2417,24 +2628,24 @@
                     return -EINVAL;
                 }
 
-                LOGV("\tnVirtualizer_command cmdSize is %d\n"
-                        "\tsizeof(effect_param_t) is  %d\n"
-                        "\tp->psize is %d\n"
-                        "\tp->vsize is %d"
-                        "\n",
-                        cmdSize, sizeof(effect_param_t), p->psize, p->vsize );
+                //LOGV("\tnVirtualizer_command cmdSize is %d\n"
+                //        "\tsizeof(effect_param_t) is  %d\n"
+                //        "\tp->psize is %d\n"
+                //        "\tp->vsize is %d"
+                //        "\n",
+                //        cmdSize, sizeof(effect_param_t), p->psize, p->vsize );
 
                 *(int *)pReplyData = android::Virtualizer_setParameter(pContext,
                                                                       (int32_t *)p->data,
-                                                                       p->data + p->psize);            
+                                                                       p->data + p->psize);
             }
             if(pContext->EffectType == LVM_EQUALIZER){
-                LOGV("\tEqualizer_command cmdCode Case: "
-                        "EFFECT_CMD_SET_PARAM start");
-                LOGV("\tEqualizer_command EFFECT_CMD_SET_PARAM param %d, *replySize %d, value %d ",
-                        *(int32_t *)((char *)pCmdData + sizeof(effect_param_t)),
-                        *replySize,
-                        *(int16_t *)((char *)pCmdData + sizeof(effect_param_t) + sizeof(int32_t)));
+                //LOGV("\tEqualizer_command cmdCode Case: "
+                //        "EFFECT_CMD_SET_PARAM start");
+                //LOGV("\tEqualizer_command EFFECT_CMD_SET_PARAM param %d, *replySize %d, value %d ",
+                //        *(int32_t *)((char *)pCmdData + sizeof(effect_param_t)),
+                //        *replySize,
+                //        *(int16_t *)((char *)pCmdData + sizeof(effect_param_t) + sizeof(int32_t)));
 
                 if (pCmdData == NULL || cmdSize < (int)(sizeof(effect_param_t) + sizeof(int32_t)) ||
                     pReplyData == NULL || *replySize != sizeof(int32_t)) {
@@ -2446,15 +2657,15 @@
 
                 *(int *)pReplyData = android::Equalizer_setParameter(pContext,
                                                                     (int32_t *)p->data,
-                                                                     p->data + p->psize);            
+                                                                     p->data + p->psize);
             }
             if(pContext->EffectType == LVM_VOLUME){
-                LOGV("\tVolume_command cmdCode Case: "
-                        "EFFECT_CMD_SET_PARAM start");
-                LOGV("\tVolume_command EFFECT_CMD_SET_PARAM param %d, *replySize %d, value %d ",
-                        *(int32_t *)((char *)pCmdData + sizeof(effect_param_t)),
-                        *replySize,
-                        *(int16_t *)((char *)pCmdData + sizeof(effect_param_t) + sizeof(int32_t)));
+                //LOGV("\tVolume_command cmdCode Case: "
+                //        "EFFECT_CMD_SET_PARAM start");
+                //LOGV("\tVolume_command EFFECT_CMD_SET_PARAM param %d, *replySize %d, value %d ",
+                //        *(int32_t *)((char *)pCmdData + sizeof(effect_param_t)),
+                //        *replySize,
+                //        *(int16_t *)((char *)pCmdData + sizeof(effect_param_t) + sizeof(int32_t)));
 
                 if (    pCmdData   == NULL||
                         cmdSize    < (int)(sizeof(effect_param_t) + sizeof(int32_t))||
@@ -2468,17 +2679,17 @@
 
                 *(int *)pReplyData = android::Volume_setParameter(pContext,
                                                                  (int32_t *)p->data,
-                                                                 p->data + p->psize);            
-            }            
-            LOGV("\tEffect_command cmdCode Case: EFFECT_CMD_SET_PARAM end");
+                                                                 p->data + p->psize);
+            }
+            //LOGV("\tEffect_command cmdCode Case: EFFECT_CMD_SET_PARAM end");
         } break;
 
         case EFFECT_CMD_ENABLE:
-            LOGV("\tEffect_command cmdCode Case: EFFECT_CMD_ENABLE start");
+            //LOGV("\tEffect_command cmdCode Case: EFFECT_CMD_ENABLE start");
             if (pReplyData == NULL || *replySize != sizeof(int)){
                 LOGV("\tLVM_ERROR : Effect_command cmdCode Case: EFFECT_CMD_ENABLE: ERROR");
                 return -EINVAL;
-            }           
+            }
             switch (pContext->EffectType){
                 case LVM_BASS_BOOST:
                     if(pContext->pBundledContext->bBassEnabled == LVM_TRUE){
@@ -2487,7 +2698,7 @@
                          return -EINVAL;
                     }
                     pContext->pBundledContext->bBassEnabled = LVM_TRUE;
-                    LOGV("\tEffect_command cmdCode Case: EFFECT_CMD_ENABLE LVM_BASS_BOOST enabled");
+                    //LOGV("\tEffect_command cmdCode Case: EFFECT_CMD_ENABLE LVM_BASS_BOOST enabled");
                     break;
                 case LVM_EQUALIZER:
                     if(pContext->pBundledContext->bEqualizerEnabled == LVM_TRUE){
@@ -2496,8 +2707,8 @@
                          return -EINVAL;
                     }
                     pContext->pBundledContext->bEqualizerEnabled = LVM_TRUE;
-                    LOGV("\tEffect_command cmdCode Case: EFFECT_CMD_ENABLE LVM_EQUALIZER enabled");                    
-                    break;                   
+                    //LOGV("\tEffect_command cmdCode Case: EFFECT_CMD_ENABLE LVM_EQUALIZER enabled");
+                    break;
                 case LVM_VIRTUALIZER:
                     if(pContext->pBundledContext->bVirtualizerEnabled == LVM_TRUE){
                          LOGV("\tLVM_ERROR : Virtualizer_command cmdCode Case: "
@@ -2505,8 +2716,8 @@
                          return -EINVAL;
                     }
                     pContext->pBundledContext->bVirtualizerEnabled = LVM_TRUE;
-                    LOGV("\tEffect_command cmdCode Case: EFFECT_CMD_ENABLE LVM_VIRTUALIZER enabled");                    
-                    break;                
+                    //LOGV("\tEffect_command cmdCode Case:EFFECT_CMD_ENABLE LVM_VIRTUALIZER enabled");
+                    break;
                 case LVM_VOLUME:
                     if(pContext->pBundledContext->bVolumeEnabled == LVM_TRUE){
                          LOGV("\tLVM_ERROR : Volume_command cmdCode Case: "
@@ -2514,26 +2725,27 @@
                          return -EINVAL;
                     }
                     pContext->pBundledContext->bVolumeEnabled = LVM_TRUE;
-                    LOGV("\tEffect_command cmdCode Case: EFFECT_CMD_ENABLE LVM_VOLUME enabled");                    
+                    //LOGV("\tEffect_command cmdCode Case: EFFECT_CMD_ENABLE LVM_VOLUME enabled");
                     break;
                 default:
                     LOGV("\tLVM_ERROR : Effect_command cmdCode Case: "
                         "EFFECT_CMD_ENABLE: ERROR, invalid Effect Type");
-                    return -EINVAL;                    
+                    return -EINVAL;
             }
             *(int *)pReplyData = 0;
             pContext->pBundledContext->NumberEffectsEnabled++;
-            android::LvmEffect_enable(pContext);  
-            LOGV("\tEffect_command cmdCode Case: EFFECT_CMD_ENABLE NumberEffectsEnabled = %d", pContext->pBundledContext->NumberEffectsEnabled);          
-            LOGV("\tEffect_command cmdCode Case: EFFECT_CMD_ENABLE end");          
+            android::LvmEffect_enable(pContext);
+            //LOGV("\tEffect_command cmdCode Case: EFFECT_CMD_ENABLE NumberEffectsEnabled = %d",
+            //        pContext->pBundledContext->NumberEffectsEnabled);
+            //LOGV("\tEffect_command cmdCode Case: EFFECT_CMD_ENABLE end");
             break;
-        
+
         case EFFECT_CMD_DISABLE:
-            LOGV("\tEffect_command cmdCode Case: EFFECT_CMD_DISABLE start");
+            //LOGV("\tEffect_command cmdCode Case: EFFECT_CMD_DISABLE start");
             if (pReplyData == NULL || *replySize != sizeof(int)){
                 LOGV("\tLVM_ERROR : Effect_command cmdCode Case: EFFECT_CMD_DISABLE: ERROR");
                 return -EINVAL;
-            }        
+            }
             switch (pContext->EffectType){
                 case LVM_BASS_BOOST:
                     if(pContext->pBundledContext->bBassEnabled == LVM_FALSE){
@@ -2541,8 +2753,9 @@
                                  "EFFECT_CMD_DISABLE: ERROR-Effect is not yet enabled");
                          return -EINVAL;
                     }
-                    pContext->pBundledContext->bBassEnabled = LVM_FALSE;
-                    LOGV("\tEffect_command cmdCode Case: EFFECT_CMD_DISABLE LVM_BASS_BOOST disabled");                    
+                    pContext->pBundledContext->bBassEnabled      = LVM_FALSE;
+                    //LOGV("\tEffect_command cmdCode Case: "
+                    //       "EFFECT_CMD_DISABLE LVM_BASS_BOOST disabled");
                     break;
                 case LVM_EQUALIZER:
                     if(pContext->pBundledContext->bEqualizerEnabled == LVM_FALSE){
@@ -2551,8 +2764,9 @@
                          return -EINVAL;
                     }
                     pContext->pBundledContext->bEqualizerEnabled = LVM_FALSE;
-                    LOGV("\tEffect_command cmdCode Case: EFFECT_CMD_DISABLE LVM_EQUALIZER disabled");                                        
-                    break;                 
+                    //LOGV("\tEffect_command cmdCode Case: "
+                    //       "EFFECT_CMD_DISABLE LVM_EQUALIZER disabled");
+                    break;
                 case LVM_VIRTUALIZER:
                     if(pContext->pBundledContext->bVirtualizerEnabled == LVM_FALSE){
                          LOGV("\tLVM_ERROR : Virtualizer_command cmdCode Case: "
@@ -2560,8 +2774,9 @@
                          return -EINVAL;
                     }
                     pContext->pBundledContext->bVirtualizerEnabled = LVM_FALSE;
-                    LOGV("\tEffect_command cmdCode Case: EFFECT_CMD_DISABLE LVM_VIRTUALIZER disabled");                                        
-                    break;                
+                    //LOGV("\tEffect_command cmdCode Case: "
+                    //     "EFFECT_CMD_DISABLE LVM_VIRTUALIZER disabled");
+                    break;
                 case LVM_VOLUME:
                     if(pContext->pBundledContext->bVolumeEnabled == LVM_FALSE){
                          LOGV("\tLVM_ERROR : Volume_command cmdCode Case: "
@@ -2569,34 +2784,128 @@
                          return -EINVAL;
                     }
                     pContext->pBundledContext->bVolumeEnabled = LVM_FALSE;
-                    LOGV("\tEffect_command cmdCode Case: EFFECT_CMD_DISABLE LVM_VOLUME disabled");                                        
-                    break;                 
+                    //LOGV("\tEffect_command cmdCode Case: EFFECT_CMD_DISABLE LVM_VOLUME disabled");
                     break;
                 default:
                     LOGV("\tLVM_ERROR : Effect_command cmdCode Case: "
                         "EFFECT_CMD_DISABLE: ERROR, invalid Effect Type");
-                    return -EINVAL;                    
-            }      
+                    return -EINVAL;
+            }
             *(int *)pReplyData = 0;
             pContext->pBundledContext->NumberEffectsEnabled--;
-            android::LvmEffect_disable(pContext);   
-            LOGV("\tEffect_command cmdCode Case: EFFECT_CMD_DISABLE NumberEffectsEnabled = %d", pContext->pBundledContext->NumberEffectsEnabled); 
-            LOGV("\tEffect_command cmdCode Case: EFFECT_CMD_DISABLE end");        
+            android::LvmEffect_disable(pContext);
+            //LOGV("\tEffect_command cmdCode Case: EFFECT_CMD_DISABLE NumberEffectsEnabled = %d",
+            //        pContext->pBundledContext->NumberEffectsEnabled);
+            //LOGV("\tEffect_command cmdCode Case: EFFECT_CMD_DISABLE end");
             break;
 
         case EFFECT_CMD_SET_DEVICE:
-        case EFFECT_CMD_SET_VOLUME:
-//        case EFFECT_CMD_SET_AUDIO_MODE:// AGO add this
-            LOGV("\tEffect_command cmdCode Case: "
-                    "EFFECT_CMD_SET_DEVICE/EFFECT_CMD_SET_VOLUME/EFFECT_CMD_SET_AUDIO_MODE start");
-            break;
+        {
+            LOGV("\tEffect_command cmdCode Case: EFFECT_CMD_SET_DEVICE start");
+            audio_device_e device = *(audio_device_e *)pCmdData;
 
+            if(pContext->EffectType == LVM_BASS_BOOST){
+                if((device == DEVICE_SPEAKER)||(device == DEVICE_BLUETOOTH_SCO_CARKIT)||
+                   (device == DEVICE_BLUETOOTH_A2DP_SPEAKER)){
+                    LOGV("\tEFFECT_CMD_SET_DEVICE device is invalid for LVM_BASS_BOOST %d",
+                          *(int32_t *)pCmdData);
+                    LOGV("\tEFFECT_CMD_SET_DEVICE temporary disable LVM_BAS_BOOST");
+
+                    // If a device doesnt support bassboost the effect must be temporarily disabled
+                    // the effect must still report its original state as this can only be changed
+                    // by the ENABLE/DISABLE command
+
+                    if(pContext->pBundledContext->bBassEnabled == LVM_TRUE){
+                        LOGV("\tEFFECT_CMD_SET_DEVICE disable LVM_BASS_BOOST %d",
+                             *(int32_t *)pCmdData);
+                        android::LvmEffect_disable(pContext);
+                        pContext->pBundledContext->bBassTempDisabled = LVM_TRUE;
+                    }
+                }else{
+                    LOGV("\tEFFECT_CMD_SET_DEVICE device is valid for LVM_BASS_BOOST %d",
+                         *(int32_t *)pCmdData);
+
+                    // If a device supports bassboost and the effect has been temporarily disabled
+                    // previously then re-enable it
+
+                    if(pContext->pBundledContext->bBassTempDisabled == LVM_TRUE){
+                        LOGV("\tEFFECT_CMD_SET_DEVICE re-enable LVM_BASS_BOOST %d",
+                             *(int32_t *)pCmdData);
+                        android::LvmEffect_enable(pContext);
+                        pContext->pBundledContext->bBassTempDisabled = LVM_FALSE;
+                    }
+                }
+            }
+            if(pContext->EffectType == LVM_VIRTUALIZER){
+                if((device == DEVICE_SPEAKER)||(device == DEVICE_BLUETOOTH_SCO_CARKIT)||
+                   (device == DEVICE_BLUETOOTH_A2DP_SPEAKER)){
+                    LOGV("\tEFFECT_CMD_SET_DEVICE device is invalid for LVM_VIRTUALIZER %d",
+                          *(int32_t *)pCmdData);
+                    LOGV("\tEFFECT_CMD_SET_DEVICE temporary disable LVM_VIRTUALIZER");
+
+                    //If a device doesnt support virtualizer the effect must be temporarily disabled
+                    // the effect must still report its original state as this can only be changed
+                    // by the ENABLE/DISABLE command
+
+                    if(pContext->pBundledContext->bVirtualizerEnabled == LVM_TRUE){
+                        LOGV("\tEFFECT_CMD_SET_DEVICE disable LVM_VIRTUALIZER %d",
+                              *(int32_t *)pCmdData);
+                        android::LvmEffect_disable(pContext);
+                        pContext->pBundledContext->bVirtualizerTempDisabled = LVM_TRUE;
+                    }
+                }else{
+                    LOGV("\tEFFECT_CMD_SET_DEVICE device is valid for LVM_VIRTUALIZER %d",
+                          *(int32_t *)pCmdData);
+
+                    // If a device supports virtualizer and the effect has been temporarily disabled
+                    // previously then re-enable it
+
+                    if(pContext->pBundledContext->bVirtualizerTempDisabled == LVM_TRUE){
+                        LOGV("\tEFFECT_CMD_SET_DEVICE re-enable LVM_VIRTUALIZER %d",
+                              *(int32_t *)pCmdData);
+                        android::LvmEffect_enable(pContext);
+                        pContext->pBundledContext->bVirtualizerTempDisabled = LVM_FALSE;
+                    }
+                }
+            }
+            LOGV("\tEffect_command cmdCode Case: EFFECT_CMD_SET_DEVICE end");
+            break;
+        }
+        case EFFECT_CMD_SET_VOLUME:
+        {
+            int32_t channels = cmdSize/sizeof(int32_t);
+            int32_t vol     = *(int32_t *)pCmdData;
+            int16_t vol_db;
+            int16_t dB;
+            int16_t vol_db_rnd;
+            int32_t vol_ret[2] = {1<<24,1<<24}; // Apply no volume
+
+            // if pReplyData is NULL, VOL_CTRL is delegated to another effect
+            if(pReplyData == LVM_NULL){
+                break;
+            }
+
+            if(vol==0x1000000){
+                vol -= 1;
+            }
+            // Convert volume linear (Q8.24) to volume dB (0->-96)
+            dB = android::LVC_ToDB_s32Tos16(vol <<7);
+            dB = (dB +8)>>4;
+            dB = (dB <-96) ? -96 : dB ;
+
+            //LOGV("\tSession: %d, VOLUME is %d dB (%d), effect is %d",
+            //pContext->pBundledContext->SessionNo, (int32_t)dB, vol<<7, pContext->EffectType);
+            memcpy(pReplyData, vol_ret, sizeof(int32_t)*2);
+            android::VolumeSetVolumeLevel(pContext, (int16_t)(dB*100));
+            break;
+         }
+        case EFFECT_CMD_SET_AUDIO_MODE:
+            break;
         default:
-            LOGV("\tLVM_ERROR : Effect_command cmdCode Case: DEFAULT start %d ERROR",cmdCode);
             return -EINVAL;
     }
 
-    LOGV("\tEffect_command end...\n\n");
+    //LOGV("\tEffect_command end...\n\n");
     return 0;
 }    /* end Effect_command */
 
@@ -2606,4 +2915,3 @@
     Effect_command
 };    /* end gLvmEffectInterface */
 
-
diff --git a/media/libeffects/lvm/wrapper/Bundle/EffectBundle.h b/media/libeffects/lvm/wrapper/Bundle/EffectBundle.h
index 6818dd6..029f843 100644
--- a/media/libeffects/lvm/wrapper/Bundle/EffectBundle.h
+++ b/media/libeffects/lvm/wrapper/Bundle/EffectBundle.h
@@ -27,25 +27,30 @@
 #define FIVEBAND_NUMBANDS       5
 #define MAX_NUM_BANDS           5
 #define MAX_CALL_SIZE           256
+//#define LVM_PCM
 
 //TODO: this should be included from each effect API include
-static const effect_uuid_t SL_IID_BASSBOOST_ = { 0x0634f220, 0xddd4, 0x11db, 0xa0fc, { 0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b } };
+static const effect_uuid_t SL_IID_BASSBOOST_ = { 0x0634f220, 0xddd4, 0x11db, 0xa0fc,
+                                               { 0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b } };
 const effect_uuid_t * const SL_IID_BASSBOOST = &SL_IID_BASSBOOST_;
 
-static const effect_uuid_t SL_IID_EQUALIZER_ = { 0x0bed4300, 0xddd6, 0x11db, 0x8f34, { 0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b } };
+static const effect_uuid_t SL_IID_EQUALIZER_ = { 0x0bed4300, 0xddd6, 0x11db, 0x8f34,
+                                               { 0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b } };
 const effect_uuid_t * const SL_IID_EQUALIZER = &SL_IID_EQUALIZER_;
 
-static const effect_uuid_t SL_IID_VIRTUALIZER_ = { 0x37cc2c00, 0xdddd, 0x11db, 0x8577, { 0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b } }; // updated mon 28th june 2010
+static const effect_uuid_t SL_IID_VIRTUALIZER_ = { 0x37cc2c00, 0xdddd, 0x11db, 0x8577,
+                                                 { 0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b } };
 const effect_uuid_t * const SL_IID_VIRTUALIZER = &SL_IID_VIRTUALIZER_;
 
-static const effect_uuid_t SL_IID_VOLUME_ = { 0x09e8ede0, 0xddde, 0x11db, 0xb4f6, { 0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b } }; // updated mon 28th june 2010
+static const effect_uuid_t SL_IID_VOLUME_ = { 0x09e8ede0, 0xddde, 0x11db, 0xb4f6,
+                                            { 0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b } };
 const effect_uuid_t * const SL_IID_VOLUME = &SL_IID_VOLUME_;
 
 typedef enum
 {
     LVM_BASS_BOOST,
     LVM_VIRTUALIZER,
-    LVM_EQUALIZER,    
+    LVM_EQUALIZER,
     LVM_VOLUME
 } lvm_effect_en;
 
@@ -60,41 +65,51 @@
 
 /* BundledEffectContext : One per session */
 struct BundledEffectContext{
-    LVM_Handle_t                    hInstance;                      /* Instance handle */
-    int                             SessionNo;                      /* Current session number */
-    bool                            bVolumeEnabled;                 /* Flag for Volume */
-    bool                            bEqualizerEnabled;              /* Flag for EQ */
-    bool                            bBassEnabled;                   /* Flag for Bass */
-    bool                            bVirtualizerEnabled;            /* Flag for Virtualizer */
-    int                             NumberEffectsEnabled;           /* Effects in this session */
-    int                             NumberEffectsCalled;            /* Effects called so far */    
+    LVM_Handle_t                    hInstance;                /* Instance handle */
+    int                             SessionNo;                /* Current session number */
+    bool                            bVolumeEnabled;           /* Flag for Volume */
+    bool                            bEqualizerEnabled;        /* Flag for EQ */
+    bool                            bBassEnabled;             /* Flag for Bass */
+    bool                            bBassTempDisabled;        /* Flag for Bass to be re-enabled */
+    bool                            bVirtualizerEnabled;      /* Flag for Virtualizer */
+    bool                            bVirtualizerTempDisabled; /* Flag for effect to be re-enabled */
+    int                             NumberEffectsEnabled;     /* Effects in this session */
+    int                             NumberEffectsCalled;      /* Effects called so far */
     // Saved parameters for each effect */
     // Bass Boost
-    int                             BassStrengthSaved;             /* Conversion between Get/Set */ 
+    int                             BassStrengthSaved;        /* Conversion between Get/Set */
     // Equalizer
-    int                             CurPreset;                      /* Current preset being used */
+    int                             CurPreset;                /* Current preset being used */
     // Virtualzer
-    int                             VirtStrengthSaved;              /* Conversion between Get/Set */
+    int                             VirtStrengthSaved;        /* Conversion between Get/Set */
     // Volume
     int                             levelSaved;     /* for when mute is set, level must be saved */
-    bool                            bMuteEnabled;   /* Must store as mute = -96dB level */       
+    int                             positionSaved;
+    bool                            bMuteEnabled;   /* Must store as mute = -96dB level */
+    bool                            bStereoPositionEnabled;
+    int                             frameCount;
+    LVM_Fs_en                       SampleRate;
+    #ifdef LVM_PCM
+    FILE                            *PcmInPtr;
+    FILE                            *PcmOutPtr;
+    #endif
 };
 
 /* SessionContext : One session */
 struct SessionContext{
     bool                            bBundledEffectsEnabled;
-    bool                            bVolumeInstantiated; 
+    bool                            bVolumeInstantiated;
     bool                            bEqualizerInstantiated;
     bool                            bBassInstantiated;
-    bool                            bVirtualizerInstantiated; 
-    BundledEffectContext            *pBundledContext;             
+    bool                            bVirtualizerInstantiated;
+    BundledEffectContext            *pBundledContext;
 };
 
 struct EffectContext{
     const struct effect_interface_s *itfe;
     effect_config_t                 config;
     lvm_effect_en                   EffectType;
-    BundledEffectContext            *pBundledContext; 
+    BundledEffectContext            *pBundledContext;
 };
 
 //TODO: this should be included from each effect API include
@@ -115,15 +130,15 @@
 /* enumerated parameter settings for Equalizer effect */
 typedef enum
 {
-    EQ_PARAM_NUM_BANDS,             // Gets the number of frequency bands that the equalizer supports.
-    EQ_PARAM_LEVEL_RANGE,           // Returns the minimum and maximum band levels supported.
-    EQ_PARAM_BAND_LEVEL,            // Gets/Sets the gain set for the given equalizer band.
-    EQ_PARAM_CENTER_FREQ,           // Gets the center frequency of the given band.
-    EQ_PARAM_BAND_FREQ_RANGE,       // Gets the frequency range of the given frequency band.
-    EQ_PARAM_GET_BAND,              // Gets the band that has the most effect on the given frequency.
-    EQ_PARAM_CUR_PRESET,            // Gets/Sets the current preset.
-    EQ_PARAM_GET_NUM_OF_PRESETS,    // Gets the total number of presets the equalizer supports.
-    EQ_PARAM_GET_PRESET_NAME        // Gets the preset name based on the index.
+    EQ_PARAM_NUM_BANDS,           // Gets the number of frequency bands that the equalizer supports.
+    EQ_PARAM_LEVEL_RANGE,         // Returns the minimum and maximum band levels supported.
+    EQ_PARAM_BAND_LEVEL,          // Gets/Sets the gain set for the given equalizer band.
+    EQ_PARAM_CENTER_FREQ,         // Gets the center frequency of the given band.
+    EQ_PARAM_BAND_FREQ_RANGE,     // Gets the frequency range of the given frequency band.
+    EQ_PARAM_GET_BAND,            // Gets the band that has the most effect on the given frequency.
+    EQ_PARAM_CUR_PRESET,          // Gets/Sets the current preset.
+    EQ_PARAM_GET_NUM_OF_PRESETS,  // Gets the total number of presets the equalizer supports.
+    EQ_PARAM_GET_PRESET_NAME      // Gets the preset name based on the index.
 } t_equalizer_params;
 
 /* enumerated parameter settings for Volume effect */
@@ -139,29 +154,28 @@
 static const int PRESET_CUSTOM = -1;
 
 static const uint32_t bandFreqRange[FIVEBAND_NUMBANDS][2] = {
-	{30000, 120000},
-	{12000, 460000},
-	{46000, 1800000},
-	{180000, 7000000},
-	{700000, 1}
-	};
+                                       {30000, 120000},
+                                       {120001, 460000},
+                                       {460001, 1800000},
+                                       {1800001, 7000000},
+                                       {7000001, 1}};
 
 static const LVM_UINT16  EQNB_5BandPresetsFrequencies[] = {
-															60,           /* Frequencies in Hz */
-															230,
-															910,
-															3600,
-															14000};
+                                       60,           /* Frequencies in Hz */
+                                       230,
+                                       910,
+                                       3600,
+                                       14000};
 
 static const LVM_UINT16 EQNB_5BandPresetsQFactors[] = {
-		                                  96,               /* Q factor multiplied by 100 */
-                                          96,
-                                          96,
-                                          96,
-                                          96};
+                                       96,               /* Q factor multiplied by 100 */
+                                       96,
+                                       96,
+                                       96,
+                                       96};
 
 static const LVM_INT16 EQNB_5BandNormalPresets[] = {
-									   3, 0, 0, 0, 3,       /* Normal Preset */
+                                       3, 0, 0, 0, 3,       /* Normal Preset */
                                        8, 5, -3, 5, 6,      /* Classical Preset */
                                        15, -6, 7, 13, 10,   /* Dance Preset */
                                        0, 0, 0, 0, 0,       /* Flat Preset */
@@ -172,18 +186,29 @@
                                       -6, 4, 9, 4, -5,      /* Pop Preset */
                                        10, 6, -1, 8, 10};   /* Rock Preset */
 
+static const LVM_INT16 EQNB_5BandSoftPresets[] = {
+                                        3, 0, 0, 0, 3,      /* Normal Preset */
+                                        5, 3, -2, 4, 4,     /* Classical Preset */
+                                        6, 0, 2, 4, 1,      /* Dance Preset */
+                                        0, 0, 0, 0, 0,      /* Flat Preset */
+                                        3, 0, 0, 2, -1,     /* Folk Preset */
+                                        4, 1, 9, 3, 0,      /* Heavy Metal Preset */
+                                        5, 3, 0, 1, 3,      /* Hip Hop Preset */
+                                        4, 2, -2, 2, 5,     /* Jazz Preset */
+                                       -1, 2, 5, 1, -2,     /* Pop Preset */
+                                        5, 3, -1, 3, 5};    /* Rock Preset */
+
 static const PresetConfig gEqualizerPresets[] = {
-    		{"Normal"},
-    		{"Classical"},
-    		{"Dance"},
-    		{"Flat"},
-    		{"Folk"},
-    		{"Heavy Metal"},
-    		{"Hip Hop"},
-    		{"Jazz"},
-    		{"Pop"},
-    		{"Rock"}
-    };
+                                        {"Normal"},
+                                        {"Classical"},
+                                        {"Dance"},
+                                        {"Flat"},
+                                        {"Folk"},
+                                        {"Heavy Metal"},
+                                        {"Hip Hop"},
+                                        {"Jazz"},
+                                        {"Pop"},
+                                        {"Rock"}};
 
 #if __cplusplus
 }  // extern "C"
diff --git a/media/libmediaplayerservice/StagefrightRecorder.cpp b/media/libmediaplayerservice/StagefrightRecorder.cpp
index 3dbcfd5..f747f90 100644
--- a/media/libmediaplayerservice/StagefrightRecorder.cpp
+++ b/media/libmediaplayerservice/StagefrightRecorder.cpp
@@ -473,6 +473,32 @@
     return OK;
 }
 
+status_t StagefrightRecorder::setParamTimeLapseEnable(int32_t timeLapseEnable) {
+    LOGV("setParamTimeLapseEnable: %d", timeLapseEnable);
+
+    if(timeLapseEnable == 0) {
+        mCaptureTimeLapse = false;
+    } else if (timeLapseEnable == 1) {
+        mCaptureTimeLapse = true;
+    } else {
+        return BAD_VALUE;
+    }
+    return OK;
+}
+
+status_t StagefrightRecorder::setParamTimeBetweenTimeLapseFrameCapture(int64_t timeUs) {
+    LOGV("setParamTimeBetweenTimeLapseFrameCapture: %lld us", timeUs);
+
+    // Not allowing time more than a day
+    if (timeUs <= 0 || timeUs > 86400*1E6) {
+        LOGE("Time between time lapse frame capture (%lld) is out of range [0, 1 Day]", timeUs);
+        return BAD_VALUE;
+    }
+
+    mTimeBetweenTimeLapseFrameCaptureUs = timeUs;
+    return OK;
+}
+
 status_t StagefrightRecorder::setParameter(
         const String8 &key, const String8 &value) {
     LOGV("setParameter: key (%s) => value (%s)", key.string(), value.string());
@@ -556,6 +582,17 @@
         if (safe_strtoi32(value.string(), &timeScale)) {
             return setParamVideoTimeScale(timeScale);
         }
+    } else if (key == "time-lapse-enable") {
+        int32_t timeLapseEnable;
+        if (safe_strtoi32(value.string(), &timeLapseEnable)) {
+            return setParamTimeLapseEnable(timeLapseEnable);
+        }
+    } else if (key == "time-between-time-lapse-frame-capture") {
+        int64_t timeBetweenTimeLapseFrameCaptureMs;
+        if (safe_strtoi64(value.string(), &timeBetweenTimeLapseFrameCaptureMs)) {
+            return setParamTimeBetweenTimeLapseFrameCapture(
+                    1000LL * timeBetweenTimeLapseFrameCaptureMs);
+        }
     } else {
         LOGE("setParameter: failed to find key %s", key.string());
     }
@@ -813,10 +850,14 @@
 }
 
 status_t StagefrightRecorder::setupCameraSource() {
-    clipVideoBitRate();
-    clipVideoFrameRate();
-    clipVideoFrameWidth();
-    clipVideoFrameHeight();
+    if(!mCaptureTimeLapse) {
+        // Dont clip for time lapse capture as encoder will have enough
+        // time to encode because of slow capture rate of time lapse.
+        clipVideoBitRate();
+        clipVideoFrameRate();
+        clipVideoFrameWidth();
+        clipVideoFrameHeight();
+    }
 
     int64_t token = IPCThreadState::self()->clearCallingIdentity();
     if (mCamera == 0) {
@@ -831,7 +872,13 @@
 
     // Set the actual video recording frame size
     CameraParameters params(mCamera->getParameters());
-    params.setPreviewSize(mVideoWidth, mVideoHeight);
+
+    // dont change the preview size for time lapse as mVideoWidth, mVideoHeight
+    // may correspond to HD resolution not supported by video camera.
+    if (!mCaptureTimeLapse) {
+        params.setPreviewSize(mVideoWidth, mVideoHeight);
+    }
+
     params.setPreviewFrameRate(mFrameRate);
     String8 s = params.flatten();
     CHECK_EQ(OK, mCamera->setParameters(s));
@@ -840,8 +887,9 @@
     // Check on video frame size
     int frameWidth = 0, frameHeight = 0;
     newCameraParams.getPreviewSize(&frameWidth, &frameHeight);
-    if (frameWidth  < 0 || frameWidth  != mVideoWidth ||
-        frameHeight < 0 || frameHeight != mVideoHeight) {
+    if (!mCaptureTimeLapse &&
+        (frameWidth  < 0 || frameWidth  != mVideoWidth ||
+        frameHeight < 0 || frameHeight != mVideoHeight)) {
         LOGE("Failed to set the video frame size to %dx%d",
                 mVideoWidth, mVideoHeight);
         IPCThreadState::self()->restoreCallingIdentity(token);
@@ -882,7 +930,8 @@
     if (err != OK) return err;
 
     sp<CameraSource> cameraSource = (mCaptureTimeLapse) ?
-        CameraSourceTimeLapse::CreateFromCamera(mCamera, true, 3E6, mFrameRate):
+        CameraSourceTimeLapse::CreateFromCamera(mCamera, true,
+                mTimeBetweenTimeLapseFrameCaptureUs, mVideoWidth, mVideoHeight, mFrameRate):
         CameraSource::CreateFromCamera(mCamera);
     CHECK(cameraSource != NULL);
 
@@ -934,6 +983,7 @@
     OMXClient client;
     CHECK_EQ(client.connect(), OK);
 
+    // Use software codec for time lapse
     uint32_t encoder_flags = (mCaptureTimeLapse) ? OMXCodec::kPreferSoftwareCodecs : 0;
     sp<MediaSource> encoder = OMXCodec::Create(
             client.interface(), enc_meta,
@@ -1081,6 +1131,7 @@
     mMaxFileSizeBytes = 0;
     mTrackEveryTimeDurationUs = 0;
     mCaptureTimeLapse = false;
+    mTimeBetweenTimeLapseFrameCaptureUs = -1;
     mEncoderProfiles = MediaProfiles::getInstance();
 
     mOutputFd = -1;
diff --git a/media/libmediaplayerservice/StagefrightRecorder.h b/media/libmediaplayerservice/StagefrightRecorder.h
index 232fc0e..fc287a2 100644
--- a/media/libmediaplayerservice/StagefrightRecorder.h
+++ b/media/libmediaplayerservice/StagefrightRecorder.h
@@ -93,6 +93,7 @@
     int64_t mTrackEveryTimeDurationUs;
 
     bool mCaptureTimeLapse;
+    int64_t mTimeBetweenTimeLapseFrameCaptureUs;
 
     String8 mParams;
     int mOutputFd;
@@ -114,6 +115,8 @@
     status_t setParamAudioNumberOfChannels(int32_t channles);
     status_t setParamAudioSamplingRate(int32_t sampleRate);
     status_t setParamAudioTimeScale(int32_t timeScale);
+    status_t setParamTimeLapseEnable(int32_t timeLapseEnable);
+    status_t setParamTimeBetweenTimeLapseFrameCapture(int64_t timeUs);
     status_t setParamVideoEncodingBitRate(int32_t bitRate);
     status_t setParamVideoIFramesInterval(int32_t seconds);
     status_t setParamVideoEncoderProfile(int32_t profile);
diff --git a/media/libstagefright/AudioSource.cpp b/media/libstagefright/AudioSource.cpp
index 6031797..50c0edc 100644
--- a/media/libstagefright/AudioSource.cpp
+++ b/media/libstagefright/AudioSource.cpp
@@ -137,53 +137,76 @@
     MediaBuffer *buffer;
     CHECK_EQ(mGroup->acquire_buffer(&buffer), OK);
 
-    uint32_t numFramesRecorded;
-    mRecord->getPosition(&numFramesRecorded);
-    int64_t latency = mRecord->latency() * 1000;
+    while (mStarted) {
+        uint32_t numFramesRecorded;
+        mRecord->getPosition(&numFramesRecorded);
+        int64_t latency = mRecord->latency() * 1000;
 
-    int64_t readTime = systemTime() / 1000;
-    if (numFramesRecorded == 0) {
-        // Initial delay
-        if (mStartTimeUs > 0) {
-            mStartTimeUs = readTime - mStartTimeUs;
+        int64_t readTime = systemTime() / 1000;
+
+        if (numFramesRecorded == 0) {
+            // Initial delay
+            if (mStartTimeUs > 0) {
+                mStartTimeUs = readTime - mStartTimeUs;
+            } else {
+                mStartTimeUs += latency;
+            }
+        }
+
+        ssize_t n = 0;
+        if (mCollectStats) {
+            n = mRecord->read(buffer->data(), buffer->size());
+            int64_t endTime = systemTime() / 1000;
+            mTotalReadTimeUs += (endTime - readTime);
+            if (n >= 0) {
+                mTotalReadBytes += n;
+            }
         } else {
-            mStartTimeUs += latency;
+            n = mRecord->read(buffer->data(), buffer->size());
         }
-    }
 
-    ssize_t n = 0;
-    if (mCollectStats) {
-        n = mRecord->read(buffer->data(), buffer->size());
-        int64_t endTime = systemTime() / 1000;
-        mTotalReadTimeUs += (endTime - readTime);
-        if (n >= 0) {
-            mTotalReadBytes += n;
+        if (n < 0) {
+            buffer->release();
+            buffer = NULL;
+
+            return (status_t)n;
         }
-    } else {
-        n = mRecord->read(buffer->data(), buffer->size());
+
+        uint32_t sampleRate = mRecord->getSampleRate();
+        int64_t timestampUs = (1000000LL * numFramesRecorded) / sampleRate +
+                                 mStartTimeUs;
+        int64_t skipFrameUs;
+        if (!options || !options->getSkipFrame(&skipFrameUs)) {
+            skipFrameUs = timestampUs;  // Don't skip frame
+        }
+
+        if (skipFrameUs > timestampUs) {
+            // Safe guard against the abuse of the kSkipFrame_Option.
+            if (skipFrameUs - timestampUs >= 1E6) {
+                LOGE("Frame skipping requested is way too long: %lld us",
+                    skipFrameUs - timestampUs);
+                buffer->release();
+                return UNKNOWN_ERROR;
+            }
+            LOGV("skipFrame: %lld us > timestamp: %lld us, samples %d",
+                skipFrameUs, timestampUs, numFramesRecorded);
+            continue;
+        }
+
+        if (mTrackMaxAmplitude) {
+            trackMaxAmplitude((int16_t *) buffer->data(), n >> 1);
+        }
+
+        buffer->meta_data()->setInt64(kKeyTime, timestampUs);
+        LOGV("initial delay: %lld, sample rate: %d, timestamp: %lld",
+                mStartTimeUs, sampleRate, timestampUs);
+
+        buffer->set_range(0, n);
+
+        *out = buffer;
+        return OK;
     }
 
-    if (n < 0) {
-        buffer->release();
-        buffer = NULL;
-
-        return (status_t)n;
-    }
-
-    if (mTrackMaxAmplitude) {
-        trackMaxAmplitude((int16_t *) buffer->data(), n >> 1);
-    }
-
-    uint32_t sampleRate = mRecord->getSampleRate();
-    int64_t timestampUs = (1000000LL * numFramesRecorded) / sampleRate + mStartTimeUs;
-    buffer->meta_data()->setInt64(kKeyTime, timestampUs);
-    LOGV("initial delay: %lld, sample rate: %d, timestamp: %lld",
-            mStartTimeUs, sampleRate, timestampUs);
-
-    buffer->set_range(0, n);
-
-    *out = buffer;
-
     return OK;
 }
 
diff --git a/media/libstagefright/CameraSource.cpp b/media/libstagefright/CameraSource.cpp
index f4d269f..5e7dd5c 100644
--- a/media/libstagefright/CameraSource.cpp
+++ b/media/libstagefright/CameraSource.cpp
@@ -292,23 +292,44 @@
 
     {
         Mutex::Autolock autoLock(mLock);
-        while (mStarted && mFramesReceived.empty()) {
-            mFrameAvailableCondition.wait(mLock);
-        }
-        if (!mStarted) {
-            return OK;
-        }
-        frame = *mFramesReceived.begin();
-        mFramesReceived.erase(mFramesReceived.begin());
+        while (mStarted) {
+            while(mFramesReceived.empty()) {
+                mFrameAvailableCondition.wait(mLock);
+            }
 
-        frameTime = *mFrameTimes.begin();
-        mFrameTimes.erase(mFrameTimes.begin());
+            if (!mStarted) {
+                return OK;
+            }
 
-        mFramesBeingEncoded.push_back(frame);
-        *buffer = new MediaBuffer(frame->pointer(), frame->size());
-        (*buffer)->setObserver(this);
-        (*buffer)->add_ref();
-        (*buffer)->meta_data()->setInt64(kKeyTime, frameTime);
+            frame = *mFramesReceived.begin();
+            mFramesReceived.erase(mFramesReceived.begin());
+
+            frameTime = *mFrameTimes.begin();
+            mFrameTimes.erase(mFrameTimes.begin());
+            int64_t skipTimeUs;
+            if (!options || !options->getSkipFrame(&skipTimeUs)) {
+                skipTimeUs = frameTime;
+            }
+            if (skipTimeUs > frameTime) {
+                LOGV("skipTimeUs: %lld us > frameTime: %lld us",
+                    skipTimeUs, frameTime);
+                releaseOneRecordingFrame(frame);
+                ++mNumFramesDropped;
+                // Safeguard against the abuse of the kSkipFrame_Option.
+                if (skipTimeUs - frameTime >= 1E6) {
+                    LOGE("Frame skipping requested is way too long: %lld us",
+                        skipTimeUs - frameTime);
+                    return UNKNOWN_ERROR;
+                }
+            } else {
+                mFramesBeingEncoded.push_back(frame);
+                *buffer = new MediaBuffer(frame->pointer(), frame->size());
+                (*buffer)->setObserver(this);
+                (*buffer)->add_ref();
+                (*buffer)->meta_data()->setInt64(kKeyTime, frameTime);
+                return OK;
+            }
+        }
     }
     return OK;
 }
diff --git a/media/libstagefright/CameraSourceTimeLapse.cpp b/media/libstagefright/CameraSourceTimeLapse.cpp
index 30ed143..c6186f6 100644
--- a/media/libstagefright/CameraSourceTimeLapse.cpp
+++ b/media/libstagefright/CameraSourceTimeLapse.cpp
@@ -33,6 +33,7 @@
 // static
 CameraSourceTimeLapse *CameraSourceTimeLapse::Create(bool useStillCameraForTimeLapse,
         int64_t timeBetweenTimeLapseFrameCaptureUs,
+        int32_t width, int32_t height,
         int32_t videoFrameRate) {
     sp<Camera> camera = Camera::connect(0);
 
@@ -41,25 +42,27 @@
     }
 
     return new CameraSourceTimeLapse(camera, useStillCameraForTimeLapse,
-            timeBetweenTimeLapseFrameCaptureUs, videoFrameRate);
+            timeBetweenTimeLapseFrameCaptureUs, width, height, videoFrameRate);
 }
 
 // static
 CameraSourceTimeLapse *CameraSourceTimeLapse::CreateFromCamera(const sp<Camera> &camera,
         bool useStillCameraForTimeLapse,
         int64_t timeBetweenTimeLapseFrameCaptureUs,
+        int32_t width, int32_t height,
         int32_t videoFrameRate) {
     if (camera.get() == NULL) {
         return NULL;
     }
 
     return new CameraSourceTimeLapse(camera, useStillCameraForTimeLapse,
-            timeBetweenTimeLapseFrameCaptureUs, videoFrameRate);
+            timeBetweenTimeLapseFrameCaptureUs, width, height, videoFrameRate);
 }
 
 CameraSourceTimeLapse::CameraSourceTimeLapse(const sp<Camera> &camera,
         bool useStillCameraForTimeLapse,
         int64_t timeBetweenTimeLapseFrameCaptureUs,
+        int32_t width, int32_t height,
         int32_t videoFrameRate)
     : CameraSource(camera),
       mUseStillCameraForTimeLapse(useStillCameraForTimeLapse),
@@ -70,11 +73,6 @@
 
     LOGV("starting time lapse mode");
     if(mUseStillCameraForTimeLapse) {
-        // Currently hardcoded the picture size. Will need to choose
-        // automatically or pass in from the app.
-        int32_t width, height;
-        width = 1024;
-        height = 768;
         mMeta->setInt32(kKeyWidth, width);
         mMeta->setInt32(kKeyHeight, height);
     }
diff --git a/media/libstagefright/MediaSource.cpp b/media/libstagefright/MediaSource.cpp
index fd0e79c3..b4ef338 100644
--- a/media/libstagefright/MediaSource.cpp
+++ b/media/libstagefright/MediaSource.cpp
@@ -32,6 +32,7 @@
     mOptions = 0;
     mSeekTimeUs = 0;
     mLatenessUs = 0;
+    mSkipFrameUntilTimeUs = 0;
 }
 
 void MediaSource::ReadOptions::setSeekTo(int64_t time_us, SeekMode mode) {
@@ -53,6 +54,21 @@
     return (mOptions & kSeekTo_Option) != 0;
 }
 
+void MediaSource::ReadOptions::clearSkipFrame() {
+    mOptions &= ~kSkipFrame_Option;
+    mSkipFrameUntilTimeUs = 0;
+}
+
+void MediaSource::ReadOptions::setSkipFrame(int64_t timeUs) {
+    mOptions |= kSkipFrame_Option;
+    mSkipFrameUntilTimeUs = timeUs;
+}
+
+bool MediaSource::ReadOptions::getSkipFrame(int64_t *timeUs) const {
+    *timeUs = mSkipFrameUntilTimeUs;
+    return (mOptions & kSkipFrame_Option) != 0;
+}
+
 void MediaSource::ReadOptions::setLateBy(int64_t lateness_us) {
     mLatenessUs = lateness_us;
 }
diff --git a/media/libstagefright/OMXCodec.cpp b/media/libstagefright/OMXCodec.cpp
index 1b63083..3fba2d9 100644
--- a/media/libstagefright/OMXCodec.cpp
+++ b/media/libstagefright/OMXCodec.cpp
@@ -1274,6 +1274,7 @@
       mSeekTimeUs(-1),
       mSeekMode(ReadOptions::SEEK_CLOSEST_SYNC),
       mTargetTimeUs(-1),
+      mSkipTimeUs(-1),
       mLeftOverBuffer(NULL),
       mPaused(false) {
     mPortStatus[kPortIndexInput] = ENABLED;
@@ -2200,13 +2201,15 @@
     int32_t n = 0;
     for (;;) {
         MediaBuffer *srcBuffer;
+        MediaSource::ReadOptions options;
+        if (mSkipTimeUs >= 0) {
+            options.setSkipFrame(mSkipTimeUs);
+        }
         if (mSeekTimeUs >= 0) {
             if (mLeftOverBuffer) {
                 mLeftOverBuffer->release();
                 mLeftOverBuffer = NULL;
             }
-
-            MediaSource::ReadOptions options;
             options.setSeekTo(mSeekTimeUs, mSeekMode);
 
             mSeekTimeUs = -1;
@@ -2231,7 +2234,7 @@
 
             err = OK;
         } else {
-            err = mSource->read(&srcBuffer);
+            err = mSource->read(&srcBuffer, &options);
         }
 
         if (err != OK) {
@@ -2830,6 +2833,12 @@
     if (options && options->getSeekTo(&seekTimeUs, &seekMode)) {
         seeking = true;
     }
+    int64_t skipTimeUs;
+    if (options && options->getSkipFrame(&skipTimeUs)) {
+        mSkipTimeUs = skipTimeUs;
+    } else {
+        mSkipTimeUs = -1;
+    }
 
     if (mInitialBufferSubmit) {
         mInitialBufferSubmit = false;
diff --git a/media/libstagefright/codecs/aacenc/AACEncoder.cpp b/media/libstagefright/codecs/aacenc/AACEncoder.cpp
index e8235c2..052c354 100644
--- a/media/libstagefright/codecs/aacenc/AACEncoder.cpp
+++ b/media/libstagefright/codecs/aacenc/AACEncoder.cpp
@@ -224,6 +224,7 @@
         if (mInputBuffer == NULL) {
             if (mSource->read(&mInputBuffer, options) != OK) {
                 if (mNumInputSamples == 0) {
+                    buffer->release();
                     return ERROR_END_OF_STREAM;
                 }
                 memset(&mInputFrame[mNumInputSamples],
diff --git a/opengl/tests/gl_perf/fill_common.cpp b/opengl/tests/gl_perf/fill_common.cpp
new file mode 100644
index 0000000..36db1b0
--- /dev/null
+++ b/opengl/tests/gl_perf/fill_common.cpp
@@ -0,0 +1,316 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+FILE * fOut = NULL;
+void ptSwap();
+
+static void checkGlError(const char* op) {
+    for (GLint error = glGetError(); error; error
+            = glGetError()) {
+        LOGE("after %s() glError (0x%x)\n", op, error);
+    }
+}
+
+GLuint loadShader(GLenum shaderType, const char* pSource) {
+    GLuint shader = glCreateShader(shaderType);
+    if (shader) {
+        glShaderSource(shader, 1, &pSource, NULL);
+        glCompileShader(shader);
+        GLint compiled = 0;
+        glGetShaderiv(shader, GL_COMPILE_STATUS, &compiled);
+        if (!compiled) {
+            GLint infoLen = 0;
+            glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &infoLen);
+            if (infoLen) {
+                char* buf = (char*) malloc(infoLen);
+                if (buf) {
+                    glGetShaderInfoLog(shader, infoLen, NULL, buf);
+                    LOGE("Could not compile shader %d:\n%s\n", shaderType, buf);
+                    free(buf);
+                }
+                glDeleteShader(shader);
+                shader = 0;
+            }
+        }
+    }
+    return shader;
+}
+
+enum {
+    A_POS,
+    A_COLOR,
+    A_TEX0,
+    A_TEX1
+};
+
+GLuint createProgram(const char* pVertexSource, const char* pFragmentSource) {
+    GLuint vertexShader = loadShader(GL_VERTEX_SHADER, pVertexSource);
+    if (!vertexShader) {
+        return 0;
+    }
+
+    GLuint pixelShader = loadShader(GL_FRAGMENT_SHADER, pFragmentSource);
+    if (!pixelShader) {
+        return 0;
+    }
+
+    GLuint program = glCreateProgram();
+    if (program) {
+        glAttachShader(program, vertexShader);
+        checkGlError("glAttachShader v");
+        glAttachShader(program, pixelShader);
+        checkGlError("glAttachShader p");
+
+        glBindAttribLocation(program, A_POS, "a_pos");
+        glBindAttribLocation(program, A_COLOR, "a_color");
+        glBindAttribLocation(program, A_TEX0, "a_tex0");
+        glBindAttribLocation(program, A_TEX1, "a_tex1");
+        glLinkProgram(program);
+        GLint linkStatus = GL_FALSE;
+        glGetProgramiv(program, GL_LINK_STATUS, &linkStatus);
+        if (linkStatus != GL_TRUE) {
+            GLint bufLength = 0;
+            glGetProgramiv(program, GL_INFO_LOG_LENGTH, &bufLength);
+            if (bufLength) {
+                char* buf = (char*) malloc(bufLength);
+                if (buf) {
+                    glGetProgramInfoLog(program, bufLength, NULL, buf);
+                    LOGE("Could not link program:\n%s\n", buf);
+                    free(buf);
+                }
+            }
+            glDeleteProgram(program);
+            program = 0;
+        }
+    }
+    checkGlError("createProgram");
+    glUseProgram(program);
+    return program;
+}
+
+uint64_t getTime() {
+    struct timespec t;
+    clock_gettime(CLOCK_MONOTONIC, &t);
+    return t.tv_nsec + ((uint64_t)t.tv_sec * 1000 * 1000 * 1000);
+}
+
+uint64_t gTime;
+void startTimer() {
+    gTime = getTime();
+}
+
+void endTimer(const char *str, int w, int h, double dc, int count) {
+    uint64_t t2 = getTime();
+    double delta = ((double)(t2 - gTime)) / 1000000000;
+    double pixels = dc * (w * h) * count;
+    double mpps = pixels / delta / 1000000;
+    double dc60 = pixels / delta / (w * h) / 60;
+
+    if (fOut) {
+        fprintf(fOut, "%s, %f, %f\r\n", str, mpps, dc60);
+        fflush(fOut);
+    } else {
+        printf("%s, %f, %f\n", str, mpps, dc60);
+    }
+    LOGI("%s, %f, %f\r\n", str, mpps, dc60);
+}
+
+
+static const char gVertexShader[] =
+    "attribute vec4 a_pos;\n"
+    "attribute vec4 a_color;\n"
+    "attribute vec2 a_tex0;\n"
+    "attribute vec2 a_tex1;\n"
+    "varying vec4 v_color;\n"
+    "varying vec2 v_tex0;\n"
+    "varying vec2 v_tex1;\n"
+
+    "void main() {\n"
+    "    v_color = a_color;\n"
+    "    v_tex0 = a_tex0;\n"
+    "    v_tex1 = a_tex1;\n"
+    "    gl_Position = a_pos;\n"
+    "}\n";
+
+static const char gShaderPrefix[] =
+    "precision mediump float;\n"
+    "uniform vec4 u_color;\n"
+    "uniform vec4 u_0;\n"
+    "uniform vec4 u_1;\n"
+    "uniform vec4 u_2;\n"
+    "uniform vec4 u_3;\n"
+    "varying vec4 v_color;\n"
+    "varying vec2 v_tex0;\n"
+    "varying vec2 v_tex1;\n"
+    "uniform sampler2D u_tex0;\n"
+    "uniform sampler2D u_tex1;\n"
+    "void main() {\n";
+
+static const char gShaderPostfix[] =
+    "  gl_FragColor = c;\n"
+    "}\n";
+
+
+static char * append(char *d, const char *s) {
+    size_t len = strlen(s);
+    memcpy(d, s, len);
+    return d + len;
+}
+
+static char * genShader(
+    bool useVarColor,
+    int texCount,
+    bool modulateFirstTex,
+    int extraMath)
+{
+    char *str = (char *)calloc(16 * 1024, 1);
+    char *tmp = append(str, gShaderPrefix);
+
+    if (modulateFirstTex || !texCount) {
+        if (useVarColor) {
+            tmp = append(tmp, "  vec4 c = v_color;\n");
+        } else {
+            tmp = append(tmp, "  vec4 c = u_color;\n");
+        }
+    } else {
+        tmp = append(tmp, "  vec4 c = texture2D(u_tex0, v_tex0);\n");
+    }
+
+    if (modulateFirstTex && texCount) {
+        tmp = append(tmp, "  c *= texture2D(u_tex0, v_tex0);\n");
+    }
+    if (texCount > 1) {
+        tmp = append(tmp, "  c *= texture2D(u_tex1, v_tex1);\n");
+    }
+
+    if (extraMath > 0) {
+        tmp = append(tmp, "  c *= u_0;\n");
+    }
+    if (extraMath > 1) {
+        tmp = append(tmp, "  c += u_1;\n");
+    }
+    if (extraMath > 2) {
+        tmp = append(tmp, "  c *= u_2;\n");
+    }
+    if (extraMath > 3) {
+        tmp = append(tmp, "  c += u_3;\n");
+    }
+
+
+    tmp = append(tmp, gShaderPostfix);
+    tmp[0] = 0;
+
+    //printf("%s", str);
+    return str;
+}
+
+static void setupVA() {
+    static const float vtx[] = {
+        -1.0f,-1.0f,
+         1.0f,-1.0f,
+        -1.0f, 1.0f,
+         1.0f, 1.0f };
+    static const float color[] = {
+        1.0f,0.0f,1.0f,1.0f,
+        0.0f,0.0f,1.0f,1.0f,
+        1.0f,1.0f,0.0f,1.0f,
+        1.0f,1.0f,1.0f,1.0f };
+    static const float tex0[] = {
+        0.0f,0.0f,
+        1.0f,0.0f,
+        1.0f,1.0f,
+        0.0f,1.0f };
+    static const float tex1[] = {
+        1.0f,0.0f,
+        1.0f,1.0f,
+        0.0f,1.0f,
+        0.0f,0.0f };
+
+    glEnableVertexAttribArray(A_POS);
+    glEnableVertexAttribArray(A_COLOR);
+    glEnableVertexAttribArray(A_TEX0);
+    glEnableVertexAttribArray(A_TEX1);
+
+    glVertexAttribPointer(A_POS, 2, GL_FLOAT, false, 8, vtx);
+    glVertexAttribPointer(A_COLOR, 4, GL_FLOAT, false, 16, color);
+    glVertexAttribPointer(A_TEX0, 2, GL_FLOAT, false, 8, tex0);
+    glVertexAttribPointer(A_TEX1, 2, GL_FLOAT, false, 8, tex1);
+}
+
+static void randUniform(int pgm, const char *var) {
+    int loc = glGetUniformLocation(pgm, var);
+    if (loc >= 0) {
+        float x = ((float)rand()) / RAND_MAX;
+        float y = ((float)rand()) / RAND_MAX;
+        float z = ((float)rand()) / RAND_MAX;
+        float w = ((float)rand()) / RAND_MAX;
+        glUniform4f(loc, x, y, z, w);
+    }
+}
+
+static void doLoop(bool clear, int pgm, uint32_t w, uint32_t h, const char *str) {
+    if (clear) {
+        glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);
+        glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
+        ptSwap();
+        glFinish();
+        return;
+    }
+
+    startTimer();
+    glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);
+    for (int ct=0; ct < 100; ct++) {
+        randUniform(pgm, "u_color");
+        randUniform(pgm, "u_0");
+        randUniform(pgm, "u_1");
+        randUniform(pgm, "u_2");
+        randUniform(pgm, "u_3");
+        glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
+    }
+    ptSwap();
+    glFinish();
+    endTimer(str, w, h, 1, 100);
+}
+
+void genTextures() {
+    uint32_t *m = (uint32_t *)malloc(1024*1024*4);
+    for (int y=0; y < 1024; y++){
+        for (int x=0; x < 1024; x++){
+            m[y*1024 + x] = 0xff0000ff | ((x & 0xff) << 8) | (y << 16);
+        }
+    }
+    glBindTexture(GL_TEXTURE_2D, 1);
+    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1024, 1024, 0, GL_RGBA, GL_UNSIGNED_BYTE, m);
+    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
+    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
+
+    for (int y=0; y < 16; y++){
+        for (int x=0; x < 16; x++){
+            m[y*16 + x] = 0xff0000ff | (x<<12) | (y<<20);
+        }
+    }
+    glBindTexture(GL_TEXTURE_2D, 2);
+    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 16, 16, 0, GL_RGBA, GL_UNSIGNED_BYTE, m);
+    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
+    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
+
+}
+
+
diff --git a/opengl/tests/gl_perf/filltest.cpp b/opengl/tests/gl_perf/filltest.cpp
index eb398ec..0dd4e22 100644
--- a/opengl/tests/gl_perf/filltest.cpp
+++ b/opengl/tests/gl_perf/filltest.cpp
@@ -25,256 +25,13 @@
 #include <GLES2/gl2ext.h>
 #include <utils/Timers.h>
 #include <EGL/egl.h>
+#include <utils/Log.h>
 
 
 using namespace android;
 
-static void checkGlError(const char* op) {
-    for (GLint error = glGetError(); error; error
-            = glGetError()) {
-        fprintf(stderr, "after %s() glError (0x%x)\n", op, error);
-    }
-}
 
-GLuint loadShader(GLenum shaderType, const char* pSource) {
-    GLuint shader = glCreateShader(shaderType);
-    if (shader) {
-        glShaderSource(shader, 1, &pSource, NULL);
-        glCompileShader(shader);
-        GLint compiled = 0;
-        glGetShaderiv(shader, GL_COMPILE_STATUS, &compiled);
-        if (!compiled) {
-            GLint infoLen = 0;
-            glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &infoLen);
-            if (infoLen) {
-                char* buf = (char*) malloc(infoLen);
-                if (buf) {
-                    glGetShaderInfoLog(shader, infoLen, NULL, buf);
-                    fprintf(stderr, "Could not compile shader %d:\n%s\n",
-                            shaderType, buf);
-                    free(buf);
-                }
-                glDeleteShader(shader);
-                shader = 0;
-            }
-        }
-    }
-    return shader;
-}
-
-enum {
-    A_POS,
-    A_COLOR,
-    A_TEX0,
-    A_TEX1
-};
-
-GLuint createProgram(const char* pVertexSource, const char* pFragmentSource) {
-    GLuint vertexShader = loadShader(GL_VERTEX_SHADER, pVertexSource);
-    if (!vertexShader) {
-        return 0;
-    }
-
-    GLuint pixelShader = loadShader(GL_FRAGMENT_SHADER, pFragmentSource);
-    if (!pixelShader) {
-        return 0;
-    }
-
-    GLuint program = glCreateProgram();
-    if (program) {
-        glAttachShader(program, vertexShader);
-        checkGlError("glAttachShader v");
-        glAttachShader(program, pixelShader);
-        checkGlError("glAttachShader p");
-
-        glBindAttribLocation(program, A_POS, "a_pos");
-        glBindAttribLocation(program, A_COLOR, "a_color");
-        glBindAttribLocation(program, A_TEX0, "a_tex0");
-        glBindAttribLocation(program, A_TEX1, "a_tex1");
-        glLinkProgram(program);
-        GLint linkStatus = GL_FALSE;
-        glGetProgramiv(program, GL_LINK_STATUS, &linkStatus);
-        if (linkStatus != GL_TRUE) {
-            GLint bufLength = 0;
-            glGetProgramiv(program, GL_INFO_LOG_LENGTH, &bufLength);
-            if (bufLength) {
-                char* buf = (char*) malloc(bufLength);
-                if (buf) {
-                    glGetProgramInfoLog(program, bufLength, NULL, buf);
-                    printf("Could not link program:\n%s\n", buf);
-                    free(buf);
-                }
-            }
-            glDeleteProgram(program);
-            program = 0;
-        }
-    }
-    checkGlError("createProgram");
-    glUseProgram(program);
-    return program;
-}
-
-uint64_t getTime() {
-    struct timespec t;
-    clock_gettime(CLOCK_MONOTONIC, &t);
-    return t.tv_nsec + ((uint64_t)t.tv_sec * 1000 * 1000 * 1000);
-}
-
-uint64_t gTime;
-void startTimer() {
-    gTime = getTime();
-}
-
-void endTimer(const char *str, int w, int h, double dc, int count) {
-    uint64_t t2 = getTime();
-    double delta = ((double)(t2 - gTime)) / 1000000000;
-    double pixels = dc * (w * h) * count;
-    double mpps = pixels / delta / 1000000;
-    double dc60 = pixels / delta / (w * h) / 60;
-
-    printf("%s, %f, %f\n", str, mpps, dc60);
-}
-
-static const char gVertexShader[] =
-    "attribute vec4 a_pos;\n"
-    "attribute vec4 a_color;\n"
-    "attribute vec2 a_tex0;\n"
-    "attribute vec2 a_tex1;\n"
-    "varying vec4 v_color;\n"
-    "varying vec2 v_tex0;\n"
-    "varying vec2 v_tex1;\n"
-
-    "void main() {\n"
-    "    v_color = a_color;\n"
-    "    v_tex0 = a_tex0;\n"
-    "    v_tex1 = a_tex1;\n"
-    "    gl_Position = a_pos;\n"
-    "}\n";
-
-static const char gShaderPrefix[] =
-    "precision mediump float;\n"
-    "uniform vec4 u_color;\n"
-    "uniform vec4 u_0;\n"
-    "uniform vec4 u_1;\n"
-    "uniform vec4 u_2;\n"
-    "uniform vec4 u_3;\n"
-    "varying vec4 v_color;\n"
-    "varying vec2 v_tex0;\n"
-    "varying vec2 v_tex1;\n"
-    "uniform sampler2D u_tex0;\n"
-    "uniform sampler2D u_tex1;\n"
-    "void main() {\n";
-
-static const char gShaderPostfix[] =
-    "  gl_FragColor = c;\n"
-    "}\n";
-
-
-static char * append(char *d, const char *s) {
-    size_t len = strlen(s);
-    memcpy(d, s, len);
-    return d + len;
-}
-
-static char * genShader(
-    bool useVarColor,
-    int texCount,
-    bool modulateFirstTex,
-    int extraMath)
-{
-    char *str = (char *)calloc(16 * 1024, 1);
-    char *tmp = append(str, gShaderPrefix);
-
-    if (modulateFirstTex || !texCount) {
-        if (useVarColor) {
-            tmp = append(tmp, "  vec4 c = v_color;\n");
-        } else {
-            tmp = append(tmp, "  vec4 c = u_color;\n");
-        }
-    } else {
-        tmp = append(tmp, "  vec4 c = texture2D(u_tex0, v_tex0);\n");
-    }
-
-    if (modulateFirstTex && texCount) {
-        tmp = append(tmp, "  c *= texture2D(u_tex0, v_tex0);\n");
-    }
-    if (texCount > 1) {
-        tmp = append(tmp, "  c *= texture2D(u_tex1, v_tex1);\n");
-    }
-
-    if (extraMath > 0) {
-        tmp = append(tmp, "  c *= u_0;\n");
-    }
-    if (extraMath > 1) {
-        tmp = append(tmp, "  c *= u_1;\n");
-    }
-    if (extraMath > 2) {
-        tmp = append(tmp, "  c *= u_2;\n");
-    }
-    if (extraMath > 3) {
-        tmp = append(tmp, "  c *= u_3;\n");
-    }
-
-
-    tmp = append(tmp, gShaderPostfix);
-    tmp[0] = 0;
-
-    //printf("%s", str);
-    return str;
-}
-
-static void setupVA() {
-    static const float vtx[] = {
-        -2.0f,-1.0f,
-         1.0f,-1.0f,
-        -2.0f, 1.0f,
-         1.0f, 1.0f };
-    static const float color[] = {
-        1.0f,0.0f,1.0f,1.0f,
-        0.0f,0.0f,1.0f,1.0f,
-        1.0f,1.0f,0.0f,1.0f,
-        1.0f,1.0f,1.0f,1.0f };
-    static const float tex0[] = {
-        0.0f,0.0f,
-        1.0f,0.0f,
-        1.0f,1.0f,
-        0.0f,1.0f };
-    static const float tex1[] = {
-        1.0f,0.0f,
-        1.0f,1.0f,
-        0.0f,1.0f,
-        0.0f,0.0f };
-
-    glEnableVertexAttribArray(A_POS);
-    glEnableVertexAttribArray(A_COLOR);
-    glEnableVertexAttribArray(A_TEX0);
-    glEnableVertexAttribArray(A_TEX1);
-
-    glVertexAttribPointer(A_POS, 2, GL_FLOAT, false, 8, vtx);
-    glVertexAttribPointer(A_COLOR, 4, GL_FLOAT, false, 16, color);
-    glVertexAttribPointer(A_TEX0, 2, GL_FLOAT, false, 8, tex0);
-    glVertexAttribPointer(A_TEX1, 2, GL_FLOAT, false, 8, tex1);
-}
-
-//////////////////////////
-
-void ptSwap();
-
-static void doLoop(uint32_t w, uint32_t h, const char *str) {
-    glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);
-    glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
-    ptSwap();
-    glFinish();
-
-    startTimer();
-    glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);
-    for (int ct=0; ct < 100; ct++) {
-        glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
-    }
-    ptSwap();
-    glFinish();
-    endTimer(str, w, h, 1, 100);
-}
+#include "fill_common.cpp"
 
 static void doSingleTest(uint32_t w, uint32_t h,
                          bool useVarColor,
@@ -289,26 +46,10 @@
         return;
     }
     int loc = glGetUniformLocation(pgm, "u_tex0");
-    //printf("loc = %i \n", loc);
     if (loc >= 0) glUniform1i(loc, 0);
     loc = glGetUniformLocation(pgm, "u_tex1");
     if (loc >= 0) glUniform1i(loc, 1);
 
-    loc = glGetUniformLocation(pgm, "u_color");
-    if (loc >= 0) glUniform4f(loc, 1.f, 0.4f, 0.6f, 0.8f);
-
-    loc = glGetUniformLocation(pgm, "u_0");
-    if (loc >= 0) glUniform4f(loc, 1.f, 0.4f, 0.6f, 0.8f);
-
-    loc = glGetUniformLocation(pgm, "u_1");
-    if (loc >= 0) glUniform4f(loc, 0.7f, 0.8f, 0.6f, 0.8f);
-
-    loc = glGetUniformLocation(pgm, "u_2");
-    if (loc >= 0) glUniform4f(loc, 0.9f, 0.6f, 0.7f, 1.0f);
-
-    loc = glGetUniformLocation(pgm, "u_3");
-    if (loc >= 0) glUniform4f(loc, 0.88f, 0.2f, 0.4f, 0.2f);
-
     glActiveTexture(GL_TEXTURE0);
     glBindTexture(GL_TEXTURE_2D, tex0);
     glActiveTexture(GL_TEXTURE1);
@@ -319,42 +60,16 @@
 
     glBlendFunc(GL_ONE, GL_ONE);
     glDisable(GL_BLEND);
-    sprintf(str2, "%i, %i, %i, %i, %i, 0",
-            useVarColor, texCount, modulateFirstTex, extraMath, tex0);
-    doLoop(w, h, str2);
+    //sprintf(str2, "%i, %i, %i, %i, %i, 0",
+            //useVarColor, texCount, modulateFirstTex, extraMath, tex0);
+    //doLoop(true, pgm, w, h, str2);
+    //doLoop(false, pgm, w, h, str2);
 
     glEnable(GL_BLEND);
     sprintf(str2, "%i, %i, %i, %i, %i, 1",
             useVarColor, texCount, modulateFirstTex, extraMath, tex0);
-    doLoop(w, h, str2);
-}
-
-void genTextures() {
-    uint32_t *m = (uint32_t *)malloc(1024*1024*4);
-    for (int y=0; y < 1024; y++){
-        for (int x=0; x < 1024; x++){
-            m[y*1024 + x] = 0xff0000ff | ((x & 0xff) << 8) | (y << 16);
-        }
-    }
-    glBindTexture(GL_TEXTURE_2D, 1);
-    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1024, 1024, 0, GL_RGBA, GL_UNSIGNED_BYTE, m);
-    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
-    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
-    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
-    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
-
-    for (int y=0; y < 16; y++){
-        for (int x=0; x < 16; x++){
-            m[y*16 + x] = 0xff0000ff | (x<<12) | (y<<20);
-        }
-    }
-    glBindTexture(GL_TEXTURE_2D, 2);
-    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 16, 16, 0, GL_RGBA, GL_UNSIGNED_BYTE, m);
-    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
-    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
-    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
-    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
-
+    doLoop(true, pgm, w, h, str2);
+    doLoop(false, pgm, w, h, str2);
 }
 
 bool doTest(uint32_t w, uint32_t h) {
@@ -363,7 +78,7 @@
 
     printf("\nvarColor, texCount, modulate, extraMath, texSize, blend, Mpps, DC60\n");
 
-    for (int texCount = 0; texCount < 3; texCount++) {
+    for (int texCount = 0; texCount < 2; texCount++) {
         for (int extraMath = 0; extraMath < 5; extraMath++) {
 
             doSingleTest(w, h, false, texCount, false, extraMath, 1, 1);
diff --git a/opengl/tests/gl_perfapp/jni/gl_code.cpp b/opengl/tests/gl_perfapp/jni/gl_code.cpp
index 020d848..e643292 100644
--- a/opengl/tests/gl_perfapp/jni/gl_code.cpp
+++ b/opengl/tests/gl_perfapp/jni/gl_code.cpp
@@ -13,243 +13,8 @@
 #include <stdlib.h>
 #include <math.h>
 
-FILE * out;
+#include "../../gl_perf/fill_common.cpp"
 
-static void printGLString(const char *name, GLenum s) {
-    const char *v = (const char *) glGetString(s);
-    LOGI("GL %s = %s\n", name, v);
-}
-
-static void checkGlError(const char* op) {
-    for (GLint error = glGetError(); error; error
-            = glGetError()) {
-        LOGI("after %s() glError (0x%x)\n", op, error);
-    }
-}
-
-GLuint loadShader(GLenum shaderType, const char* pSource) {
-    GLuint shader = glCreateShader(shaderType);
-    if (shader) {
-        glShaderSource(shader, 1, &pSource, NULL);
-        glCompileShader(shader);
-        GLint compiled = 0;
-        glGetShaderiv(shader, GL_COMPILE_STATUS, &compiled);
-        if (!compiled) {
-            GLint infoLen = 0;
-            glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &infoLen);
-            if (infoLen) {
-                char* buf = (char*) malloc(infoLen);
-                if (buf) {
-                    glGetShaderInfoLog(shader, infoLen, NULL, buf);
-                    LOGE("Could not compile shader %d:\n%s\n",
-                            shaderType, buf);
-                    free(buf);
-                }
-                glDeleteShader(shader);
-                shader = 0;
-            }
-        }
-    }
-    return shader;
-}
-
-enum {
-    A_POS,
-    A_COLOR,
-    A_TEX0,
-    A_TEX1
-};
-
-GLuint createProgram(const char* pVertexSource, const char* pFragmentSource) {
-    GLuint vertexShader = loadShader(GL_VERTEX_SHADER, pVertexSource);
-    if (!vertexShader) {
-        return 0;
-    }
-
-    GLuint pixelShader = loadShader(GL_FRAGMENT_SHADER, pFragmentSource);
-    if (!pixelShader) {
-        return 0;
-    }
-
-    GLuint program = glCreateProgram();
-    if (program) {
-        glAttachShader(program, vertexShader);
-        checkGlError("glAttachShader v");
-        glAttachShader(program, pixelShader);
-        checkGlError("glAttachShader p");
-
-        glBindAttribLocation(program, A_POS, "a_pos");
-        glBindAttribLocation(program, A_COLOR, "a_color");
-        glBindAttribLocation(program, A_TEX0, "a_tex0");
-        glBindAttribLocation(program, A_TEX1, "a_tex1");
-        glLinkProgram(program);
-        GLint linkStatus = GL_FALSE;
-        glGetProgramiv(program, GL_LINK_STATUS, &linkStatus);
-        if (linkStatus != GL_TRUE) {
-            GLint bufLength = 0;
-            glGetProgramiv(program, GL_INFO_LOG_LENGTH, &bufLength);
-            if (bufLength) {
-                char* buf = (char*) malloc(bufLength);
-                if (buf) {
-                    glGetProgramInfoLog(program, bufLength, NULL, buf);
-                    LOGE("Could not link program:\n%s\n", buf);
-                    free(buf);
-                }
-            }
-            glDeleteProgram(program);
-            program = 0;
-        }
-    }
-    checkGlError("createProgram");
-    glUseProgram(program);
-    return program;
-}
-
-uint64_t getTime() {
-    struct timespec t;
-    clock_gettime(CLOCK_MONOTONIC, &t);
-    return t.tv_nsec + ((uint64_t)t.tv_sec * 1000 * 1000 * 1000);
-}
-
-uint64_t gTime;
-void startTimer() {
-    gTime = getTime();
-}
-
-void endTimer(const char *str, int w, int h, double dc, int count) {
-    uint64_t t2 = getTime();
-    double delta = ((double)(t2 - gTime)) / 1000000000;
-    double pixels = dc * (w * h) * count;
-    double mpps = pixels / delta / 1000000;
-    double dc60 = pixels / delta / (w * h) / 60;
-
-    LOGI("%s, %f, %f\n", str, mpps, dc60);
-    if (out) {
-        fprintf(out, "%s, %f, %f\r\n", str, mpps, dc60);
-        fflush(out);
-    }
-}
-
-static const char gVertexShader[] =
-    "attribute vec4 a_pos;\n"
-    "attribute vec4 a_color;\n"
-    "attribute vec2 a_tex0;\n"
-    "attribute vec2 a_tex1;\n"
-    "varying vec4 v_color;\n"
-    "varying vec2 v_tex0;\n"
-    "varying vec2 v_tex1;\n"
-
-    "void main() {\n"
-    "    v_color = a_color;\n"
-    "    v_tex0 = a_tex0;\n"
-    "    v_tex1 = a_tex1;\n"
-    "    gl_Position = a_pos;\n"
-    "}\n";
-
-static const char gShaderPrefix[] =
-    "precision mediump float;\n"
-    "uniform vec4 u_color;\n"
-    "uniform vec4 u_0;\n"
-    "uniform vec4 u_1;\n"
-    "uniform vec4 u_2;\n"
-    "uniform vec4 u_3;\n"
-    "varying vec4 v_color;\n"
-    "varying vec2 v_tex0;\n"
-    "varying vec2 v_tex1;\n"
-    "uniform sampler2D u_tex0;\n"
-    "uniform sampler2D u_tex1;\n"
-    "void main() {\n";
-
-static const char gShaderPostfix[] =
-    "  gl_FragColor = c;\n"
-    "}\n";
-
-
-static char * append(char *d, const char *s) {
-    size_t len = strlen(s);
-    memcpy(d, s, len);
-    return d + len;
-}
-
-static char * genShader(
-    bool useVarColor,
-    int texCount,
-    bool modulateFirstTex,
-    int extraMath)
-{
-    char *str = (char *)calloc(16 * 1024, 1);
-    char *tmp = append(str, gShaderPrefix);
-
-    if (modulateFirstTex || !texCount) {
-        if (useVarColor) {
-            tmp = append(tmp, "  vec4 c = v_color;\n");
-        } else {
-            tmp = append(tmp, "  vec4 c = u_color;\n");
-        }
-    } else {
-        tmp = append(tmp, "  vec4 c = texture2D(u_tex0, v_tex0);\n");
-    }
-
-    if (modulateFirstTex && texCount) {
-        tmp = append(tmp, "  c *= texture2D(u_tex0, v_tex0);\n");
-    }
-    if (texCount > 1) {
-        tmp = append(tmp, "  c *= texture2D(u_tex1, v_tex1);\n");
-    }
-
-    if (extraMath > 0) {
-        tmp = append(tmp, "  c *= u_0;\n");
-    }
-    if (extraMath > 1) {
-        tmp = append(tmp, "  c *= u_1;\n");
-    }
-    if (extraMath > 2) {
-        tmp = append(tmp, "  c *= u_2;\n");
-    }
-    if (extraMath > 3) {
-        tmp = append(tmp, "  c *= u_3;\n");
-    }
-
-
-    tmp = append(tmp, gShaderPostfix);
-    tmp[0] = 0;
-
-    //LOGI("%s", str);
-    return str;
-}
-
-static void setupVA() {
-    static const float vtx[] = {
-        -2.0f,-1.0f,
-         1.0f,-1.0f,
-        -2.0f, 1.0f,
-         1.0f, 1.0f };
-    static const float color[] = {
-        1.0f,0.0f,1.0f,1.0f,
-        0.0f,0.0f,1.0f,1.0f,
-        1.0f,1.0f,0.0f,1.0f,
-        1.0f,1.0f,1.0f,1.0f };
-    static const float tex0[] = {
-        0.0f,0.0f,
-        1.0f,0.0f,
-        1.0f,1.0f,
-        0.0f,1.0f };
-    static const float tex1[] = {
-        1.0f,0.0f,
-        1.0f,1.0f,
-        0.0f,1.0f,
-        0.0f,0.0f };
-
-    glEnableVertexAttribArray(A_POS);
-    glEnableVertexAttribArray(A_COLOR);
-    glEnableVertexAttribArray(A_TEX0);
-    glEnableVertexAttribArray(A_TEX1);
-
-    glVertexAttribPointer(A_POS, 2, GL_FLOAT, false, 8, vtx);
-    glVertexAttribPointer(A_COLOR, 4, GL_FLOAT, false, 16, color);
-    glVertexAttribPointer(A_TEX0, 2, GL_FLOAT, false, 8, tex0);
-    glVertexAttribPointer(A_TEX1, 2, GL_FLOAT, false, 8, tex1);
-}
 
 //////////////////////////
 
@@ -269,23 +34,10 @@
 
 char saveBuf[1024];
 
-static void doLoop(uint32_t w, uint32_t h, const char *str) {
-    int doLoopState = stateClock % doLoopStates;
-    // LOGI("doLoop %d\n", doLoopState);
-    switch(doLoopState) {
-    case 0:
-	    glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);
-	    glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
-    	break;
-    case 1:
-            strcpy(saveBuf, str);
-	    startTimer();
-	    glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);
-	    for (int ct=0; ct < 100; ct++) {
-		glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
-	    }
-	break;
-    }
+
+int pgm;
+
+void ptSwap() {
 }
 
 static void doSingleTest(uint32_t w, uint32_t h,
@@ -299,32 +51,16 @@
     switch (doSingleTestState) {
 	case 0: {
 	    char *pgmTxt = genShader(useVarColor, texCount, modulateFirstTex, extraMath);
-	    int pgm = createProgram(gVertexShader, pgmTxt);
+	    pgm = createProgram(gVertexShader, pgmTxt);
 	    if (!pgm) {
 		LOGE("error running test\n");
 		return;
 	    }
 	    int loc = glGetUniformLocation(pgm, "u_tex0");
-	    //LOGI("loc = %i \n", loc);
 	    if (loc >= 0) glUniform1i(loc, 0);
 	    loc = glGetUniformLocation(pgm, "u_tex1");
 	    if (loc >= 0) glUniform1i(loc, 1);
 
-	    loc = glGetUniformLocation(pgm, "u_color");
-	    if (loc >= 0) glUniform4f(loc, 1.f, 0.4f, 0.6f, 0.8f);
-
-	    loc = glGetUniformLocation(pgm, "u_0");
-	    if (loc >= 0) glUniform4f(loc, 1.f, 0.4f, 0.6f, 0.8f);
-
-	    loc = glGetUniformLocation(pgm, "u_1");
-	    if (loc >= 0) glUniform4f(loc, 0.7f, 0.8f, 0.6f, 0.8f);
-
-	    loc = glGetUniformLocation(pgm, "u_2");
-	    if (loc >= 0) glUniform4f(loc, 0.9f, 0.6f, 0.7f, 1.0f);
-
-	    loc = glGetUniformLocation(pgm, "u_3");
-	    if (loc >= 0) glUniform4f(loc, 0.88f, 0.2f, 0.4f, 0.2f);
-
 	    glActiveTexture(GL_TEXTURE0);
 	    glBindTexture(GL_TEXTURE_2D, tex0);
 	    glActiveTexture(GL_TEXTURE1);
@@ -337,7 +73,8 @@
             char str2[1024];
 	    sprintf(str2, "%i, %i, %i, %i, %i, 0",
 		    useVarColor, texCount, modulateFirstTex, extraMath, tex0);
-    	    doLoop(w, h, str2);
+
+    	    doLoop((stateClock % doLoopStates) != 0, pgm, w, h, str2);
 	 }
          break;
          case 1: {
@@ -345,39 +82,12 @@
 	    glEnable(GL_BLEND);
 	    sprintf(str2, "%i, %i, %i, %i, %i, 1",
 		    useVarColor, texCount, modulateFirstTex, extraMath, tex0);
-	    doLoop(w, h, str2);
+	    doLoop((stateClock % doLoopStates) != 0, pgm, w, h, str2);
         }
         break;
     }
 }
 
-void genTextures() {
-    uint32_t *m = (uint32_t *)malloc(1024*1024*4);
-    for (int y=0; y < 1024; y++){
-        for (int x=0; x < 1024; x++){
-            m[y*1024 + x] = 0xff0000ff | ((x & 0xff) << 8) | (y << 16);
-        }
-    }
-    glBindTexture(GL_TEXTURE_2D, 1);
-    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1024, 1024, 0, GL_RGBA, GL_UNSIGNED_BYTE, m);
-    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
-    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
-    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
-    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
-
-    for (int y=0; y < 16; y++){
-        for (int x=0; x < 16; x++){
-            m[y*16 + x] = 0xff0000ff | (x<<12) | (y<<20);
-        }
-    }
-    glBindTexture(GL_TEXTURE_2D, 2);
-    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 16, 16, 0, GL_RGBA, GL_UNSIGNED_BYTE, m);
-    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
-    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
-    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
-    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
-
-}
 
 void doTest(uint32_t w, uint32_t h) {
     int testState = stateClock / (doLoopStates * doSingleTestStates);
@@ -399,9 +109,9 @@
     }
     if (texCount >= 3) {
        LOGI("done\n");
-       if (out) {
-           fclose(out);
-           out = NULL;
+       if (fOut) {
+           fclose(fOut);
+           fOut = NULL;
        }
        done = true;
        return;
@@ -454,19 +164,19 @@
 	    setupVA();
 	    genTextures();
 	    const char* fileName = "/sdcard/glperf.csv";
-            if (out != NULL) {
+            if (fOut != NULL) {
                  LOGI("Closing partially written output.n");
-                 fclose(out);
-                 out = NULL;
+                 fclose(fOut);
+                 fOut = NULL;
             }
 	    LOGI("Writing to: %s\n",fileName);
-	    out = fopen(fileName, "w");
-	    if (out == NULL) {
+	    fOut = fopen(fileName, "w");
+	    if (fOut == NULL) {
 		LOGE("Could not open: %s\n", fileName);
 	    }
 
 	    LOGI("\nvarColor, texCount, modulate, extraMath, texSize, blend, Mpps, DC60\n");
-	    if (out) fprintf(out,"varColor, texCount, modulate, extraMath, texSize, blend, Mpps, DC60\r\n");
+	    if (fOut) fprintf(fOut,"varColor, texCount, modulate, extraMath, texSize, blend, Mpps, DC60\r\n");
     }
 }
 
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarPolicy.java b/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarPolicy.java
index 4f39ee4..e828f68 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarPolicy.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarPolicy.java
@@ -1033,6 +1033,7 @@
                     iconId = sWifiSignalImages[mLastWifiSignalLevel];
                 }
 
+                mService.setIcon("wifi", iconId, 0);
                 // Show the icon since wi-fi is connected
                 mService.setIconVisibility("wifi", true);
 
@@ -1041,11 +1042,11 @@
                 mIsWifiConnected = false;
                 iconId = sWifiSignalImages[0];
 
+                mService.setIcon("wifi", iconId, 0);
                 // Hide the icon since we're not connected
                 mService.setIconVisibility("wifi", false);
             }
 
-            mService.setIcon("wifi", iconId, 0);
         } else if (action.equals(WifiManager.RSSI_CHANGED_ACTION)) {
             int iconId;
             final int newRssi = intent.getIntExtra(WifiManager.EXTRA_NEW_RSSI, -200);
diff --git a/services/java/com/android/server/am/ActivityManagerService.java b/services/java/com/android/server/am/ActivityManagerService.java
index a8df71d..0c8769e 100644
--- a/services/java/com/android/server/am/ActivityManagerService.java
+++ b/services/java/com/android/server/am/ActivityManagerService.java
@@ -3549,10 +3549,12 @@
                 String[] pkgs = intent.getStringArrayExtra(Intent.EXTRA_PACKAGES);
                 if (pkgs != null) {
                     for (String pkg : pkgs) {
-                        if (forceStopPackageLocked(pkg, -1, false, false, false)) {
-                            setResultCode(Activity.RESULT_OK);
-                            return;
-                        }
+                        synchronized (ActivityManagerService.this) {
+                          if (forceStopPackageLocked(pkg, -1, false, false, false)) {
+                              setResultCode(Activity.RESULT_OK);
+                              return;
+                          }
+                       }
                     }
                 }
             }
diff --git a/services/sensorservice/SensorService.cpp b/services/sensorservice/SensorService.cpp
index 82cdf3d..b79373d 100644
--- a/services/sensorservice/SensorService.cpp
+++ b/services/sensorservice/SensorService.cpp
@@ -40,7 +40,6 @@
 
 /*
  * TODO:
- * - filter events per connection
  * - make sure to keep the last value of each event type so we can quickly
  *   send something to application when they enable a sensor that is already
  *   active (the issue here is that it can take time before a value is
@@ -162,6 +161,7 @@
     LOGD("nuSensorService thread starting...");
 
     sensors_event_t buffer[16];
+    sensors_event_t scratch[16];
     struct sensors_poll_device_t* device = mSensorDevice;
     ssize_t count;
 
@@ -177,10 +177,11 @@
 
         size_t numConnections = activeConnections.size();
         if (numConnections) {
+            Mutex::Autolock _l(mLock);
             for (size_t i=0 ; i<numConnections ; i++) {
                 sp<SensorEventConnection> connection(activeConnections[i].promote());
                 if (connection != 0) {
-                    connection->sendEvents(buffer, count);
+                    connection->sendEvents(buffer, count, scratch);
                 }
             }
         }
@@ -425,12 +426,23 @@
 }
 
 status_t SensorService::SensorEventConnection::sendEvents(
-        sensors_event_t const* buffer, size_t count)
+        sensors_event_t const* buffer, size_t numEvents,
+        sensors_event_t* scratch)
 {
-    // TODO: we should only send the events for the sensors this connection
-    // is registered for.
+    // filter out events not for this connection
+    size_t count=0, i=0;
+    while (i<numEvents) {
+        const int32_t curr = buffer[i].sensor;
+        if (mSensorInfo.indexOfKey(curr) >= 0) {
+            do {
+                scratch[count++] = buffer[i++];
+            } while ((i<numEvents) && (buffer[i].sensor == curr));
+        } else {
+            i++;
+        }
+    }
 
-    ssize_t size = mChannel->write(buffer, count*sizeof(sensors_event_t));
+    ssize_t size = mChannel->write(scratch, count*sizeof(sensors_event_t));
     if (size == -EAGAIN) {
         // the destination doesn't accept events anymore, it's probably
         // full. For now, we just drop the events on the floor.
diff --git a/services/sensorservice/SensorService.h b/services/sensorservice/SensorService.h
index b8dda84..f77652d 100644
--- a/services/sensorservice/SensorService.h
+++ b/services/sensorservice/SensorService.h
@@ -77,8 +77,6 @@
         sp<SensorChannel> const mChannel;
 
         // protected by SensorService::mLock
-        //SortedVector<int32_t> mSensorList;
-
         struct SensorInfo {
             SensorInfo() : ns(DEFAULT_EVENTS_PERIOD) { }
             nsecs_t ns;
@@ -88,7 +86,8 @@
     public:
         SensorEventConnection(const sp<SensorService>& service);
 
-        status_t sendEvents(sensors_event_t const* buffer, size_t count);
+        status_t sendEvents(sensors_event_t const* buffer, size_t count,
+                sensors_event_t* scratch);
         bool hasSensor(int32_t handle) const;
         bool hasAnySensor() const;
         bool addSensor(int32_t handle);