diff --git a/include/media/AudioEffect.h b/include/media/AudioEffect.h
new file mode 100644
index 0000000..2bdba2d
--- /dev/null
+++ b/include/media/AudioEffect.h
@@ -0,0 +1,462 @@
+/*
+ * Copyright (C) 2009 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_AUDIOEFFECT_H
+#define ANDROID_AUDIOEFFECT_H
+
+#include <stdint.h>
+#include <sys/types.h>
+
+#include <media/IAudioFlinger.h>
+#include <media/IEffect.h>
+#include <media/IEffectClient.h>
+#include <media/EffectApi.h>
+#include <media/AudioSystem.h>
+
+#include <utils/RefBase.h>
+#include <utils/Errors.h>
+#include <binder/IInterface.h>
+
+
+namespace android {
+
+// ----------------------------------------------------------------------------
+
+class effect_param_cblk_t;
+
+// ----------------------------------------------------------------------------
+
+class AudioEffect : public RefBase
+{
+public:
+
+    /*
+     *  Static methods for effect libraries management.
+     */
+
+    /*
+     *   Loads the effect library which path is given as first argument.
+     *   This must be the full path of a dynamic library (.so) implementing one or
+     *   more effect engines and exposing the effect library interface described in
+     *   EffectApi.h. The function returns a handle on the library for use by
+     *   further call to unloadEffectLibrary() to unload the library.
+     *
+     *   Parameters:
+     *          libPath:    full path of the dynamic library file in the file system.
+     *          handle:     address where to return the library handle
+     *
+     *   Returned status (from utils/Errors.h) can be:
+     *          NO_ERROR    successful operation.
+     *          PERMISSION_DENIED could not get AudioFlinger interface or
+     *                      application does not have permission to configure audio
+     *          NO_INIT     effect factory not initialized or
+     *                      library could not be loaded or
+     *                      library does not implement required functions
+     *          BAD_VALUE   invalid libPath string or handle
+     *
+     *   Returned value:
+     *          *handle updated with library handle
+     */
+    static status_t loadEffectLibrary(const char *libPath, int *handle);
+
+    /*
+     *   Unloads the effect library which handle is given as argument.
+     *
+     *   Parameters:
+     *          handle: library handle
+     *
+     *   Returned status (from utils/Errors.h) can be:
+     *          NO_ERROR    successful operation.
+     *          PERMISSION_DENIED could not get AudioFlinger interface or
+     *                      application does not have permission to configure audio
+     *          NO_INIT     effect factory not initialized
+     *          BAD_VALUE   invalid handle
+     */
+    static status_t unloadEffectLibrary(int handle);
+
+    /*
+     *  Static methods for effects enumeration.
+     */
+
+    /*
+     * Returns the number of effects available. This method together
+     * with EffectQueryNext() is used to enumerate all effects:
+     * The enumeration sequence is:
+     *      QueryNumberEffects(&num_effects);
+     *      while (num_effects--)
+     *          QueryNextEffect();
+     *
+     * Parameters:
+     *      pNumEffects:    address where the number of effects should be returned.
+     *
+     * Returned status (from utils/Errors.h) can be:
+     *      NO_ERROR   successful operation.
+     *      PERMISSION_DENIED could not get AudioFlinger interface
+     *      NO_INIT    effect library failed to initialize
+     *      BAD_VALUE  invalid numEffects pointer
+     *
+     * Returned value
+     *   *numEffects:     updated with number of effects available
+     */
+    static status_t queryNumberEffects(uint32_t *numEffects);
+
+    /*
+     * Returns number effect descriptor during effect
+     * enumeration.
+     *
+     * Parameters:
+     *      pDescriptor:    address where the effect descriptor should be returned.
+     *
+     * Returned status (from utils/Errors.h) can be:
+     *      NO_ERROR        successful operation.
+     *      NAME_NOT_FOUND  no more effect available
+     *      PERMISSION_DENIED could not get AudioFlinger interface
+     *      NO_INIT         effect library failed to initialize
+     *      BAD_VALUE       invalid descriptor pointer
+     *      INVALID_OPERATION  effect list has changed since last execution of queryNumberEffects()
+     *
+     * Returned value
+     *   *descriptor:     updated with effect descriptor
+     */
+    static status_t queryNextEffect(effect_descriptor_t *descriptor);
+
+
+    /*
+     * Returns the descriptor for the specified effect uuid.
+     *
+     * Parameters:
+     *      uuid:       pointer to effect uuid.
+     *      descriptor: address where the effect descriptor should be returned.
+     *
+     * Returned status (from utils/Errors.h) can be:
+     *      NO_ERROR        successful operation.
+     *      PERMISSION_DENIED could not get AudioFlinger interface
+     *      NO_INIT         effect library failed to initialize
+     *      BAD_VALUE       invalid uuid or descriptor pointers
+     *      NAME_NOT_FOUND  no effect with this uuid found
+     *
+     * Returned value
+     *   *descriptor updated with effect descriptor
+     */
+    static status_t getEffectDescriptor(effect_uuid_t *uuid, effect_descriptor_t *descriptor);
+
+
+    /*
+     * Events used by callback function (effect_callback_t).
+     */
+    enum event_type {
+        EVENT_CONTROL_STATUS_CHANGED = 0,
+        EVENT_ENABLE_STATUS_CHANGED = 1,
+        EVENT_PARAMETER_CHANGED = 2,
+        EVENT_ERROR = 3
+    };
+
+    /* Callback function notifying client application of a change in effect engine state or
+     * configuration.
+     * An effect engine can be shared by several applications but only one has the control
+     * of the engine activity and configuration at a time.
+     * The EVENT_CONTROL_STATUS_CHANGED event is received when an application loses or
+     * retrieves the control of the effect engine. Loss of control happens
+     * if another application requests the use of the engine by creating an AudioEffect for
+     * the same effect type but with a higher priority. Control is returned when the
+     * application having the control deletes its AudioEffect object.
+     * The EVENT_ENABLE_STATUS_CHANGED event is received by all applications not having the
+     * control of the effect engine when the effect is enabled or disabled.
+     * The EVENT_PARAMETER_CHANGED event is received by all applications not having the
+     * control of the effect engine when an effect parameter is changed.
+     * The EVENT_ERROR event is received when the media server process dies.
+     *
+     * Parameters:
+     *
+     * event:   type of event notified (see enum AudioEffect::event_type).
+     * user:    Pointer to context for use by the callback receiver.
+     * info:    Pointer to optional parameter according to event type:
+     *  - EVENT_CONTROL_STATUS_CHANGED:  boolean indicating if control is granted (true)
+     *  or stolen (false).
+     *  - EVENT_ENABLE_STATUS_CHANGED: boolean indicating if effect is now enabled (true)
+     *  or disabled (false).
+     *  - EVENT_PARAMETER_CHANGED: pointer to a effect_param_t structure.
+     *  - EVENT_ERROR:  status_t indicating the error (DEAD_OBJECT when media server dies).
+     */
+
+    typedef void (*effect_callback_t)(int32_t event, void* user, void *info);
+
+
+    /* Constructor.
+     * AudioEffect is the base class for creating and controlling an effect engine from
+     * the application process. Creating an AudioEffect object will create the effect engine
+     * in the AudioFlinger if no engine of the specified type exists. If one exists, this engine
+     * will be used. The application creating the AudioEffect object (or a derived class like
+     * Reverb for instance) will either receive control of the effect engine or not, depending
+     * on the priority parameter. If priority is higher than the priority used by the current
+     * effect engine owner, the control will be transfered to the new application. Otherwise
+     * control will remain to the previous application. In this case, the new application will be
+     * notified of changes in effect engine state or control ownership by the effect callback.
+     * After creating the AudioEffect, the application must call the initCheck() method and
+     * check the creation status before trying to control the effect engine (see initCheck()).
+     * If the effect is to be applied to an AudioTrack or MediaPlayer only the application
+     * must specify the audio session ID corresponding to this player.
+     */
+
+    /* Simple Constructor.
+     */
+    AudioEffect();
+
+
+    /* Constructor.
+     *
+     * Parameters:
+     *
+     * type:  type of effect created: can be null if uuid is specified. This corresponds to
+     *        the OpenSL ES interface implemented by this effect.
+     * uuid:  Uuid of effect created: can be null if type is specified. This uuid corresponds to
+     *        a particular implementation of an effect type.
+     * priority:    requested priority for effect control: the priority level corresponds to the
+     *      value of priority parameter: negative values indicate lower priorities, positive values
+     *      higher priorities, 0 being the normal priority.
+     * cbf:         optional callback function (see effect_callback_t)
+     * user:        pointer to context for use by the callback receiver.
+     * sessionID:   audio session this effect is associated to. If 0, the effect will be global to
+     *      the output mix. If not 0, the effect will be applied to all players
+     *      (AudioTrack or MediaPLayer) within the same audio session.
+     * output:  HAL audio output stream to which this effect must be attached. Leave at 0 for
+     *      automatic output selection by AudioFlinger.
+     */
+
+    AudioEffect(const effect_uuid_t *type,
+                const effect_uuid_t *uuid = NULL,
+                  int32_t priority = 0,
+                  effect_callback_t cbf = 0,
+                  void* user = 0,
+                  int sessionId = 0,
+                  audio_io_handle_t output = 0
+                  );
+
+    /* Constructor.
+     *      Same as above but with type and uuid specified by character strings
+     */
+    AudioEffect(const char *typeStr,
+                    const char *uuidStr = NULL,
+                    int32_t priority = 0,
+                    effect_callback_t cbf = 0,
+                    void* user = 0,
+                    int sessionId = 0,
+                    audio_io_handle_t output = 0
+                    );
+
+    /* Terminates the AudioEffect and unregisters it from AudioFlinger.
+     * The effect engine is also destroyed if this AudioEffect was the last controlling
+     * the engine.
+     */
+                        ~AudioEffect();
+
+    /* Initialize an uninitialized AudioEffect.
+    * Returned status (from utils/Errors.h) can be:
+    *  - NO_ERROR or ALREADY_EXISTS: successful initialization
+    *  - INVALID_OPERATION: AudioEffect is already initialized
+    *  - BAD_VALUE: invalid parameter
+    *  - NO_INIT: audio flinger or audio hardware not initialized
+    * */
+            status_t    set(const effect_uuid_t *type,
+                            const effect_uuid_t *uuid = NULL,
+                            int32_t priority = 0,
+                            effect_callback_t cbf = 0,
+                            void* user = 0,
+                            int sessionId = 0,
+                            audio_io_handle_t output = 0
+                            );
+
+    /* Result of constructing the AudioEffect. This must be checked
+     * before using any AudioEffect API.
+     * initCheck() can return:
+     *  - NO_ERROR:    the effect engine is successfully created and the application has control.
+     *  - ALREADY_EXISTS: the effect engine is successfully created but the application does not
+     *              have control.
+     *  - NO_INIT:     the effect creation failed.
+     *
+     */
+            status_t    initCheck() const;
+
+
+    /* Returns the unique effect Id for the controlled effect engine. This ID is unique
+     * system wide and is used for instance in the case of auxiliary effects to attach
+     * the effect to an AudioTrack or MediaPlayer.
+     *
+     */
+            int32_t     id() const { return mId; }
+
+    /* Returns a descriptor for the effect (see effect_descriptor_t in EffectApi.h).
+     */
+            effect_descriptor_t descriptor() const;
+
+    /* Returns effect control priority of this AudioEffect object.
+     */
+            int32_t     priority() const { return mPriority; }
+
+
+    /* Enables the effect engine.
+     *
+     * Parameters:
+     *      None.
+     *
+     * Returned status (from utils/Errors.h) can be:
+     *  - NO_ERROR: successful operation
+     *  - INVALID_OPERATION: the application does not have control of the effect engine
+     */
+            status_t    enable();
+
+    /* Disables the effect engine.
+     *
+     * Parameters:
+     *      None.
+     *
+     * Returned status (from utils/Errors.h) can be:
+     *  - NO_ERROR: successful operation
+     *  - INVALID_OPERATION: the application does not have control of the effect engine
+     */
+             status_t    disable();
+
+             bool        isEnabled() const;
+
+    /* Sets a parameter value.
+     *
+     * Parameters:
+     *      param:  pointer to effect_param_t structure containing the parameter
+     *          and its value (See EffectApi.h).
+     * Returned status (from utils/Errors.h) can be:
+     *  - NO_ERROR: successful operation.
+     *  - INVALID_OPERATION: the application does not have control of the effect engine.
+     *  - BAD_VALUE: invalid parameter identifier or value.
+     *  - DEAD_OBJECT: the effect engine has been deleted.
+     */
+             status_t   setParameter(effect_param_t *param);
+
+    /* Prepare a new parameter value that will be set by next call to
+     * setParameterCommit(). This method can be used to set multiple parameters
+     * in a synchronous manner or to avoid multiple binder calls for each
+     * parameter.
+     *
+     * Parameters:
+     *      param:  pointer to effect_param_t structure containing the parameter
+     *          and its value (See EffectApi.h).
+     *
+     * Returned status (from utils/Errors.h) can be:
+     *  - NO_ERROR: successful operation.
+     *  - INVALID_OPERATION: the application does not have control of the effect engine.
+     *  - NO_MEMORY: no more space available in shared memory used for deferred parameter
+     *  setting.
+     */
+             status_t   setParameterDeferred(effect_param_t *param);
+
+     /* Commit all parameter values previously prepared by setParameterDeferred().
+      *
+      * Parameters:
+      *     none
+      *
+      * Returned status (from utils/Errors.h) can be:
+      *  - NO_ERROR: successful operation.
+      *  - INVALID_OPERATION: No new parameter values ready for commit.
+      *  - BAD_VALUE: invalid parameter identifier or value: there is no indication
+      *     as to which of the parameters caused this error.
+      *  - DEAD_OBJECT: the effect engine has been deleted.
+      */
+             status_t   setParameterCommit();
+
+    /* Gets a parameter value.
+     *
+     * Parameters:
+     *      param:  pointer to effect_param_t structure containing the parameter
+     *          and the returned value (See EffectApi.h).
+     *
+     * Returned status (from utils/Errors.h) can be:
+     *  - NO_ERROR: successful operation.
+     *  - INVALID_OPERATION: the AudioEffect was not successfully initialized.
+     *  - BAD_VALUE: invalid parameter identifier.
+     *  - DEAD_OBJECT: the effect engine has been deleted.
+     */
+             status_t   getParameter(effect_param_t *param);
+
+     /* Sends a command and receives a response to/from effect engine.
+      *     See EffectApi.h for details on effect command() function, valid command codes
+      *     and formats.
+      */
+             status_t command(int32_t cmdCode, int32_t cmdSize, void *cmdData, int32_t *replySize, void *replyData);
+
+
+     /*
+      * Utility functions.
+      */
+
+     /* Converts the string passed as first argument to the effect_uuid_t
+      * pointed to by second argument
+      */
+     static status_t stringToGuid(const char *str, effect_uuid_t *guid);
+     /* Converts the effect_uuid_t pointed to by first argument to the
+      * string passed as second argument
+      */
+     static status_t guidToString(const effect_uuid_t *guid, char *str, size_t maxLen);
+
+private:
+
+     // Implements the IEffectClient interface
+    class EffectClient : public android::BnEffectClient,  public android::IBinder::DeathRecipient
+    {
+    public:
+
+        EffectClient(AudioEffect *effect) : mEffect(effect){}
+
+        // IEffectClient
+        virtual void controlStatusChanged(bool controlGranted) {mEffect->controlStatusChanged(controlGranted);}
+        virtual void enableStatusChanged(bool enabled) {mEffect->enableStatusChanged(enabled);}
+        virtual void commandExecuted(int cmdCode, int cmdSize, void *pCmdData, int replySize, void *pReplyData) {
+            mEffect->commandExecuted(cmdCode, cmdSize, pCmdData, replySize, pReplyData);
+        }
+
+        // IBinder::DeathRecipient
+        virtual void binderDied(const wp<IBinder>& who) {mEffect->binderDied();}
+
+    private:
+        AudioEffect *mEffect;
+    };
+
+
+    friend class EffectClient;
+
+    // IEffectClient
+    void controlStatusChanged(bool controlGranted);
+    void enableStatusChanged(bool enabled);
+    void commandExecuted(int cmdCode, int cmdSize, void *pCmdData, int replySize, void *pReplyData);
+    void binderDied();
+
+
+    sp<IEffect>             mIEffect;           // IEffect binder interface
+    sp<EffectClient>        mIEffectClient;     // IEffectClient implementation
+    sp<IMemory>             mCblkMemory;        // shared memory for deferred parameter setting
+    effect_param_cblk_t*    mCblk;              // control block for deferred parameter setting
+    int32_t                 mPriority;          // priority for effect control
+    status_t                mStatus;            // effect status
+    volatile int32_t        mEnabled;           // enable state
+    effect_callback_t       mCbf;               // callback function for status, control, parameter changes notifications
+    void*                   mUserData;          // client context for callback function
+    effect_descriptor_t     mDescriptor;        // effect descriptor
+    int32_t                 mId;                // system wide unique effect engine instance identifier
+    int32_t                 mSessionId;         // audio session ID
+};
+
+
+}; // namespace android
+
+#endif // ANDROID_AUDIOEFFECT_H
diff --git a/media/java/android/media/AudioEffect.java b/media/java/android/media/AudioEffect.java
new file mode 100644
index 0000000..b1b7fed
--- /dev/null
+++ b/media/java/android/media/AudioEffect.java
@@ -0,0 +1,954 @@
+/*
+ * 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.
+ */
+
+package android.media;
+
+import android.util.Log;
+import java.lang.ref.WeakReference;
+import java.io.IOException;
+import android.os.Handler;
+import android.os.Looper;
+import android.os.Message;
+import java.nio.ByteOrder;
+import java.nio.ByteBuffer;
+import java.util.UUID;
+
+/**
+ * AudioEffect is the base class for implementing audio effect control in Java applications.
+ * Creating an AudioEffect object will create the effect engine in audio framework if no
+ * instance of the same effect type exists in the specified audio session.
+ * If one exists, this instance will be used. The application creating the AudioEffect object
+ * (or a derived class) will either receive control of the effect engine or not depending
+ * on the priority parameter. If priority is higher than the priority used by the current
+ * effect engine owner, the control will be transfered to the new object. Otherwise
+ * control will remain with the previous object. In this case, the new application will be
+ * notified of changes in effect engine state or control ownership by the appropiate listener.
+ * If the effect is to be applied to a specific AudioTrack or MediaPlayer instance,
+ * the application must specify the audio session ID of that instance.
+ *
+ * {@hide Pending API council review}
+ */
+public class AudioEffect
+{
+    static {
+        System.loadLibrary("audioeffect_jni");
+        native_init();
+    }
+
+    private final static String TAG = "AudioEffect-JAVA";
+
+    /**
+     * The following UUIDs define effect types corresponding to standard audio effects
+     * whose implementation and interface conform to the OpenSL ES specification.
+     * The definitions match the corresponding interface IDs in OpenSLES_IID.h
+     */
+    public static final UUID EFFECT_TYPE_ENV_REVERB = UUID.fromString("c2e5d5f0-94bd-4763-9cac-4e234d06839e");
+    public static final UUID EFFECT_TYPE_PRESET_REVERB = UUID.fromString("47382d60-ddd8-11db-bf3a-0002a5d5c51b");
+    public static final UUID EFFECT_TYPE_EQUALIZER = UUID.fromString("0bed4300-ddd6-11db-8f34-0002a5d5c51b");
+    public static final UUID EFFECT_TYPE_BASS_BOOST = UUID.fromString("0634f220-ddd4-11db-a0fc-0002a5d5c51b");
+    public static final UUID EFFECT_TYPE_VIRTUALIZER = UUID.fromString("37cc2c00-dddd-11db-8577-0002a5d5c51b");
+
+    public static final UUID EFFECT_TYPE_INVALID = UUID.fromString("ec7178ec-e5e1-4432-a3f4-4657e6795210");
+
+    /**
+     * State of an AudioEffect object that was not successfully initialized upon creation
+     */
+    public static final int STATE_UNINITIALIZED = 0;
+    /**
+     * State of an AudioEffect object that is ready to be used.
+     */
+    public static final int STATE_INITIALIZED   = 1;
+
+    /**
+     * Event id for engine state change notification.
+     */
+    protected static final int NATIVE_EVENT_ENABLED_STATUS  = 0;
+    /**
+     * Event id for engine control ownership change notification.
+     */
+    protected static final int NATIVE_EVENT_CONTROL_STATUS = 1;
+    /**
+     * Event id for engine parameter change notification.
+     */
+    protected static final int NATIVE_EVENT_PARAMETER_CHANGED = 2;
+
+
+    // to keep in sync with frameworks/base/media/jni/audioeffect/android_media_AudioEffect.cpp
+    public  static final int SUCCESS              = 0;
+    public  static final int ERROR                = -1;
+    public  static final int ALREADY_EXISTS       = -2;
+    public  static final int NO_INIT              = -3;
+    public  static final int BAD_VALUE            = -4;
+    public  static final int INVALID_OPERATION    = -5;
+    public  static final int NO_MEMORY            = -6;
+    public  static final int DEAD_OBJECT          = -7;
+
+
+     /**
+      * The effect descriptor contains necessary information to facilitate
+      * effects enumeration:
+      * mType: UUID corresponding to the OpenSL ES interface implemented by this effect
+      * mUuid: UUID for this particular implementation
+      * mConnectMode: {@link #EFFECT_INSERT} or {@link #EFFECT_AUXILIARY}
+      * mName: human readable effect name
+      * mImplementor: human readable effect implementor name
+      */
+     public static class Descriptor {
+
+         public Descriptor() {
+         }
+         public Descriptor(String type,
+                           String uuid,
+                           String connectMode,
+                           String name,
+                           String implementor) {
+             mType = UUID.fromString(type);
+             mUuid = UUID.fromString(uuid);
+             mConnectMode = connectMode;
+             mName = name;
+             mImplementor = implementor;
+         }
+
+         public UUID mType;
+         public UUID mUuid;
+         public String mConnectMode;
+         public String mName;
+         public String mImplementor;
+     };
+
+     public static final String EFFECT_INSERT = "Insert";
+     public static final String EFFECT_AUXILIARY = "Auxiliary";
+
+    //--------------------------------------------------------------------------
+    // Member variables
+    //--------------------
+    /**
+     * Indicates the state of the AudioEffect instance
+     */
+    protected int mState = STATE_UNINITIALIZED;
+    /**
+     * Lock to synchronize access to mState
+     */
+    protected final Object mStateLock = new Object();
+    /**
+     * System wide unique effect ID
+     */
+    protected int mId;
+
+    // accessed by native methods
+    private int mNativeAudioEffect;
+    private int mJniData;
+
+    /**
+     * Effect descriptor
+     */
+    private Descriptor mDescriptor;
+
+    /**
+     * Listener for effect engine state change notifications.
+     *  @see #setEnableStatusListener(OnEnableStatusChangeListener)
+     */
+    protected OnEnableStatusChangeListener mEnableStatusChangeListener = null;
+    /**
+     * Listener for effect engine control ownership change notifications.
+     *  @see #setControlStatusListener(OnControlStatusChangeListener)
+     */
+    protected OnControlStatusChangeListener mControlChangeStatusListener = null;
+    /**
+     * Listener for effect engine control ownership change notifications.
+     *  @see #setParameterListener(OnParameterChangeListener)
+     */
+    protected OnParameterChangeListener mParameterChangeListener = null;
+    /**
+     * Lock to protect listeners updates against event notifications
+     */
+    protected final Object mListenerLock = new Object();
+    /**
+     * Handler for events coming from the native code
+     */
+    protected NativeEventHandler mNativeEventHandler = null;
+
+
+
+    //--------------------------------------------------------------------------
+    // Constructor, Finalize
+    //--------------------
+    /**
+     * Class constructor.
+     * @param type:  type of effect engine created. See
+     *   {@link #EFFECT_TYPE_ENV_REVERB}, {@link #EFFECT_TYPE_EQUALIZER} ...
+     *   Types corresponding to built-in effects are defined by AudioEffect class.
+     *   Other types can be specified provided they correspond an existing OpenSL ES
+     *   interface ID and the corresponsing effect is available on the platform.
+     *   If an unspecified effect type is requested, the constructor with throw the
+     *   IllegalArgumentException.
+     * @param uuid:  unique identifier of a particular effect implementation. Must be
+     *  specified if the caller wants to use a particular implementation of an effect type.
+     *  This parameter can be set to null in which case only the type will be used to select
+     *  the effect.
+     * @param priority:  the priority level requested by the application for controlling
+     *  the effect engine. As the same effect engine can be shared by several applications,
+     *  this parameter indicates how much the requesting application needs control of
+     *  effect parameters. The normal priority is 0, above normal is a positive number,
+     *  below normal a negative number.
+     * @param audioSession:  System wide unique audio session identifier. If audioSession
+     *  is not 0, the effect will be attached to the MediaPlayer or AudioTrack in the
+     *  same audio session. Otherwise, the effect will apply to the output mix.
+     *
+     * @throws java.lang.IllegalArgumentException
+     * @throws java.lang.UnsupportedOperationException
+     * @throws java.lang.RuntimeException
+     */
+
+    public AudioEffect(UUID type, UUID uuid, int priority, int audioSession)
+    throws IllegalArgumentException, UnsupportedOperationException, RuntimeException {
+        int[] id = new int[1];
+        Descriptor[] desc = new Descriptor[1];
+        // native initialization
+        int initResult = native_setup(new WeakReference<AudioEffect>(this),
+                type.toString(), uuid.toString(), priority, audioSession, id, desc);
+        if (initResult != SUCCESS && initResult != ALREADY_EXISTS) {
+            Log.e(TAG, "Error code "+initResult+" when initializing AudioEffect.");
+            switch (initResult) {
+            case BAD_VALUE:
+                throw (new IllegalArgumentException("Effect type: "+type+ " not supported."));
+            case INVALID_OPERATION:
+                throw (new UnsupportedOperationException("Effect library not loaded"));
+            default:
+                throw (new RuntimeException("Cannot initialize effect engine for type: "+type+
+                        "Error: "+ initResult));
+            }
+        }
+        mId = id[0];
+        mDescriptor = desc[0];
+        synchronized (mStateLock) {
+            mState = STATE_INITIALIZED;
+        }
+    }
+
+    /**
+     * Releases the native AudioEffect resources. It is a good practice to release the
+     * effect engine when not in use as control can be returned to other applications
+     * or the native resources released.
+     */
+    public void release() {
+        synchronized (mStateLock) {
+            native_release();
+            mState = STATE_UNINITIALIZED;
+        }
+    }
+
+    @Override
+    protected void finalize() {
+        native_finalize();
+    }
+
+    /**
+     * Get the effect descriptor.
+     * {@see #Descriptor}.
+     * @throws IllegalStateException
+     */
+    public Descriptor getDescriptor()
+    throws IllegalStateException {
+        checkState("getDescriptor()");
+        return mDescriptor;
+    }
+
+    //--------------------------------------------------------------------------
+    // Effects Enumeration
+    //--------------------
+
+    /**
+     * Query all effects available on the platform. Returns an array of
+     * {@link #Descriptor} objects
+     *
+     * @throws IllegalStateException
+     */
+
+    static public Descriptor[] queryEffects() {
+        return (Descriptor[])native_query_effects();
+    }
+
+    //--------------------------------------------------------------------------
+    // Control methods
+    //--------------------
+
+    /**
+     * Enable effect engine.
+     * @return {@link #NO_ERROR} in case of success,
+     * {@link #INVALID_OPERATION} or {@link #DEAD_OBJECT} in case of failure.
+     * @throws IllegalStateException
+     */
+    public int enable()
+    throws IllegalStateException {
+        checkState("enable()");
+        return native_enable();
+    }
+
+    /**
+     * Disable effect engine.
+     * @return NO_ERROR in case of success,
+     * INVALID_OPERATION or DEAD_OBJECT in case of failure.
+     * @throws IllegalStateException
+     */
+    public int disable()
+    throws IllegalStateException {
+        checkState("disable()");
+        return native_disable();
+    }
+
+    /**
+     * Set effect parameter. The setParameter method is provided in several
+     * forms addressing most common parameter formats. This form is the
+     * most generic one where the parameter and its value are both specified
+     * as an array of bytes. The parameter and value type and length are therefore
+     * totally free. For standard effect defined by OpenSL ES, the parameter format
+     * and values must match the definitions in the corresponding OpenSL ES interface.
+     *
+     * @param param:  the identifier of the parameter to set
+     * @param value:  the new value for the specified parameter
+     * @return NO_ERROR in case of success,
+     * {@link #BAD_VALUE}, {@link #NO_MEMORY}, {@link #INVALID_OPERATION} or {@link DEAD_OBJECT} in case of failure
+     * @throws IllegalStateException
+     */
+    public int setParameter(byte[] param, byte[] value)
+    throws IllegalStateException {
+        checkState("setParameter()");
+        return native_setParameter(param.length, param, value.length, value);
+    }
+
+    /**
+     * Set effect parameter. The parameter and its value are integers.
+     *  @see #setParameter(byte[], byte[])
+     */
+    public int setParameter(int param, int value)
+    throws IllegalStateException {
+        byte[] p = intToByteArray(param);
+        byte[] v = intToByteArray(value);
+        return setParameter(p, v);
+    }
+
+    /**
+     * Set effect parameter. The parameter is an integer and the value is a short integer.
+     *  @see #setParameter(byte[], byte[])
+     */
+    public int setParameter(int param, short value)
+    throws IllegalStateException {
+        byte[] p = intToByteArray(param);
+        byte[] v = shortToByteArray(value);
+        return setParameter(p, v);
+    }
+
+    /**
+     * Set effect parameter. The parameter is an integer and the value is an array of bytes.
+     *  @see #setParameter(byte[], byte[])
+     */
+    public int setParameter(int param, byte[] value)
+    throws IllegalStateException {
+        byte[] p = intToByteArray(param);
+        return setParameter(p, value);
+    }
+
+    /**
+     * Set effect parameter. The parameter is an array of 1 or 2 integers and the value
+     *  is also an array of 1 or 2 integers
+     *  @see #setParameter(byte[], byte[])
+     */
+    public int setParameter(int[] param, int[] value)
+    throws IllegalStateException {
+        if (param.length > 2 || value.length > 2) {
+            return BAD_VALUE;
+        }
+        byte[] p = intToByteArray(param[0]);
+        if (param.length > 1) {
+            byte[] p2 = intToByteArray(param[1]);
+            p = concatArrays(p, p2);
+        }
+        byte[] v = intToByteArray(value[0]);
+        if (value.length > 1) {
+            byte[] v2 = intToByteArray(value[1]);
+            v = concatArrays(v, v2);
+        }
+        return setParameter(p, v);
+    }
+
+    /**
+     * Set effect parameter. The parameter is an array of 1 or 2 integers and the value
+     *  is an array of 1 or 2 short integers
+     *  @see #setParameter(byte[], byte[])
+     */
+    public int setParameter(int[] param, short[] value)
+    throws IllegalStateException {
+        if (param.length > 2 || value.length > 2) {
+            return BAD_VALUE;
+        }
+        byte[] p = intToByteArray(param[0]);
+        if (param.length > 1) {
+            byte[] p2 = intToByteArray(param[1]);
+            p = concatArrays(p, p2);
+        }
+
+        byte[] v = shortToByteArray(value[0]);
+        if (value.length > 1) {
+            byte[] v2 = shortToByteArray(value[1]);
+            v = concatArrays(v, v2);
+        }
+        return setParameter(p, v);
+    }
+
+    /**
+     * Set effect parameter. The parameter is an array of 1 or 2 integers and the value
+     *  is an array of bytes
+     *  @see #setParameter(byte[], byte[])
+     */
+    public int setParameter(int[] param, byte[] value)
+    throws IllegalStateException {
+        if (param.length > 2) {
+            return BAD_VALUE;
+        }
+        byte[] p = intToByteArray(param[0]);
+        if (param.length > 1) {
+            byte[] p2 = intToByteArray(param[1]);
+            p = concatArrays(p, p2);
+        }
+        return setParameter(p, value);
+    }
+
+    /**
+     * Get effect parameter. The getParameter method is provided in several
+     * forms addressing most common parameter formats. This form is the
+     * most generic one where the parameter and its value are both specified
+     * as an array of bytes. The parameter and value type and length are therefore
+     * totally free.
+     * @param param:  the identifier of the parameter to set
+     * @param value:  the new value for the specified parameter
+     * @return NO_ERROR in case of success,
+     * {@link #BAD_VALUE}, {@link #NO_MEMORY}, {@link #INVALID_OPERATION} or {@link DEAD_OBJECT} in case of failure
+     * When called, value.length indicates the maximum size of the returned parameters value.
+     * When returning, value.length is updated with the actual size of the returned value.
+     * @throws IllegalStateException
+     */
+    public int getParameter(byte[] param, byte[] value)
+    throws IllegalStateException {
+        checkState("getParameter()");
+        int[] vSize = new int[1];
+        vSize[0] = value.length;
+        int status = native_getParameter(param.length, param, vSize, value);
+        if (value.length > vSize[0]) {
+            byte[] resizedValue = new byte[vSize[0]];
+            System.arraycopy(value, 0, resizedValue, 0, vSize[0]);
+            value = resizedValue;
+        }
+        return status;
+    }
+
+    /**
+     * Get effect parameter. The parameter is an integer and the value is an array of bytes.
+     *  @see #getParameter(byte[], byte[])
+     */
+    public int getParameter(int param, byte[] value)
+    throws IllegalStateException {
+        byte[] p = intToByteArray(param);
+
+        return getParameter(p, value);
+    }
+
+    /**
+     * Get effect parameter. The parameter is an integer and the value
+     *  is an array of 1 or 2 integers
+     *  @see #getParameter(byte[], byte[])
+     */
+    public int getParameter(int param, int[] value)
+    throws IllegalStateException {
+        if (value.length > 2) {
+            return BAD_VALUE;
+        }
+        byte[] p = intToByteArray(param);
+
+        byte[] v = new byte[value.length * 4];
+
+        int status = getParameter(p, v);
+
+        value[0] = byteArrayToInt(v);
+        if (v.length > 4) {
+            value[1] = byteArrayToInt(v, 4);
+        }
+        return status;
+    }
+
+    /**
+     * Get effect parameter. The parameter is an integer and the value
+     *  is an array of 1 or 2 short integers
+     *  @see #getParameter(byte[], byte[])
+     */
+    public int getParameter(int param, short[] value)
+    throws IllegalStateException {
+        if (value.length > 2) {
+            return BAD_VALUE;
+        }
+        byte[] p = intToByteArray(param);
+
+        byte[] v = new byte[value.length * 2];
+
+        int status = getParameter(p, v);
+
+        value[0] = byteArrayToShort(v);
+        if (v.length > 2) {
+            value[1] = byteArrayToShort(v, 2);
+        }
+        return status;
+    }
+
+    /**
+     * Get effect parameter. The parameter is an array of 1 or 2 integers and the value
+     *  is also an array of 1 or 2 integers
+     *  @see #getParameter(byte[], byte[])
+     */
+    public int getParameter(int[] param, int[] value)
+    throws IllegalStateException {
+        if (param.length > 2 || value.length > 2) {
+            return BAD_VALUE;
+        }
+        byte[] p = intToByteArray(param[0]);
+        if (param.length > 1) {
+            byte[] p2 = intToByteArray(param[1]);
+            p = concatArrays(p, p2);
+        }
+        byte[] v = new byte[value.length * 4];
+
+        int status = getParameter(p, v);
+
+        value[0] = byteArrayToInt(v);
+        if (v.length > 4) {
+            value[1] = byteArrayToInt(v, 4);
+        }
+        return status;
+    }
+
+    /**
+     * Get effect parameter. The parameter is an array of 1 or 2 integers and the value
+     *  is an array of 1 or 2 short integers
+     *  @see #getParameter(byte[], byte[])
+     */
+    public int getParameter(int[] param, short[] value)
+    throws IllegalStateException {
+        if (param.length > 2 || value.length > 2) {
+            return BAD_VALUE;
+        }
+        byte[] p = intToByteArray(param[0]);
+        if (param.length > 1) {
+            byte[] p2 = intToByteArray(param[1]);
+            p = concatArrays(p, p2);
+        }
+        byte[] v = new byte[value.length * 2];
+
+        int status = getParameter(p, v);
+
+        value[0] = byteArrayToShort(v);
+        if (v.length > 2) {
+            value[1] = byteArrayToShort(v, 2);
+        }
+        return status;
+    }
+
+    /**
+     * Get effect parameter. The parameter is an array of 1 or 2 integers and the value
+     *  is an array of bytes
+     *  @see #getParameter(byte[], byte[])
+     */
+    public int getParameter(int[] param, byte[] value)
+    throws IllegalStateException {
+        if (param.length > 2) {
+            return BAD_VALUE;
+        }
+        byte[] p = intToByteArray(param[0]);
+        if (param.length > 1) {
+            byte[] p2 = intToByteArray(param[1]);
+            p = concatArrays(p, p2);
+        }
+
+        return getParameter(p, value);
+    }
+
+
+    /**
+     * Send a command to the effect engine. This method is intended to send proprietary
+     * commands to a particular effect implementation.
+     *
+     */
+    public int command(int cmdCode, byte[] command, byte[] reply)
+    throws IllegalStateException {
+        checkState("command()");
+        int[] replySize = new int[1];
+        replySize[0] = reply.length;
+
+        int status = native_command(cmdCode, command.length, command, replySize, reply);
+
+        if (reply.length > replySize[0]) {
+            byte[] resizedReply = new byte[replySize[0]];
+            System.arraycopy(reply, 0, resizedReply, 0, replySize[0]);
+            reply = resizedReply;
+        }
+        return status;
+    }
+
+    //--------------------------------------------------------------------------
+    // Getters
+    //--------------------
+
+    /**
+     * Returns effect unique identifier. This system wide unique identifier
+     * can be used to attach this effect to a MediaPlayer or an AudioTrack
+     * when the effect is an auxiliary effect (Reverb)
+     * @return the effect identifier.
+     * @throws IllegalStateException
+     */
+    public int getId()
+    throws IllegalStateException {
+        checkState("getId()");
+        return mId;
+    }
+
+    /**
+     * Returns effect engine enable state
+     * @return true if the effect is enabled, false otherwise.
+     * @throws IllegalStateException
+     */
+    public boolean getEnable()
+    throws IllegalStateException {
+        checkState("getEnable()");
+        return native_getEnable();
+    }
+
+    /**
+     * Checks if this AudioEffect object is controlling the effect engine.
+     * @return true if this instance has control of effect engine, false otherwise.
+     * @throws IllegalStateException
+     */
+    public boolean hasControl()
+    throws IllegalStateException {
+        checkState("hasControl()");
+        return native_hasControl();
+    }
+
+    //--------------------------------------------------------------------------
+    // Initialization / configuration
+    //--------------------
+    /**
+     * Sets the listener AudioEffect notifies when the effect engine is enabled
+     * or disabled.
+     * @param listener
+     */
+    public void setEnableStatusListener(OnEnableStatusChangeListener listener) {
+        synchronized (mListenerLock) {
+            mEnableStatusChangeListener = listener;
+        }
+        if ((listener != null) && (mNativeEventHandler == null)) {
+            createNativeEventHandler();
+        }
+    }
+
+    /**
+     * Sets the listener AudioEffect notifies when the effect engine control
+     * is taken or returned.
+     * @param listener
+     */
+    public void setControlStatusListener(OnControlStatusChangeListener listener) {
+        synchronized (mListenerLock) {
+            mControlChangeStatusListener = listener;
+        }
+        if ((listener != null) && (mNativeEventHandler == null)) {
+            createNativeEventHandler();
+        }
+    }
+
+    /**
+     * Sets the listener AudioEffect notifies when a parameter is changed.
+     * @param listener
+     */
+    public void setParameterListener(OnParameterChangeListener listener) {
+        synchronized (mListenerLock) {
+            mParameterChangeListener = listener;
+        }
+        if ((listener != null) && (mNativeEventHandler == null)) {
+            createNativeEventHandler();
+        }
+    }
+
+    // Convenience method for the creation of the native event handler
+    // It is called only when a non-null event listener is set.
+    // precondition:
+    //    mNativeEventHandler is null
+    private void createNativeEventHandler() {
+        Looper looper;
+        if ((looper = Looper.myLooper()) != null) {
+            mNativeEventHandler = new NativeEventHandler(this, looper);
+        } else if ((looper = Looper.getMainLooper()) != null) {
+            mNativeEventHandler = new NativeEventHandler(this, looper);
+        } else {
+            mNativeEventHandler = null;
+        }
+    }
+
+    //---------------------------------------------------------
+    // Interface definitions
+    //--------------------
+    /**
+     * Interface definition for a callback to be invoked when the
+     * effect engine is enabled or disabled.
+     */
+    public interface OnEnableStatusChangeListener  {
+        /**
+         * Called on the listener to notify it that the effect engine
+         * has been enabled or disabled.
+         */
+        void onEnableStatusChange(AudioEffect effect, boolean enabled);
+    }
+
+    /**
+     * Interface definition for a callback to be invoked when the
+     * effect engine control is taken or returned.
+     */
+    public interface OnControlStatusChangeListener  {
+        /**
+         * Called on the listener to notify it that the effect engine
+         * control has been taken or returned.
+         */
+        void onControlStatusChange(AudioEffect effect, boolean controlGranted);
+    }
+
+    /**
+     * Interface definition for a callback to be invoked when a
+     * parameter value has changed.
+     */
+    public interface OnParameterChangeListener  {
+        /**
+         * Called on the listener to notify it that a parameter value has changed.
+         */
+        void onParameterChange(AudioEffect effect, int status, byte[] param, byte[] value);
+    }
+
+    //---------------------------------------------------------
+    // Inner classes
+    //--------------------
+    /**
+     * Helper class to handle the forwarding of native events to the appropriate listeners
+     */
+    private class NativeEventHandler extends Handler
+    {
+        private AudioEffect mAudioEffect;
+
+        public NativeEventHandler(AudioEffect ae, Looper looper) {
+            super(looper);
+            mAudioEffect = ae;
+        }
+
+        @Override
+        public void handleMessage(Message msg) {
+            if (mAudioEffect == null) {
+                return;
+            }
+            switch(msg.what) {
+            case NATIVE_EVENT_ENABLED_STATUS:
+                OnEnableStatusChangeListener enableStatusChangeListener = null;
+                synchronized (mListenerLock) {
+                    enableStatusChangeListener = mAudioEffect.mEnableStatusChangeListener;
+                }
+                if (enableStatusChangeListener != null) {
+                    enableStatusChangeListener.onEnableStatusChange(mAudioEffect, (boolean)(msg.arg1 != 0));
+                }
+                break;
+            case NATIVE_EVENT_CONTROL_STATUS:
+                OnControlStatusChangeListener controlStatusChangeListener = null;
+                synchronized (mListenerLock) {
+                    controlStatusChangeListener = mAudioEffect.mControlChangeStatusListener;
+                }
+                if (controlStatusChangeListener != null) {
+                    controlStatusChangeListener.onControlStatusChange(mAudioEffect, (boolean)(msg.arg1 != 0));
+                }
+                break;
+            case NATIVE_EVENT_PARAMETER_CHANGED:
+                OnParameterChangeListener parameterChangeListener = null;
+                synchronized (mListenerLock) {
+                    parameterChangeListener = mAudioEffect.mParameterChangeListener;
+                }
+                if (parameterChangeListener != null) {
+                    // arg1 contains offset of parameter value from start of byte array
+                    int vOffset = msg.arg1;
+                    byte[] p = (byte[])msg.obj;
+                    // See effect_param_t in EffectApi.h for psize and vsize fields offsets
+                    int status = byteArrayToInt(p, 0);
+                    int psize = byteArrayToInt(p, 4);
+                    int vsize = byteArrayToInt(p, 8);
+                    byte[] param = new byte[psize];
+                    byte[] value = new byte[vsize];
+                    System.arraycopy(p, 12, param, 0, psize);
+                    System.arraycopy(p, vOffset, value, 0, vsize);
+
+                    parameterChangeListener.onParameterChange(mAudioEffect, status, param, value);
+                }
+                break;
+
+             default:
+                Log.e(TAG, "handleMessage() Unknown event type: " + msg.what);
+                break;
+            }
+        }
+    }
+
+
+    //---------------------------------------------------------
+    // Java methods called from the native side
+    //--------------------
+    @SuppressWarnings("unused")
+    private static void postEventFromNative(Object effect_ref,
+            int what, int arg1, int arg2, Object obj) {
+        AudioEffect effect = (AudioEffect)((WeakReference)effect_ref).get();
+        if (effect == null) {
+            return;
+        }
+
+        if (effect.mNativeEventHandler != null) {
+            Message m = effect.mNativeEventHandler.obtainMessage(what, arg1, arg2, obj);
+            effect.mNativeEventHandler.sendMessage(m);
+        }
+
+    }
+
+
+    //---------------------------------------------------------
+    // Native methods called from the Java side
+    //--------------------
+
+    private static native final void native_init();
+
+    private native final int native_setup(Object audioeffect_this,
+                                          String type,
+                                          String uuid,
+                                          int priority,
+                                          int audioSession,
+                                          int[] id,
+                                          Object[] desc);
+
+    private native final void native_finalize();
+
+    private native final void native_release();
+
+    private native final int native_enable();
+
+    private native final int native_disable();
+
+    private native final boolean native_getEnable();
+
+    private native final boolean native_hasControl();
+
+    private native final int native_setParameter(int psize,
+                                                 byte[] param,
+                                                 int vsize,
+                                                 byte[] value);
+
+    private native final int native_getParameter(int psize,
+                                                 byte[] param,
+                                                 int[] vsize,
+                                                 byte[] value);
+
+    private native final int native_command(int cmdCode,
+                                            int cmdSize,
+                                            byte[] cmdData,
+                                            int[] repSize,
+                                            byte[] repData);
+
+    private static native Object[] native_query_effects();
+
+    //---------------------------------------------------------
+    // Utility methods
+    //------------------
+
+    protected void checkState(String methodName)
+        throws IllegalStateException {
+        synchronized (mStateLock) {
+            if (mState != STATE_INITIALIZED) {
+                throw(new IllegalStateException(methodName+" called on uninitialized AudioEffect."));
+            }
+        }
+    }
+
+    protected void checkStatus(int status) {
+        switch (status) {
+        case AudioEffect.SUCCESS:
+            break;
+        case AudioEffect.BAD_VALUE:
+            throw (new IllegalArgumentException("AudioEffect: bad parameter value"));
+        case AudioEffect.INVALID_OPERATION:
+            throw (new UnsupportedOperationException("AudioEffect: invalid parameter operation"));
+        default:
+            throw (new RuntimeException("AudioEffect: set/get parameter error"));
+        }
+    }
+
+    protected int byteArrayToInt(byte[] valueBuf) {
+        return byteArrayToInt(valueBuf, 0);
+
+    }
+    protected int byteArrayToInt(byte[] valueBuf, int offset) {
+        ByteBuffer converter = ByteBuffer.wrap(valueBuf);
+        converter.order(ByteOrder.nativeOrder());
+        return converter.getInt(offset);
+
+    }
+
+    protected byte[] intToByteArray(int value) {
+        ByteBuffer converter = ByteBuffer.allocate(4);
+        converter.order(ByteOrder.nativeOrder());
+        converter.putInt(value);
+        return converter.array();
+    }
+
+    protected short byteArrayToShort(byte[] valueBuf) {
+        return byteArrayToShort(valueBuf, 0);
+    }
+
+    protected short byteArrayToShort(byte[] valueBuf, int offset) {
+        ByteBuffer converter = ByteBuffer.wrap(valueBuf);
+        converter.order(ByteOrder.nativeOrder());
+        return converter.getShort(offset);
+
+    }
+
+    protected byte[] shortToByteArray(short value) {
+        ByteBuffer converter = ByteBuffer.allocate(2);
+        converter.order(ByteOrder.nativeOrder());
+        short sValue = (short)value;
+        converter.putShort(sValue);
+        return converter.array();
+    }
+
+    protected byte[] concatArrays(byte[] ...arrays) {
+        int len = 0;
+        for (byte[] a : arrays) {
+            len += a.length;
+        }
+        byte[] b = new byte[len];
+
+        int offs = 0;
+        for (byte[] a : arrays) {
+            System.arraycopy(a, 0, b, offs, a.length);
+            offs += a.length;
+        }
+        return b;
+    }
+
+}
diff --git a/media/jni/Android.mk b/media/jni/Android.mk
index a6a25cd..698cece 100644
--- a/media/jni/Android.mk
+++ b/media/jni/Android.mk
@@ -65,4 +65,5 @@
 include $(BUILD_SHARED_LIBRARY)
 
 # build libsoundpool.so
-include $(LOCAL_PATH)/soundpool/Android.mk
+# build libaudioeffect_jni.so
+include $(call all-makefiles-under,$(LOCAL_PATH))
diff --git a/media/jni/audioeffect/Android.mk b/media/jni/audioeffect/Android.mk
new file mode 100644
index 0000000..d03b63b
--- /dev/null
+++ b/media/jni/audioeffect/Android.mk
@@ -0,0 +1,16 @@
+LOCAL_PATH:= $(call my-dir)
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES:= \
+	android_media_AudioEffect.cpp
+
+LOCAL_SHARED_LIBRARIES := \
+	libcutils \
+	libutils \
+	libandroid_runtime \
+	libnativehelper \
+	libmedia
+
+LOCAL_MODULE:= libaudioeffect_jni
+
+include $(BUILD_SHARED_LIBRARY)
diff --git a/media/jni/audioeffect/android_media_AudioEffect.cpp b/media/jni/audioeffect/android_media_AudioEffect.cpp
new file mode 100644
index 0000000..de01dd3
--- /dev/null
+++ b/media/jni/audioeffect/android_media_AudioEffect.cpp
@@ -0,0 +1,861 @@
+/*
+ * 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.
+ */
+
+#include <stdio.h>
+
+//#define LOG_NDEBUG 0
+#define LOG_TAG "AudioEffects-JNI"
+
+#include <utils/Log.h>
+#include <nativehelper/jni.h>
+#include <nativehelper/JNIHelp.h>
+#include <android_runtime/AndroidRuntime.h>
+#include "media/AudioEffect.h"
+
+using namespace android;
+
+#define AUDIOEFFECT_SUCCESS                      0
+#define AUDIOEFFECT_ERROR                       -1
+#define AUDIOEFFECT_ERROR_ALREADY_EXISTS        -2
+#define AUDIOEFFECT_ERROR_NO_INIT               -3
+#define AUDIOEFFECT_ERROR_BAD_VALUE             -4
+#define AUDIOEFFECT_ERROR_INVALID_OPERATION     -5
+#define AUDIOEFFECT_ERROR_NO_MEMORY             -6
+#define AUDIOEFFECT_ERROR_DEAD_OBJECT           -7
+
+// ----------------------------------------------------------------------------
+static const char* const kClassPathName = "android/media/AudioEffect";
+
+struct fields_t {
+    // these fields provide access from C++ to the...
+    jclass    clazzEffect;          // AudioEffect class
+    jmethodID midPostNativeEvent;   // event post callback method
+    jfieldID  fidNativeAudioEffect; // stores in Java the native AudioEffect object
+    jfieldID  fidJniData;           // stores in Java additional resources used by the native AudioEffect
+    jclass    clazzDesc;            // AudioEffect.Descriptor class
+    jmethodID midDescCstor;         // AudioEffect.Descriptor class constructor
+};
+static fields_t fields;
+
+struct effect_callback_cookie {
+    jclass      audioEffect_class;  // AudioEffect class
+    jobject     audioEffect_ref;    // AudioEffect object instance
+ };
+
+// ----------------------------------------------------------------------------
+class AudioEffectJniStorage {
+    public:
+        effect_callback_cookie mCallbackData;
+
+    AudioEffectJniStorage() {
+    }
+
+    ~AudioEffectJniStorage() {
+    }
+
+};
+
+
+static jint translateError(int code) {
+    switch(code) {
+    case NO_ERROR:
+        return AUDIOEFFECT_SUCCESS;
+    case ALREADY_EXISTS:
+        return AUDIOEFFECT_ERROR_ALREADY_EXISTS;
+    case NO_INIT:
+        return AUDIOEFFECT_ERROR_NO_INIT;
+    case BAD_VALUE:
+        return AUDIOEFFECT_ERROR_BAD_VALUE;
+    case INVALID_OPERATION:
+        return AUDIOEFFECT_ERROR_INVALID_OPERATION;
+    case NO_MEMORY:
+        return AUDIOEFFECT_ERROR_NO_MEMORY;
+    case DEAD_OBJECT:
+        return AUDIOEFFECT_ERROR_DEAD_OBJECT;
+    default:
+        return AUDIOEFFECT_ERROR;
+    }
+}
+
+
+// ----------------------------------------------------------------------------
+static void effectCallback(int event, void* user, void *info) {
+
+    effect_param_t *p;
+    int arg1 = 0;
+    int arg2 = 0;
+    jobject obj = NULL;
+    jbyteArray array = NULL;
+    jbyte *bytes;
+    bool param;
+    size_t size;
+
+    effect_callback_cookie *callbackInfo = (effect_callback_cookie *)user;
+    JNIEnv *env = AndroidRuntime::getJNIEnv();
+
+    LOGV("effectCallback: callbackInfo %p, audioEffect_ref %p audioEffect_class %p",
+            callbackInfo,
+            callbackInfo->audioEffect_ref,
+            callbackInfo->audioEffect_class);
+
+    if (!user || !env) {
+        LOGW("effectCallback error user %p, env %p", user, env);
+        return;
+    }
+
+    switch (event) {
+    case AudioEffect::EVENT_CONTROL_STATUS_CHANGED:
+        if (info == 0) {
+            LOGW("EVENT_CONTROL_STATUS_CHANGED info == NULL");
+            goto effectCallback_Exit;
+        }
+        param = *(bool *)info;
+        arg1 = (int)param;
+        LOGV("EVENT_CONTROL_STATUS_CHANGED");
+        break;
+    case AudioEffect::EVENT_ENABLE_STATUS_CHANGED:
+        if (info == 0) {
+            LOGW("EVENT_ENABLE_STATUS_CHANGED info == NULL");
+            goto effectCallback_Exit;
+        }
+        param = *(bool *)info;
+        arg1 = (int)param;
+        LOGV("EVENT_ENABLE_STATUS_CHANGED");
+        break;
+    case AudioEffect::EVENT_PARAMETER_CHANGED:
+        if (info == 0) {
+            LOGW("EVENT_PARAMETER_CHANGED info == NULL");
+            goto effectCallback_Exit;
+        }
+        p = (effect_param_t *)info;
+        if (p->psize == 0 || p->vsize == 0) {
+            goto effectCallback_Exit;
+        }
+        // arg1 contains offset of parameter value from start of byte array
+        arg1 = sizeof(effect_param_t) + ((p->psize - 1) / sizeof(int) + 1) * sizeof(int);
+        size = arg1 + p->vsize;
+        array = env->NewByteArray(size);
+        if (array == NULL) {
+            LOGE("effectCallback: Couldn't allocate byte array for parameter data");
+            goto effectCallback_Exit;
+        }
+        bytes = env->GetByteArrayElements(array, NULL);
+        memcpy(bytes, p, size);
+        env->ReleaseByteArrayElements(array, bytes, 0);
+        obj = array;
+        LOGV("EVENT_PARAMETER_CHANGED");
+       break;
+    case AudioEffect::EVENT_ERROR:
+        LOGW("EVENT_ERROR");
+        break;
+    }
+
+    env->CallStaticVoidMethod(
+        callbackInfo->audioEffect_class,
+        fields.midPostNativeEvent,
+        callbackInfo->audioEffect_ref, event, arg1, arg2, obj);
+
+effectCallback_Exit:
+    if (array) {
+        env->DeleteLocalRef(array);
+    }
+
+    if (env->ExceptionCheck()) {
+        env->ExceptionDescribe();
+        env->ExceptionClear();
+    }
+}
+
+// ----------------------------------------------------------------------------
+// This function gets some field IDs, which in turn causes class initialization.
+// It is called from a static block in AudioEffect, which won't run until the
+// first time an instance of this class is used.
+static void
+android_media_AudioEffect_native_init(JNIEnv *env)
+{
+
+    LOGV("android_media_AudioEffect_native_init");
+
+    fields.clazzEffect = NULL;
+    fields.clazzDesc = NULL;
+
+    // Get the AudioEffect class
+    jclass clazz = env->FindClass(kClassPathName);
+    if (clazz == NULL) {
+        LOGE("Can't find %s", kClassPathName);
+        return;
+    }
+
+    fields.clazzEffect = (jclass)env->NewGlobalRef(clazz);
+
+    // Get the postEvent method
+    fields.midPostNativeEvent = env->GetStaticMethodID(
+            fields.clazzEffect,
+            "postEventFromNative", "(Ljava/lang/Object;IIILjava/lang/Object;)V");
+    if (fields.midPostNativeEvent == NULL) {
+        LOGE("Can't find AudioEffect.%s", "postEventFromNative");
+        return;
+    }
+
+    // Get the variables fields
+    //      nativeTrackInJavaObj
+    fields.fidNativeAudioEffect = env->GetFieldID(
+            fields.clazzEffect,
+            "mNativeAudioEffect", "I");
+    if (fields.fidNativeAudioEffect == NULL) {
+        LOGE("Can't find AudioEffect.%s", "mNativeAudioEffect");
+        return;
+    }
+    //      fidJniData;
+    fields.fidJniData = env->GetFieldID(
+            fields.clazzEffect,
+            "mJniData", "I");
+    if (fields.fidJniData == NULL) {
+        LOGE("Can't find AudioEffect.%s", "mJniData");
+        return;
+    }
+
+    clazz = env->FindClass("android/media/AudioEffect$Descriptor");
+    if (clazz == NULL) {
+        LOGE("Can't find android/media/AudioEffect$Descriptor class");
+        return;
+    }
+    fields.clazzDesc = (jclass)env->NewGlobalRef(clazz);
+
+    fields.midDescCstor
+            = env->GetMethodID(
+                    fields.clazzDesc,
+                    "<init>",
+                    "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V");
+    if (fields.midDescCstor == NULL) {
+        LOGE("Can't find android/media/AudioEffect$Descriptor class constructor");
+        return;
+    }
+}
+
+
+static jint
+android_media_AudioEffect_native_setup(JNIEnv *env, jobject thiz, jobject weak_this,
+        jstring type, jstring uuid, jint priority, jint sessionId, jintArray jId, jobjectArray javadesc)
+{
+    LOGV("android_media_AudioEffect_native_setup");
+    AudioEffectJniStorage* lpJniStorage = NULL;
+    int lStatus = AUDIOEFFECT_ERROR_NO_MEMORY;
+    AudioEffect* lpAudioEffect = NULL;
+    jint* nId = NULL;
+    const char *typeStr = NULL;
+    const char *uuidStr = NULL;
+    effect_descriptor_t desc;
+    jobject jdesc;
+    char str[EFFECT_STRING_LEN_MAX];
+    jstring jdescType;
+    jstring jdescUuid;
+    jstring jdescConnect;
+    jstring jdescName;
+    jstring jdescImplementor;
+
+    if (type != NULL) {
+        typeStr = env->GetStringUTFChars(type, NULL);
+        if (typeStr == NULL) {  // Out of memory
+            jniThrowException(env, "java/lang/RuntimeException", "Out of memory");
+            goto setup_failure;
+        }
+    }
+
+    if (uuid != NULL) {
+        uuidStr = env->GetStringUTFChars(uuid, NULL);
+        if (uuidStr == NULL) {  // Out of memory
+            jniThrowException(env, "java/lang/RuntimeException", "Out of memory");
+            goto setup_failure;
+        }
+    }
+
+    if (typeStr == NULL && uuidStr == NULL) {
+        lStatus = AUDIOEFFECT_ERROR_BAD_VALUE;
+        goto setup_failure;
+    }
+
+    lpJniStorage = new AudioEffectJniStorage();
+    if (lpJniStorage == NULL) {
+        LOGE("setup: Error creating JNI Storage");
+        goto setup_failure;
+    }
+
+    lpJniStorage->mCallbackData.audioEffect_class = (jclass)env->NewGlobalRef(fields.clazzEffect);
+    // we use a weak reference so the AudioEffect object can be garbage collected.
+    lpJniStorage->mCallbackData.audioEffect_ref = env->NewGlobalRef(weak_this);
+
+    LOGV("setup: lpJniStorage: %p audioEffect_ref %p audioEffect_class %p, &mCallbackData %p",
+            lpJniStorage,
+            lpJniStorage->mCallbackData.audioEffect_ref,
+            lpJniStorage->mCallbackData.audioEffect_class,
+            &lpJniStorage->mCallbackData);
+
+    if (jId) {
+        nId = (jint *) env->GetPrimitiveArrayCritical(jId, NULL);
+        if (nId == NULL) {
+            LOGE("setup: Error retrieving id pointer");
+            lStatus = AUDIOEFFECT_ERROR_BAD_VALUE;
+            goto setup_failure;
+        }
+    } else {
+        LOGE("setup: NULL java array for id pointer");
+        lStatus = AUDIOEFFECT_ERROR_BAD_VALUE;
+        goto setup_failure;
+    }
+
+    // create the native AudioEffect object
+    lpAudioEffect = new AudioEffect(typeStr,
+                                    uuidStr,
+                                    priority,
+                                    effectCallback,
+                                    &lpJniStorage->mCallbackData,
+                                    0,
+                                    sessionId);
+    if (lpAudioEffect == NULL) {
+        LOGE("Error creating AudioEffect");
+        goto setup_failure;
+    }
+
+    lStatus = translateError(lpAudioEffect->initCheck());
+    if (lStatus != AUDIOEFFECT_SUCCESS && lStatus != AUDIOEFFECT_ERROR_ALREADY_EXISTS) {
+        LOGE("AudioEffect initCheck failed %d", lStatus);
+        goto setup_failure;
+    }
+
+    nId[0] = lpAudioEffect->id();
+
+    env->ReleasePrimitiveArrayCritical(jId, nId, 0);
+    nId = NULL;
+
+    if (typeStr) {
+        env->ReleaseStringUTFChars(type, typeStr);
+        typeStr = NULL;
+    }
+
+    if (uuidStr) {
+        env->ReleaseStringUTFChars(uuid, uuidStr);
+        uuidStr = NULL;
+    }
+
+    // get the effect descriptor
+    desc = lpAudioEffect->descriptor();
+
+    AudioEffect::guidToString(&desc.type, str, EFFECT_STRING_LEN_MAX);
+    jdescType = env->NewStringUTF(str);
+
+    AudioEffect::guidToString(&desc.uuid, str, EFFECT_STRING_LEN_MAX);
+    jdescUuid = env->NewStringUTF(str);
+
+    if ((desc.flags & EFFECT_FLAG_TYPE_MASK) == EFFECT_FLAG_TYPE_AUXILIARY) {
+        jdescConnect = env->NewStringUTF("Auxiliary");
+    } else {
+        jdescConnect = env->NewStringUTF("Insert");
+    }
+
+    jdescName = env->NewStringUTF(desc.name);
+    jdescImplementor = env->NewStringUTF(desc.implementor);
+
+    jdesc = env->NewObject(fields.clazzDesc,
+                           fields.midDescCstor,
+                           jdescType,
+                           jdescUuid,
+                           jdescConnect,
+                           jdescName,
+                           jdescImplementor);
+    env->DeleteLocalRef(jdescType);
+    env->DeleteLocalRef(jdescUuid);
+    env->DeleteLocalRef(jdescConnect);
+    env->DeleteLocalRef(jdescName);
+    env->DeleteLocalRef(jdescImplementor);
+    if (jdesc == NULL) {
+        LOGE("env->NewObject(fields.clazzDesc, fields.midDescCstor)");
+        goto setup_failure;
+    }
+
+    env->SetObjectArrayElement(javadesc, 0, jdesc);
+
+    env->SetIntField(thiz, fields.fidNativeAudioEffect, (int)lpAudioEffect);
+
+    env->SetIntField(thiz, fields.fidJniData, (int)lpJniStorage);
+
+    return AUDIOEFFECT_SUCCESS;
+
+    // failures:
+setup_failure:
+
+    if (nId != NULL) {
+        env->ReleasePrimitiveArrayCritical(jId, nId, 0);
+    }
+
+    if (lpAudioEffect) {
+        delete lpAudioEffect;
+    }
+    env->SetIntField(thiz, fields.fidNativeAudioEffect, 0);
+
+    if (lpJniStorage) {
+        delete lpJniStorage;
+    }
+    env->SetIntField(thiz, fields.fidJniData, 0);
+
+    if (uuidStr != NULL) {
+        env->ReleaseStringUTFChars(uuid, uuidStr);
+    }
+
+    if (typeStr != NULL) {
+        env->ReleaseStringUTFChars(type, typeStr);
+    }
+
+    return lStatus;
+}
+
+
+// ----------------------------------------------------------------------------
+static void android_media_AudioEffect_native_finalize(JNIEnv *env,  jobject thiz) {
+    LOGV("android_media_AudioEffect_native_finalize jobject: %x\n", (int)thiz);
+
+    // delete the AudioEffect object
+    AudioEffect* lpAudioEffect = (AudioEffect *)env->GetIntField(
+        thiz, fields.fidNativeAudioEffect);
+    if (lpAudioEffect) {
+        LOGV("deleting AudioEffect: %x\n", (int)lpAudioEffect);
+        delete lpAudioEffect;
+    }
+
+    // delete the JNI data
+    AudioEffectJniStorage* lpJniStorage = (AudioEffectJniStorage *)env->GetIntField(
+        thiz, fields.fidJniData);
+    if (lpJniStorage) {
+        LOGV("deleting pJniStorage: %x\n", (int)lpJniStorage);
+        delete lpJniStorage;
+    }
+}
+
+// ----------------------------------------------------------------------------
+static void android_media_AudioEffect_native_release(JNIEnv *env,  jobject thiz) {
+
+    // do everything a call to finalize would
+    android_media_AudioEffect_native_finalize(env, thiz);
+    // + reset the native resources in the Java object so any attempt to access
+    // them after a call to release fails.
+    env->SetIntField(thiz, fields.fidNativeAudioEffect, 0);
+    env->SetIntField(thiz, fields.fidJniData, 0);
+}
+
+
+static jint
+android_media_AudioEffect_native_enable(JNIEnv *env, jobject thiz)
+{
+    // retrieve the AudioEffect object
+    AudioEffect* lpAudioEffect = (AudioEffect *)env->GetIntField(
+        thiz, fields.fidNativeAudioEffect);
+
+    if (lpAudioEffect == NULL) {
+        jniThrowException(env, "java/lang/IllegalStateException",
+            "Unable to retrieve AudioEffect pointer for enable()");
+        return AUDIOEFFECT_ERROR_NO_INIT;
+    }
+
+    return translateError(lpAudioEffect->enable());
+}
+
+
+static jint
+android_media_AudioEffect_native_disable(JNIEnv *env, jobject thiz)
+{
+    // retrieve the AudioEffect object
+    AudioEffect* lpAudioEffect = (AudioEffect *)env->GetIntField(
+        thiz, fields.fidNativeAudioEffect);
+
+    if (lpAudioEffect == NULL) {
+        jniThrowException(env, "java/lang/IllegalStateException",
+            "Unable to retrieve AudioEffect pointer for disable()");
+        return AUDIOEFFECT_ERROR_NO_INIT;
+    }
+
+    return translateError(lpAudioEffect->disable());
+}
+
+
+static jboolean
+android_media_AudioEffect_native_getEnable(JNIEnv *env, jobject thiz)
+{
+    // retrieve the AudioEffect object
+    AudioEffect* lpAudioEffect = (AudioEffect *)env->GetIntField(
+        thiz, fields.fidNativeAudioEffect);
+
+    if (lpAudioEffect == NULL) {
+        jniThrowException(env, "java/lang/IllegalStateException",
+            "Unable to retrieve AudioEffect pointer for getEnabled()");
+        return false;
+    }
+
+    return (jboolean)lpAudioEffect->isEnabled();
+}
+
+
+static jboolean
+android_media_AudioEffect_native_hasControl(JNIEnv *env, jobject thiz)
+{
+    // retrieve the AudioEffect object
+    AudioEffect* lpAudioEffect = (AudioEffect *)env->GetIntField(
+        thiz, fields.fidNativeAudioEffect);
+
+    if (lpAudioEffect == NULL) {
+        jniThrowException(env, "java/lang/IllegalStateException",
+            "Unable to retrieve AudioEffect pointer for getEnabled()");
+        return false;
+    }
+
+    if (lpAudioEffect->initCheck() == NO_ERROR) {
+        return true;
+    } else {
+        return false;
+    }
+}
+
+static jint android_media_AudioEffect_native_setParameter(JNIEnv *env,
+        jobject thiz, int psize, jbyteArray pJavaParam, int vsize,
+        jbyteArray pJavaValue) {
+    // retrieve the AudioEffect object
+    jbyte* lpValue = NULL;
+    jbyte* lpParam = NULL;
+    jint lStatus = AUDIOEFFECT_ERROR_BAD_VALUE;
+    effect_param_t *p;
+    int voffset;
+
+    AudioEffect* lpAudioEffect = (AudioEffect *) env->GetIntField(thiz,
+            fields.fidNativeAudioEffect);
+
+    if (lpAudioEffect == NULL) {
+        jniThrowException(env, "java/lang/IllegalStateException",
+                "Unable to retrieve AudioEffect pointer for setParameter()");
+        return AUDIOEFFECT_ERROR_NO_INIT;
+    }
+
+    if (psize == 0 || vsize == 0 || pJavaParam == NULL || pJavaValue == NULL) {
+        return AUDIOEFFECT_ERROR_BAD_VALUE;
+    }
+
+    // get the pointer for the param from the java array
+    lpParam = (jbyte *) env->GetPrimitiveArrayCritical(pJavaParam, NULL);
+    if (lpParam == NULL) {
+        LOGE("setParameter: Error retrieving param pointer");
+        goto setParameter_Exit;
+    }
+
+    // get the pointer for the value from the java array
+    lpValue = (jbyte *) env->GetPrimitiveArrayCritical(pJavaValue, NULL);
+    if (lpValue == NULL) {
+        LOGE("setParameter: Error retrieving value pointer");
+        goto setParameter_Exit;
+    }
+
+    voffset = ((psize - 1) / sizeof(int) + 1) * sizeof(int);
+    p = (effect_param_t *) malloc(sizeof(effect_param_t) + voffset + vsize);
+    memcpy(p->data, lpParam, psize);
+    p->psize = psize;
+    memcpy(p->data + voffset, lpValue, psize);
+    p->vsize = vsize;
+
+    lStatus = lpAudioEffect->setParameter(p);
+    if (lStatus == NO_ERROR) {
+        lStatus = p->status;
+    }
+
+    free(p);
+
+setParameter_Exit:
+
+    if (lpParam != NULL) {
+        env->ReleasePrimitiveArrayCritical(pJavaParam, lpParam, 0);
+    }
+    if (lpValue != NULL) {
+        env->ReleasePrimitiveArrayCritical(pJavaValue, lpValue, 0);
+    }
+    return translateError(lStatus);
+}
+
+static jint
+android_media_AudioEffect_native_getParameter(JNIEnv *env,
+        jobject thiz, int psize, jbyteArray pJavaParam,
+        jintArray pJavaValueSize, jbyteArray pJavaValue) {
+    // retrieve the AudioEffect object
+    jbyte* lpParam = NULL;
+    jbyte* lpValue = NULL;
+    jbyte* lpValueSize = NULL;
+    jint lStatus = AUDIOEFFECT_ERROR_BAD_VALUE;
+    effect_param_t *p;
+    int voffset;
+
+    AudioEffect* lpAudioEffect = (AudioEffect *) env->GetIntField(thiz,
+            fields.fidNativeAudioEffect);
+
+    if (lpAudioEffect == NULL) {
+        jniThrowException(env, "java/lang/IllegalStateException",
+                "Unable to retrieve AudioEffect pointer for getParameter()");
+        return AUDIOEFFECT_ERROR_NO_INIT;
+    }
+
+    if (psize == 0 || pJavaValueSize == NULL || pJavaParam == NULL || pJavaValue == NULL) {
+        return AUDIOEFFECT_ERROR_BAD_VALUE;
+    }
+
+    // get the pointer for the param from the java array
+    lpParam = (jbyte *) env->GetPrimitiveArrayCritical(pJavaParam, NULL);
+    if (lpParam == NULL) {
+        LOGE("getParameter: Error retrieving param pointer");
+        goto getParameter_Exit;
+    }
+
+    // get the pointer for the value from the java array
+    lpValue = (jbyte *) env->GetPrimitiveArrayCritical(pJavaValue, NULL);
+    if (lpValue == NULL) {
+        LOGE("getParameter: Error retrieving value pointer");
+        goto getParameter_Exit;
+    }
+
+    // get the pointer for the value size from the java array
+    lpValueSize = (jbyte *) env->GetPrimitiveArrayCritical(pJavaValueSize, NULL);
+    if (lpValueSize == NULL) {
+        LOGE("getParameter: Error retrieving value size pointer");
+        goto getParameter_Exit;
+    }
+
+    voffset = ((psize - 1) / sizeof(int) + 1) * sizeof(int);
+    p = (effect_param_t *) malloc(sizeof(effect_param_t) + voffset
+            + lpValueSize[0]);
+    memcpy(p->data, lpParam, psize);
+    p->psize = psize;
+    p->vsize = lpValueSize[0];
+
+    lStatus = lpAudioEffect->getParameter(p);
+    if (lStatus == NO_ERROR) {
+        lStatus = p->status;
+        if (lStatus == NO_ERROR) {
+            memcpy(lpValue, p->data + voffset, p->vsize);
+            lpValueSize[0] = p->vsize;
+        }
+    }
+
+    free(p);
+
+getParameter_Exit:
+
+    if (lpParam != NULL) {
+        env->ReleasePrimitiveArrayCritical(pJavaParam, lpParam, 0);
+    }
+    if (lpValue != NULL) {
+        env->ReleasePrimitiveArrayCritical(pJavaValue, lpValue, 0);
+    }
+    if (lpValueSize != NULL) {
+        env->ReleasePrimitiveArrayCritical(pJavaValueSize, lpValueSize, 0);
+    }
+
+    return translateError(lStatus);
+}
+
+static jint android_media_AudioEffect_native_command(JNIEnv *env, jobject thiz,
+        jint cmdCode, jint cmdSize, jbyteArray jCmdData, jintArray jReplySize,
+        jbyteArray jReplyData) {
+    jbyte* pCmdData = NULL;
+    jbyte* pReplyData = NULL;
+    jint* pReplySize = NULL;
+    jint lStatus = AUDIOEFFECT_ERROR_BAD_VALUE;
+
+    // retrieve the AudioEffect object
+    AudioEffect* lpAudioEffect = (AudioEffect *) env->GetIntField(thiz,
+            fields.fidNativeAudioEffect);
+
+    if (lpAudioEffect == NULL) {
+        jniThrowException(env, "java/lang/IllegalStateException",
+                "Unable to retrieve AudioEffect pointer for setParameter()");
+        return AUDIOEFFECT_ERROR_NO_INIT;
+    }
+
+    if ((cmdSize != 0 && jCmdData == NULL) || (jReplySize != NULL && jReplyData == NULL)) {
+        return AUDIOEFFECT_ERROR_BAD_VALUE;
+    }
+
+    // get the pointer for the command from the java array
+    if (cmdSize != 0) {
+        pCmdData = (jbyte *) env->GetPrimitiveArrayCritical(jCmdData, NULL);
+        if (pCmdData == NULL) {
+            LOGE("setParameter: Error retrieving command pointer");
+            goto command_Exit;
+        }
+    }
+
+    // get the pointer for the reply size from the java array
+    if (jReplySize != NULL) {
+        pReplySize = (jint *) env->GetPrimitiveArrayCritical(jReplySize, NULL);
+        if (pReplySize == NULL) {
+            LOGE("setParameter: Error retrieving reply pointer");
+            goto command_Exit;
+        }
+    }
+
+    // get the pointer for the reply from the java array
+    if (pReplySize != NULL && pReplySize[0] != 0 && jReplyData != NULL) {
+        pReplyData = (jbyte *) env->GetPrimitiveArrayCritical(jReplyData, NULL);
+        if (pReplyData == NULL) {
+            LOGE("setParameter: Error retrieving reply pointer");
+            goto command_Exit;
+        }
+    }
+
+    lStatus = translateError(lpAudioEffect->command(cmdCode, cmdSize, pCmdData,
+            pReplySize, pReplyData));
+
+command_Exit:
+
+    if (pCmdData != NULL) {
+        env->ReleasePrimitiveArrayCritical(jCmdData, pCmdData, 0);
+    }
+    if (pReplyData != NULL) {
+        env->ReleasePrimitiveArrayCritical(jReplyData, pReplyData, 0);
+    }
+    if (pReplySize != NULL) {
+        env->ReleasePrimitiveArrayCritical(jReplySize, pReplySize, 0);
+    }
+
+    return lStatus;
+}
+
+static jobjectArray
+android_media_AudioEffect_native_queryEffects(JNIEnv *env, jclass clazz)
+{
+    effect_descriptor_t desc;
+    char str[EFFECT_STRING_LEN_MAX];
+    uint32_t numEffects;
+    uint32_t i = 0;
+    jstring jdescType;
+    jstring jdescUuid;
+    jstring jdescConnect;
+    jstring jdescName;
+    jstring jdescImplementor;
+    jobject jdesc;
+
+    AudioEffect::queryNumberEffects(&numEffects);
+    jobjectArray ret = env->NewObjectArray(numEffects, fields.clazzDesc, NULL);
+    if (ret == NULL) {
+        return ret;
+    }
+
+    LOGV("queryEffects() numEffects: %d", numEffects);
+
+    for (i = 0; i < numEffects; i++) {
+        if (AudioEffect::queryNextEffect(&desc) != NO_ERROR) {
+            goto queryEffects_failure;
+        }
+
+        AudioEffect::guidToString(&desc.type, str, EFFECT_STRING_LEN_MAX);
+        jdescType = env->NewStringUTF(str);
+
+        AudioEffect::guidToString(&desc.uuid, str, EFFECT_STRING_LEN_MAX);
+        jdescUuid = env->NewStringUTF(str);
+
+        if ((desc.flags & EFFECT_FLAG_TYPE_MASK) == EFFECT_FLAG_TYPE_AUXILIARY) {
+            jdescConnect = env->NewStringUTF("Auxiliary");
+        } else {
+            jdescConnect = env->NewStringUTF("Insert");
+        }
+
+        jdescName = env->NewStringUTF(desc.name);
+        jdescImplementor = env->NewStringUTF(desc.implementor);
+
+        jdesc = env->NewObject(fields.clazzDesc,
+                               fields.midDescCstor,
+                               jdescType,
+                               jdescUuid,
+                               jdescConnect,
+                               jdescName,
+                               jdescImplementor);
+        env->DeleteLocalRef(jdescType);
+        env->DeleteLocalRef(jdescUuid);
+        env->DeleteLocalRef(jdescConnect);
+        env->DeleteLocalRef(jdescName);
+        env->DeleteLocalRef(jdescImplementor);
+        if (jdesc == NULL) {
+            LOGE("env->NewObject(fields.clazzDesc, fields.midDescCstor)");
+            goto queryEffects_failure;
+        }
+
+        env->SetObjectArrayElement(ret, i, jdesc);
+   }
+
+    return ret;
+
+queryEffects_failure:
+
+    if (ret != NULL) {
+        env->DeleteLocalRef(ret);
+    }
+    return NULL;
+
+}
+
+// ----------------------------------------------------------------------------
+
+// Dalvik VM type signatures
+static JNINativeMethod gMethods[] = {
+    {"native_init",          "()V",      (void *)android_media_AudioEffect_native_init},
+    {"native_setup",         "(Ljava/lang/Object;Ljava/lang/String;Ljava/lang/String;II[I[Ljava/lang/Object;)I",
+                                         (void *)android_media_AudioEffect_native_setup},
+    {"native_finalize",      "()V",      (void *)android_media_AudioEffect_native_finalize},
+    {"native_release",       "()V",      (void *)android_media_AudioEffect_native_release},
+    {"native_enable",        "()I",      (void *)android_media_AudioEffect_native_enable},
+    {"native_disable",       "()I",      (void *)android_media_AudioEffect_native_disable},
+    {"native_getEnable",     "()Z",      (void *)android_media_AudioEffect_native_getEnable},
+    {"native_hasControl",    "()Z",      (void *)android_media_AudioEffect_native_hasControl},
+    {"native_setParameter",  "(I[BI[B)I",  (void *)android_media_AudioEffect_native_setParameter},
+    {"native_getParameter",  "(I[B[I[B)I",  (void *)android_media_AudioEffect_native_getParameter},
+    {"native_command",       "(II[B[I[B)I", (void *)android_media_AudioEffect_native_command},
+    {"native_query_effects", "()[Ljava/lang/Object;", (void *)android_media_AudioEffect_native_queryEffects},
+};
+
+
+// ----------------------------------------------------------------------------
+
+int register_android_media_AudioEffect(JNIEnv *env)
+{
+    return AndroidRuntime::registerNativeMethods(env, kClassPathName, gMethods, NELEM(gMethods));
+}
+
+jint JNI_OnLoad(JavaVM* vm, void* reserved)
+{
+
+    JNIEnv* env = NULL;
+    jint result = -1;
+
+    if (vm->GetEnv((void**) &env, JNI_VERSION_1_4) != JNI_OK) {
+        LOGE("ERROR: GetEnv failed\n");
+        goto bail;
+    }
+    assert(env != NULL);
+
+    if (register_android_media_AudioEffect(env) < 0) {
+        LOGE("ERROR: AudioEffect native registration failed\n");
+        goto bail;
+    }
+
+    /* success -- return valid version number */
+    result = JNI_VERSION_1_4;
+
+bail:
+    return result;
+}
+
diff --git a/media/libmedia/Android.mk b/media/libmedia/Android.mk
index 29cd2ee..7908f5d 100644
--- a/media/libmedia/Android.mk
+++ b/media/libmedia/Android.mk
@@ -28,7 +28,8 @@
     IMediaDeathNotifier.cpp \
     MediaProfiles.cpp \
     IEffect.cpp \
-    IEffectClient.cpp
+    IEffectClient.cpp \
+    AudioEffect.cpp
 
 LOCAL_SHARED_LIBRARIES := \
 	libui libcutils libutils libbinder libsonivox libicuuc libexpat libsurfaceflinger_client libcamera_client
diff --git a/media/libmedia/AudioEffect.cpp b/media/libmedia/AudioEffect.cpp
new file mode 100644
index 0000000..8648211
--- /dev/null
+++ b/media/libmedia/AudioEffect.cpp
@@ -0,0 +1,462 @@
+/*
+**
+** Copyright 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_NDEBUG 0
+#define LOG_TAG "AudioEffect"
+
+#include <stdint.h>
+#include <sys/types.h>
+#include <limits.h>
+
+#include <private/media/AudioEffectShared.h>
+#include <media/AudioEffect.h>
+
+#include <utils/Log.h>
+#include <cutils/atomic.h>
+#include <binder/IPCThreadState.h>
+
+
+
+namespace android {
+
+// ---------------------------------------------------------------------------
+
+AudioEffect::AudioEffect()
+    : mStatus(NO_INIT)
+{
+}
+
+
+AudioEffect::AudioEffect(const effect_uuid_t *type,
+                const effect_uuid_t *uuid,
+                int32_t priority,
+                effect_callback_t cbf,
+                void* user,
+                int sessionId,
+                audio_io_handle_t output
+                )
+    : mStatus(NO_INIT)
+{
+    mStatus = set(type, uuid, priority, cbf, user, output, sessionId);
+}
+
+AudioEffect::AudioEffect(const char *typeStr,
+                const char *uuidStr,
+                int32_t priority,
+                effect_callback_t cbf,
+                void* user,
+                int sessionId,
+                audio_io_handle_t output
+                )
+    : mStatus(NO_INIT)
+{
+    effect_uuid_t type;
+    effect_uuid_t *pType = NULL;
+    effect_uuid_t uuid;
+    effect_uuid_t *pUuid = NULL;
+
+    LOGV("Constructor string\n - type: %s\n - uuid: %s", typeStr, uuidStr);
+
+    if (typeStr != NULL) {
+        if (stringToGuid(typeStr, &type) == NO_ERROR) {
+            pType = &type;
+        }
+    }
+
+    if (uuidStr != NULL) {
+        if (stringToGuid(uuidStr, &uuid) == NO_ERROR) {
+            pUuid = &uuid;
+        }
+    }
+
+    mStatus = set(pType, pUuid, priority, cbf, user, output, sessionId);
+}
+
+status_t AudioEffect::set(const effect_uuid_t *type,
+                const effect_uuid_t *uuid,
+                int32_t priority,
+                effect_callback_t cbf,
+                void* user,
+                int sessionId,
+                audio_io_handle_t output)
+{
+    sp<IEffect> iEffect;
+    sp<IMemory> cblk;
+    int enabled;
+
+    LOGV("set %p mUserData: %p", this, user);
+
+    if (mIEffect != 0) {
+        LOGW("Effect already in use");
+        return INVALID_OPERATION;
+    }
+
+    const sp<IAudioFlinger>& audioFlinger = AudioSystem::get_audio_flinger();
+    if (audioFlinger == 0) {
+        LOGE("set(): Could not get audioflinger");
+        return NO_INIT;
+    }
+
+    if (type == NULL && uuid == NULL) {
+        LOGW("Must specify at least type or uuid");
+        return BAD_VALUE;
+    }
+
+    mPriority = priority;
+    mCbf = cbf;
+    mUserData = user;
+    mSessionId = sessionId;
+
+    memset(&mDescriptor, 0, sizeof(effect_descriptor_t));
+    memcpy(&mDescriptor.type, EFFECT_UUID_NULL, sizeof(effect_uuid_t));
+    memcpy(&mDescriptor.uuid, EFFECT_UUID_NULL, sizeof(effect_uuid_t));
+
+    if (type != NULL) {
+        memcpy(&mDescriptor.type, type, sizeof(effect_uuid_t));
+    }
+    if (uuid != NULL) {
+        memcpy(&mDescriptor.uuid, uuid, sizeof(effect_uuid_t));
+    }
+
+    mIEffectClient = new EffectClient(this);
+
+    iEffect = audioFlinger->createEffect(getpid(), (effect_descriptor_t *)&mDescriptor,
+            mIEffectClient, priority, output, mSessionId, &mStatus, &mId, &enabled);
+
+    if (iEffect == 0 || (mStatus != NO_ERROR && mStatus != ALREADY_EXISTS)) {
+        LOGE("set(): AudioFlinger could not create effect, status: %d", mStatus);
+        return mStatus;
+    }
+
+    mEnabled = (volatile int32_t)enabled;
+
+    mIEffect = iEffect;
+    cblk = iEffect->getCblk();
+    if (cblk == 0) {
+        mStatus = NO_INIT;
+        LOGE("Could not get control block");
+        return mStatus;
+    }
+
+    mIEffect = iEffect;
+    mCblkMemory = cblk;
+    mCblk = static_cast<effect_param_cblk_t*>(cblk->pointer());
+    int bufOffset = ((sizeof(effect_param_cblk_t) - 1) / sizeof(int) + 1) * sizeof(int);
+    mCblk->buffer = (uint8_t *)mCblk + bufOffset;
+
+    iEffect->asBinder()->linkToDeath(mIEffectClient);
+    LOGV("set() %p OK effect: %s id: %d status %d enabled %d, ", this, mDescriptor.name, mId, mStatus, mEnabled);
+
+    return mStatus;
+}
+
+
+AudioEffect::~AudioEffect()
+{
+    LOGV("Destructor %p", this);
+
+    if (mStatus == NO_ERROR || mStatus == ALREADY_EXISTS) {
+        disable();
+        if (mIEffect != NULL) {
+            mIEffect->disconnect();
+            mIEffect->asBinder()->unlinkToDeath(mIEffectClient);
+        }
+         IPCThreadState::self()->flushCommands();
+    }
+    mIEffect.clear();
+    mIEffectClient.clear();
+    mCblkMemory.clear();
+}
+
+
+status_t AudioEffect::initCheck() const
+{
+    return mStatus;
+}
+
+// -------------------------------------------------------------------------
+
+effect_descriptor_t AudioEffect::descriptor() const
+{
+    return mDescriptor;
+}
+
+bool AudioEffect::isEnabled() const
+{
+    return (mEnabled != 0);
+}
+
+status_t AudioEffect::enable()
+{
+    if (mStatus != NO_ERROR) {
+        return INVALID_OPERATION;
+    }
+    LOGV("enable %p", this);
+
+    if (android_atomic_or(1, &mEnabled) == 0) {
+       return mIEffect->enable();
+    }
+
+    return INVALID_OPERATION;
+}
+
+status_t AudioEffect::disable()
+{
+    if (mStatus != NO_ERROR) {
+        return INVALID_OPERATION;
+    }
+    LOGV("disable %p", this);
+
+    if (android_atomic_and(~1, &mEnabled) == 1) {
+       return mIEffect->disable();
+    }
+
+    return INVALID_OPERATION;
+}
+
+status_t AudioEffect::command(int32_t cmdCode, int32_t cmdSize, void *cmdData, int32_t *replySize, void *replyData)
+{
+    if (mStatus != NO_ERROR && mStatus != ALREADY_EXISTS) {
+        return INVALID_OPERATION;
+    }
+
+    return mIEffect->command(cmdCode, cmdSize, cmdData, replySize, replyData);
+}
+
+
+status_t AudioEffect::setParameter(effect_param_t *param)
+{
+    if (mStatus != NO_ERROR) {
+        return INVALID_OPERATION;
+    }
+
+    if (param == NULL || param->psize == 0 || param->vsize == 0) {
+        return BAD_VALUE;
+    }
+
+    int size = sizeof(int);
+    int psize = ((param->psize - 1) / sizeof(int) + 1) * sizeof(int) + param->vsize;
+
+    LOGV("setParameter: param: %d, param2: %d", *(int *)param->data, (param->psize == 8) ? *((int *)param->data + 1): -1);
+
+    return mIEffect->command(EFFECT_CMD_SET_PARAM, sizeof (effect_param_t) + psize, param, &size, &param->status);
+}
+
+status_t AudioEffect::setParameterDeferred(effect_param_t *param)
+{
+    if (mStatus != NO_ERROR) {
+        return INVALID_OPERATION;
+    }
+
+    if (param == NULL || param->psize == 0 || param->vsize == 0) {
+        return BAD_VALUE;
+    }
+
+    Mutex::Autolock _l(mCblk->lock);
+
+    int psize = ((param->psize - 1) / sizeof(int) + 1) * sizeof(int) + param->vsize;
+    int size = ((sizeof(effect_param_t) + psize - 1) / sizeof(int) + 1) * sizeof(int);
+
+    if (mCblk->clientIndex + size > EFFECT_PARAM_BUFFER_SIZE) {
+        return NO_MEMORY;
+    }
+    int *p = (int *)(mCblk->buffer + mCblk->clientIndex);
+    *p++ = size;
+    memcpy(p, param, sizeof(effect_param_t) + psize);
+    mCblk->clientIndex += size;
+
+    return NO_ERROR;
+}
+
+status_t AudioEffect::setParameterCommit()
+{
+    if (mStatus != NO_ERROR) {
+        return INVALID_OPERATION;
+    }
+
+    Mutex::Autolock _l(mCblk->lock);
+    if (mCblk->clientIndex == 0) {
+        return INVALID_OPERATION;
+    }
+    int size = 0;
+    return mIEffect->command(EFFECT_CMD_SET_PARAM_COMMIT, 0, NULL, &size, NULL);
+}
+
+status_t AudioEffect::getParameter(effect_param_t *param)
+{
+    if (mStatus != NO_ERROR && mStatus != ALREADY_EXISTS) {
+        return INVALID_OPERATION;
+    }
+
+    if (param == NULL || param->psize == 0 || param->vsize == 0) {
+        return BAD_VALUE;
+    }
+
+    LOGV("getParameter: param: %d, param2: %d", *(int *)param->data, (param->psize == 8) ? *((int *)param->data + 1): -1);
+
+    int psize = sizeof(effect_param_t) + ((param->psize - 1) / sizeof(int) + 1) * sizeof(int) + param->vsize;
+
+    return mIEffect->command(EFFECT_CMD_GET_PARAM, sizeof(effect_param_t) + param->psize, param, &psize, param);
+}
+
+
+// -------------------------------------------------------------------------
+
+void AudioEffect::binderDied()
+{
+    LOGW("IEffect died");
+    mStatus = NO_INIT;
+    if (mCbf) {
+        status_t status = DEAD_OBJECT;
+        mCbf(EVENT_ERROR, mUserData, &status);
+    }
+    mIEffect.clear();
+}
+
+// -------------------------------------------------------------------------
+
+void AudioEffect::controlStatusChanged(bool controlGranted)
+{
+    LOGV("controlStatusChanged %p control %d callback %p mUserData %p", this, controlGranted, mCbf, mUserData);
+    if (controlGranted) {
+        if (mStatus == ALREADY_EXISTS) {
+            mStatus = NO_ERROR;
+        }
+    } else {
+        if (mStatus == NO_ERROR) {
+            mStatus = ALREADY_EXISTS;
+        }
+    }
+    if (mCbf) {
+        mCbf(EVENT_CONTROL_STATUS_CHANGED, mUserData, &controlGranted);
+    }
+}
+
+void AudioEffect::enableStatusChanged(bool enabled)
+{
+    LOGV("enableStatusChanged %p enabled %d", this, enabled);
+    if (mStatus == ALREADY_EXISTS) {
+        mEnabled = enabled;
+        if (mCbf) {
+            mCbf(EVENT_ENABLE_STATUS_CHANGED, mUserData, &enabled);
+        }
+    }
+}
+
+void AudioEffect::commandExecuted(int cmdCode, int cmdSize, void *cmdData, int replySize, void *replyData)
+{
+    if (cmdData == NULL || replyData == NULL) {
+        return;
+    }
+
+    if (mCbf && cmdCode == EFFECT_CMD_SET_PARAM) {
+        effect_param_t *cmd = (effect_param_t *)cmdData;
+        cmd->status = *(int32_t *)replyData;
+        mCbf(EVENT_PARAMETER_CHANGED, mUserData, cmd);
+    }
+}
+
+// -------------------------------------------------------------------------
+
+status_t AudioEffect::loadEffectLibrary(const char *libPath, int *handle)
+{
+    const sp<IAudioFlinger>& af = AudioSystem::get_audio_flinger();
+    if (af == 0) return PERMISSION_DENIED;
+    return af->loadEffectLibrary(libPath, handle);
+}
+
+status_t AudioEffect::unloadEffectLibrary(int handle)
+{
+    const sp<IAudioFlinger>& af = AudioSystem::get_audio_flinger();
+    if (af == 0) return PERMISSION_DENIED;
+    return af->unloadEffectLibrary(handle);
+}
+
+status_t AudioEffect::queryNumberEffects(uint32_t *numEffects)
+{
+    const sp<IAudioFlinger>& af = AudioSystem::get_audio_flinger();
+    if (af == 0) return PERMISSION_DENIED;
+    return af->queryNumberEffects(numEffects);
+}
+
+status_t AudioEffect::queryNextEffect(effect_descriptor_t *descriptor)
+{
+    const sp<IAudioFlinger>& af = AudioSystem::get_audio_flinger();
+    if (af == 0) return PERMISSION_DENIED;
+    return af->queryNextEffect(descriptor);
+}
+
+status_t AudioEffect::getEffectDescriptor(effect_uuid_t *uuid, effect_descriptor_t *descriptor)
+{
+    const sp<IAudioFlinger>& af = AudioSystem::get_audio_flinger();
+    if (af == 0) return PERMISSION_DENIED;
+    return af->getEffectDescriptor(uuid, descriptor);
+}
+
+// -------------------------------------------------------------------------
+
+status_t AudioEffect::stringToGuid(const char *str, effect_uuid_t *guid)
+{
+    if (str == NULL || guid == NULL) {
+        return BAD_VALUE;
+    }
+
+    int tmp[10];
+
+    if (sscanf(str, "%08x-%04x-%04x-%04x-%02x%02x%02x%02x%02x%02x",
+            tmp, tmp+1, tmp+2, tmp+3, tmp+4, tmp+5, tmp+6, tmp+7, tmp+8, tmp+9) < 10) {
+        return BAD_VALUE;
+    }
+    guid->timeLow = (uint32_t)tmp[0];
+    guid->timeMid = (uint16_t)tmp[1];
+    guid->timeHiAndVersion = (uint16_t)tmp[2];
+    guid->clockSeq = (uint16_t)tmp[3];
+    guid->node[0] = (uint8_t)tmp[4];
+    guid->node[1] = (uint8_t)tmp[5];
+    guid->node[2] = (uint8_t)tmp[6];
+    guid->node[3] = (uint8_t)tmp[7];
+    guid->node[4] = (uint8_t)tmp[8];
+    guid->node[5] = (uint8_t)tmp[9];
+
+    return NO_ERROR;
+}
+
+status_t AudioEffect::guidToString(const effect_uuid_t *guid, char *str, size_t maxLen)
+{
+    if (guid == NULL || str == NULL) {
+        return BAD_VALUE;
+    }
+
+    snprintf(str, maxLen, "%08x-%04x-%04x-%04x-%02x%02x%02x%02x%02x%02x",
+            guid->timeLow,
+            guid->timeMid,
+            guid->timeHiAndVersion,
+            guid->clockSeq,
+            guid->node[0],
+            guid->node[1],
+            guid->node[2],
+            guid->node[3],
+            guid->node[4],
+            guid->node[5]);
+
+    return NO_ERROR;
+}
+
+
+}; // namespace android
+
