audio: qahw_effect_api: Initial version of QTI audio effect HAL

Initial version of QTI audio effect HAL Wrapper.

CRs-Fixed: 1081403
Change-Id: I12291cc7106f7530422891d1bee7e3d4530563c5
diff --git a/qahw_api/Android.mk b/qahw_api/Android.mk
index 98e1a38..1886262 100644
--- a/qahw_api/Android.mk
+++ b/qahw_api/Android.mk
@@ -12,7 +12,8 @@
 LOCAL_C_INCLUDES   := $(libqahw-inc)
 
 LOCAL_SRC_FILES := \
-    src/qahw.c
+    src/qahw.c \
+    src/qahw_effect.c
 
 LOCAL_SHARED_LIBRARIES := \
     liblog \
@@ -23,6 +24,13 @@
 LOCAL_COPY_HEADERS_TO   := mm-audio/qahw_api/inc
 LOCAL_COPY_HEADERS      := inc/qahw_api.h
 LOCAL_COPY_HEADERS      += inc/qahw_defs.h
+LOCAL_COPY_HEADERS      += inc/qahw_effect_api.h
+LOCAL_COPY_HEADERS      += inc/qahw_effect_bassboost.h
+LOCAL_COPY_HEADERS      += inc/qahw_effect_environmentalreverb.h
+LOCAL_COPY_HEADERS      += inc/qahw_effect_equalizer.h
+LOCAL_COPY_HEADERS      += inc/qahw_effect_presetreverb.h
+LOCAL_COPY_HEADERS      += inc/qahw_effect_virtualizer.h
+LOCAL_COPY_HEADERS      += inc/qahw_effect_visualizer.h
 
 LOCAL_PRELINK_MODULE    := false
 
diff --git a/qahw_api/Makefile.am b/qahw_api/Makefile.am
index 78b34c4..a2139d9 100644
--- a/qahw_api/Makefile.am
+++ b/qahw_api/Makefile.am
@@ -1,13 +1,21 @@
 AM_CFLAGS = -I $(top_srcdir)/qahw_api/inc
 
 h_sources = inc/qahw_api.h \
-            inc/qahw_defs.h
+            inc/qahw_defs.h \
+            inc/qahw_effect_api.h \
+            inc/qahw_effect_bassboost.h \
+            inc/qahw_effect_environmentalreverb.h \
+            inc/qahw_effect_equalizer.h \
+            inc/qahw_effect_presetreverb.h \
+            inc/qahw_effect_virtualizer.h \
+            inc/qahw_effect_visualizer.h
 
 library_include_HEADERS = $(h_sources)
 library_includedir = $(includedir)/mm-audio/qahw_api/inc
 
 lib_LTLIBRARIES = libqahw.la
-libqahw_la_SOURCES = src/qahw.c
+libqahw_la_SOURCES = src/qahw.c \
+                     src/qahw_effect.c
 libqahw_la_CFLAGS = $(AM_CFLAGS) -include stddef.h
 libqahw_la_CFLAGS += -D__unused=__attribute__\(\(__unused__\)\)
 libqahw_la_LIBADD = -llog -lcutils -lhardware
diff --git a/qahw_api/inc/qahw_effect_api.h b/qahw_api/inc/qahw_effect_api.h
new file mode 100644
index 0000000..a6fbcc2
--- /dev/null
+++ b/qahw_api/inc/qahw_effect_api.h
@@ -0,0 +1,839 @@
+/*
+ * Copyright (c) 2017, The Linux Foundation. All rights reserved.
+ * Not a Contribution.
+ *
+ * Copyright (C) 2011 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_AUDIO_QAHW_EFFECT_H
+#define ANDROID_AUDIO_QAHW_EFFECT_H
+
+#include <errno.h>
+#include <stdint.h>
+#include <strings.h>
+#include <sys/cdefs.h>
+#include <sys/types.h>
+
+#include <cutils/bitops.h>
+
+#include <system/audio.h>
+
+#include "qahw_api.h"
+
+__BEGIN_DECLS
+
+#define QAHW_EFFECT_API_VERSION_0_0 QAHW_MAKE_API_VERSION(0, 0)
+#define QAHW_EFFECT_API_VERSION_MIN QAHW_EFFECT_API_VERSION_0_0
+
+/////////////////////////////////////////////////
+//      Common Definitions
+/////////////////////////////////////////////////
+
+//
+//--- Effect descriptor structure qahw_effect_descriptor_t
+//
+
+// Unique effect ID (can be generated from the following site:
+//  http://www.itu.int/ITU-T/asn1/uuid.html)
+// This format is used for both "type" and "uuid" fields of the effect descriptor structure.
+// - When used for effect type and the engine is implementing and effect corresponding to a standard
+// OpenSL ES interface, this ID must be the one defined in OpenSLES_IID.h for that interface.
+// - When used as uuid, it should be a unique UUID for this particular implementation.
+typedef struct qahw_effect_uuid_s {
+    uint32_t timeLow;
+    uint16_t timeMid;
+    uint16_t timeHiAndVersion;
+    uint16_t clockSeq;
+    uint8_t node[6];
+} qahw_effect_uuid_t;
+
+// Maximum length of character strings in structures defines by this API.
+#define QAHW_EFFECT_STRING_LEN_MAX 64
+
+// NULL UUID definition (matches SL_IID_NULL_)
+#define QAHW_EFFECT_UUID_INITIALIZER { 0xec7178ec, 0xe5e1, 0x4432, 0xa3f4, \
+                                     { 0x46, 0x57, 0xe6, 0x79, 0x52, 0x10 } }
+static const qahw_effect_uuid_t QAHW_EFFECT_UUID_NULL_ = QAHW_EFFECT_UUID_INITIALIZER;
+static const qahw_effect_uuid_t * const QAHW_EFFECT_UUID_NULL = &QAHW_EFFECT_UUID_NULL_;
+static const char * const QAHW_EFFECT_UUID_NULL_STR = "ec7178ec-e5e1-4432-a3f4-4657e6795210";
+
+
+// The effect descriptor contains necessary information to facilitate the enumeration of the effect
+// engines present in a library.
+typedef struct qahw_effect_descriptor_s {
+    qahw_effect_uuid_t type;     // UUID of to the OpenSL ES interface implemented by this effect
+    qahw_effect_uuid_t uuid;     // UUID for this particular implementation
+    uint32_t      apiVersion;    // Version of the effect control API implemented
+    uint32_t      flags;         // effect engine capabilities/requirements flags (see below)
+    uint16_t      cpuLoad;       // CPU load indication (see below)
+    uint16_t      memoryUsage;   // Data Memory usage (see below)
+    char    name[QAHW_EFFECT_STRING_LEN_MAX];   // human readable effect name
+    char    implementor[QAHW_EFFECT_STRING_LEN_MAX];    // human readable effect implementor name
+} qahw_effect_descriptor_t;
+
+#define QAHW_EFFECT_MAKE_API_VERSION(M, m)  (((M)<<16) | ((m) & 0xFFFF))
+#define QAHW_EFFECT_API_VERSION_MAJOR(v)    ((v)>>16)
+#define QAHW_EFFECT_API_VERSION_MINOR(v)    ((m) & 0xFFFF)
+
+
+/////////////////////////////////////////////////
+//      Effect control interface
+/////////////////////////////////////////////////
+
+// Effect control interface version 2.0
+#define QAHW_EFFECT_CONTROL_API_VERSION QAHW_EFFECT_MAKE_API_VERSION(2,0)
+
+typedef void* qahw_effect_handle_t;
+
+
+// Forward definition of type qahw_audio_buffer_t
+typedef struct qahw_audio_buffer_s qahw_audio_buffer_t;
+
+
+//
+//--- Standardized command codes for command() function
+//
+enum qahw_effect_command_e {
+   QAHW_EFFECT_CMD_INIT,                 // initialize effect engine
+   QAHW_EFFECT_CMD_SET_CONFIG,           // configure effect engine (see effect_config_t)
+   QAHW_EFFECT_CMD_RESET,                // reset effect engine
+   QAHW_EFFECT_CMD_ENABLE,               // enable effect process
+   QAHW_EFFECT_CMD_DISABLE,              // disable effect process
+   QAHW_EFFECT_CMD_SET_PARAM,            // set parameter immediately (see effect_param_t)
+   QAHW_EFFECT_CMD_SET_PARAM_DEFERRED,   // set parameter deferred
+   QAHW_EFFECT_CMD_SET_PARAM_COMMIT,     // commit previous set parameter deferred
+   QAHW_EFFECT_CMD_GET_PARAM,            // get parameter
+   QAHW_EFFECT_CMD_SET_DEVICE,           // set audio device (see audio.h, audio_devices_t)
+   QAHW_EFFECT_CMD_SET_VOLUME,           // set volume
+   QAHW_EFFECT_CMD_SET_AUDIO_MODE,       // set the audio mode (normal, ring, ...)
+   QAHW_EFFECT_CMD_SET_CONFIG_REVERSE,   // configure effect engine reverse stream(see effect_config_t)
+   QAHW_EFFECT_CMD_SET_INPUT_DEVICE,     // set capture device (see audio.h, audio_devices_t)
+   QAHW_EFFECT_CMD_GET_CONFIG,           // read effect engine configuration
+   QAHW_EFFECT_CMD_GET_CONFIG_REVERSE,   // read configure effect engine reverse stream configuration
+   QAHW_EFFECT_CMD_GET_FEATURE_SUPPORTED_CONFIGS,// get all supported configurations for a feature.
+   QAHW_EFFECT_CMD_GET_FEATURE_CONFIG,   // get current feature configuration
+   QAHW_EFFECT_CMD_SET_FEATURE_CONFIG,   // set current feature configuration
+   QAHW_EFFECT_CMD_SET_AUDIO_SOURCE,     // set the audio source (see audio.h, audio_source_t)
+   QAHW_EFFECT_CMD_OFFLOAD,              // set if effect thread is an offload one,
+                                         // send the ioHandle of the effect thread
+   QAHW_EFFECT_CMD_FIRST_PROPRIETARY = 0x10000 // first proprietary command code
+};
+
+//==================================================================================================
+// command: QAHW_EFFECT_CMD_INIT
+//--------------------------------------------------------------------------------------------------
+// description:
+//  Initialize effect engine: All configurations return to default
+//--------------------------------------------------------------------------------------------------
+// command format:
+//  size: 0
+//  data: N/A
+//--------------------------------------------------------------------------------------------------
+// reply format:
+//  size: sizeof(int)
+//  data: status
+//==================================================================================================
+// command: QAHW_EFFECT_CMD_SET_CONFIG
+//--------------------------------------------------------------------------------------------------
+// description:
+//  Apply new audio parameters configurations for input and output buffers
+//--------------------------------------------------------------------------------------------------
+// command format:
+//  size: sizeof(effect_config_t)
+//  data: effect_config_t
+//--------------------------------------------------------------------------------------------------
+// reply format:
+//  size: sizeof(int)
+//  data: status
+//==================================================================================================
+// command: QAHW_EFFECT_CMD_RESET
+//--------------------------------------------------------------------------------------------------
+// description:
+//  Reset the effect engine. Keep configuration but resets state and buffer content
+//--------------------------------------------------------------------------------------------------
+// command format:
+//  size: 0
+//  data: N/A
+//--------------------------------------------------------------------------------------------------
+// reply format:
+//  size: 0
+//  data: N/A
+//==================================================================================================
+// command: QAHW_EFFECT_CMD_ENABLE
+//--------------------------------------------------------------------------------------------------
+// description:
+//  Enable the process. Called by the framework before the first call to process()
+//--------------------------------------------------------------------------------------------------
+// command format:
+//  size: 0
+//  data: N/A
+//--------------------------------------------------------------------------------------------------
+// reply format:
+//  size: sizeof(int)
+//  data: status
+//==================================================================================================
+// command: QAHW_EFFECT_CMD_DISABLE
+//--------------------------------------------------------------------------------------------------
+// description:
+//  Disable the process. Called by the framework after the last call to process()
+//--------------------------------------------------------------------------------------------------
+// command format:
+//  size: 0
+//  data: N/A
+//--------------------------------------------------------------------------------------------------
+// reply format:
+//  size: sizeof(int)
+//  data: status
+//==================================================================================================
+// command: QAHW_EFFECT_CMD_SET_PARAM
+//--------------------------------------------------------------------------------------------------
+// description:
+//  Set a parameter and apply it immediately
+//--------------------------------------------------------------------------------------------------
+// command format:
+//  size: sizeof(effect_param_t) + size of param and value
+//  data: effect_param_t + param + value. See effect_param_t definition below for value offset
+//--------------------------------------------------------------------------------------------------
+// reply format:
+//  size: sizeof(int)
+//  data: status
+//==================================================================================================
+// command: QAHW_EFFECT_CMD_SET_PARAM_DEFERRED
+//--------------------------------------------------------------------------------------------------
+// description:
+//  Set a parameter but apply it only when receiving QAHW_EFFECT_CMD_SET_PARAM_COMMIT command
+//--------------------------------------------------------------------------------------------------
+// command format:
+//  size: sizeof(effect_param_t) + size of param and value
+//  data: effect_param_t + param + value. See effect_param_t definition below for value offset
+//--------------------------------------------------------------------------------------------------
+// reply format:
+//  size: 0
+//  data: N/A
+//==================================================================================================
+// command: QAHW_EFFECT_CMD_SET_PARAM_COMMIT
+//--------------------------------------------------------------------------------------------------
+// description:
+//  Apply all previously received QAHW_EFFECT_CMD_SET_PARAM_DEFERRED commands
+//--------------------------------------------------------------------------------------------------
+// command format:
+//  size: 0
+//  data: N/A
+//--------------------------------------------------------------------------------------------------
+// reply format:
+//  size: sizeof(int)
+//  data: status
+//==================================================================================================
+// command: QAHW_EFFECT_CMD_GET_PARAM
+//--------------------------------------------------------------------------------------------------
+// description:
+//  Get a parameter value
+//--------------------------------------------------------------------------------------------------
+// command format:
+//  size: sizeof(effect_param_t) + size of param
+//  data: effect_param_t + param
+//--------------------------------------------------------------------------------------------------
+// reply format:
+//  size: sizeof(effect_param_t) + size of param and value
+//  data: effect_param_t + param + value. See effect_param_t definition below for value offset
+//==================================================================================================
+// command: QAHW_EFFECT_CMD_SET_DEVICE
+//--------------------------------------------------------------------------------------------------
+// description:
+//  Set the rendering device the audio output path is connected to. See audio.h, audio_devices_t
+//  for device values.
+//  The effect implementation must set QAHW_EFFECT_FLAG_DEVICE_IND flag in its descriptor to receive this
+//  command when the device changes
+//--------------------------------------------------------------------------------------------------
+// command format:
+//  size: sizeof(uint32_t)
+//  data: uint32_t
+//--------------------------------------------------------------------------------------------------
+// reply format:
+//  size: 0
+//  data: N/A
+//==================================================================================================
+// command: QAHW_EFFECT_CMD_SET_VOLUME
+//--------------------------------------------------------------------------------------------------
+// description:
+//  Set and get volume. Used by audio framework to delegate volume control to effect engine.
+//  The effect implementation must set QAHW_EFFECT_FLAG_VOLUME_IND or QAHW_EFFECT_FLAG_VOLUME_CTRL flag in
+//  its descriptor to receive this command before every call to process() function
+//  If QAHW_EFFECT_FLAG_VOLUME_CTRL flag is set in the effect descriptor, the effect engine must return
+//  the volume that should be applied before the effect is processed. The overall volume (the volume
+//  actually applied by the effect engine multiplied by the returned value) should match the value
+//  indicated in the command.
+//--------------------------------------------------------------------------------------------------
+// command format:
+//  size: n * sizeof(uint32_t)
+//  data: volume for each channel defined in effect_config_t for output buffer expressed in
+//      8.24 fixed point format
+//--------------------------------------------------------------------------------------------------
+// reply format:
+//  size: n * sizeof(uint32_t) / 0
+//  data: - if QAHW_EFFECT_FLAG_VOLUME_CTRL is set in effect descriptor:
+//              volume for each channel defined in effect_config_t for output buffer expressed in
+//              8.24 fixed point format
+//        - if QAHW_EFFECT_FLAG_VOLUME_CTRL is not set in effect descriptor:
+//              N/A
+//  It is legal to receive a null pointer as pReplyData in which case the effect framework has
+//  delegated volume control to another effect
+//==================================================================================================
+// command: QAHW_EFFECT_CMD_SET_AUDIO_MODE
+//--------------------------------------------------------------------------------------------------
+// description:
+//  Set the audio mode. The effect implementation must set QAHW_EFFECT_FLAG_AUDIO_MODE_IND flag in its
+//  descriptor to receive this command when the audio mode changes.
+//--------------------------------------------------------------------------------------------------
+// command format:
+//  size: sizeof(uint32_t)
+//  data: audio_mode_t
+//--------------------------------------------------------------------------------------------------
+// reply format:
+//  size: 0
+//  data: N/A
+//==================================================================================================
+// command: QAHW_EFFECT_CMD_SET_CONFIG_REVERSE
+//--------------------------------------------------------------------------------------------------
+// description:
+//  Apply new audio parameters configurations for input and output buffers of reverse stream.
+//  An example of reverse stream is the echo reference supplied to an Acoustic Echo Canceler.
+//--------------------------------------------------------------------------------------------------
+// command format:
+//  size: sizeof(effect_config_t)
+//  data: effect_config_t
+//--------------------------------------------------------------------------------------------------
+// reply format:
+//  size: sizeof(int)
+//  data: status
+//==================================================================================================
+// command: QAHW_EFFECT_CMD_SET_INPUT_DEVICE
+//--------------------------------------------------------------------------------------------------
+// description:
+//  Set the capture device the audio input path is connected to. See audio.h, audio_devices_t
+//  for device values.
+//  The effect implementation must set QAHW_EFFECT_FLAG_DEVICE_IND flag in its descriptor to receive this
+//  command when the device changes
+//--------------------------------------------------------------------------------------------------
+// command format:
+//  size: sizeof(uint32_t)
+//  data: uint32_t
+//--------------------------------------------------------------------------------------------------
+// reply format:
+//  size: 0
+//  data: N/A
+//==================================================================================================
+// command: QAHW_EFFECT_CMD_GET_CONFIG
+//--------------------------------------------------------------------------------------------------
+// description:
+//  Read audio parameters configurations for input and output buffers
+//--------------------------------------------------------------------------------------------------
+// command format:
+//  size: 0
+//  data: N/A
+//--------------------------------------------------------------------------------------------------
+// reply format:
+//  size: sizeof(effect_config_t)
+//  data: effect_config_t
+//==================================================================================================
+// command: QAHW_EFFECT_CMD_GET_CONFIG_REVERSE
+//--------------------------------------------------------------------------------------------------
+// description:
+//  Read audio parameters configurations for input and output buffers of reverse stream
+//--------------------------------------------------------------------------------------------------
+// command format:
+//  size: 0
+//  data: N/A
+//--------------------------------------------------------------------------------------------------
+// reply format:
+//  size: sizeof(effect_config_t)
+//  data: effect_config_t
+//==================================================================================================
+// command: QAHW_EFFECT_CMD_GET_FEATURE_SUPPORTED_CONFIGS
+//--------------------------------------------------------------------------------------------------
+// description:
+//  Queries for supported configurations for a particular feature (e.g. get the supported
+// combinations of main and auxiliary channels for a noise suppressor).
+// The command parameter is the feature identifier (See effect_feature_e for a list of defined
+// features) followed by the maximum number of configuration descriptor to return.
+// The reply is composed of:
+//  - status (uint32_t):
+//          - 0 if feature is supported
+//          - -ENOSYS if the feature is not supported,
+//          - -ENOMEM if the feature is supported but the total number of supported configurations
+//          exceeds the maximum number indicated by the caller.
+//  - total number of supported configurations (uint32_t)
+//  - an array of configuration descriptors.
+// The actual number of descriptors returned must not exceed the maximum number indicated by
+// the caller.
+//--------------------------------------------------------------------------------------------------
+// command format:
+//  size: 2 x sizeof(uint32_t)
+//  data: effect_feature_e + maximum number of configurations to return
+//--------------------------------------------------------------------------------------------------
+// reply format:
+//  size: 2 x sizeof(uint32_t) + n x sizeof (<config descriptor>)
+//  data: status + total number of configurations supported + array of n config descriptors
+//==================================================================================================
+// command: QAHW_EFFECT_CMD_GET_FEATURE_CONFIG
+//--------------------------------------------------------------------------------------------------
+// description:
+//  Retrieves current configuration for a given feature.
+// The reply status is:
+//      - 0 if feature is supported
+//      - -ENOSYS if the feature is not supported,
+//--------------------------------------------------------------------------------------------------
+// command format:
+//  size: sizeof(uint32_t)
+//  data: effect_feature_e
+//--------------------------------------------------------------------------------------------------
+// reply format:
+//  size: sizeof(uint32_t) + sizeof (<config descriptor>)
+//  data: status + config descriptor
+//==================================================================================================
+// command: QAHW_EFFECT_CMD_SET_FEATURE_CONFIG
+//--------------------------------------------------------------------------------------------------
+// description:
+//  Sets current configuration for a given feature.
+// The reply status is:
+//      - 0 if feature is supported
+//      - -ENOSYS if the feature is not supported,
+//      - -EINVAL if the configuration is invalid
+//--------------------------------------------------------------------------------------------------
+// command format:
+//  size: sizeof(uint32_t) + sizeof (<config descriptor>)
+//  data: effect_feature_e + config descriptor
+//--------------------------------------------------------------------------------------------------
+// reply format:
+//  size: sizeof(uint32_t)
+//  data: status
+//==================================================================================================
+// command: QAHW_EFFECT_CMD_SET_AUDIO_SOURCE
+//--------------------------------------------------------------------------------------------------
+// description:
+//  Set the audio source the capture path is configured for (Camcorder, voice recognition...).
+//  See audio.h, audio_source_t for values.
+//--------------------------------------------------------------------------------------------------
+// command format:
+//  size: sizeof(uint32_t)
+//  data: uint32_t
+//--------------------------------------------------------------------------------------------------
+// reply format:
+//  size: 0
+//  data: N/A
+//==================================================================================================
+// command: QAHW_EFFECT_CMD_OFFLOAD
+//--------------------------------------------------------------------------------------------------
+// description:
+//  1.indicate if the playback thread the effect is attached to is offloaded or not
+//  2.update the io handle of the playback thread the effect is attached to
+//--------------------------------------------------------------------------------------------------
+// command format:
+//  size: sizeof(effect_offload_param_t)
+//  data: effect_offload_param_t
+//--------------------------------------------------------------------------------------------------
+// reply format:
+//  size: sizeof(uint32_t)
+//  data: uint32_t
+//--------------------------------------------------------------------------------------------------
+// command: QAHW_EFFECT_CMD_FIRST_PROPRIETARY
+//--------------------------------------------------------------------------------------------------
+// description:
+//  All proprietary effect commands must use command codes above this value. The size and format of
+//  command and response fields is free in this case
+//==================================================================================================
+
+
+// Audio buffer descriptor used by process(), bufferProvider() functions and buffer_config_t
+// structure. Multi-channel audio is always interleaved. The channel order is from LSB to MSB with
+// regard to the channel mask definition in audio.h, audio_channel_mask_t e.g :
+// Stereo: left, right
+// 5 point 1: front left, front right, front center, low frequency, back left, back right
+// The buffer size is expressed in frame count, a frame being composed of samples for all
+// channels at a given time. Frame size for unspecified format (AUDIO_FORMAT_OTHER) is 8 bit by
+// definition
+struct qahw_audio_buffer_s {
+    size_t   frameCount;        // number of frames in buffer
+    union {
+        void*       raw;        // raw pointer to start of buffer
+        int32_t*    s32;        // pointer to signed 32 bit data at start of buffer
+        int16_t*    s16;        // pointer to signed 16 bit data at start of buffer
+        uint8_t*    u8;         // pointer to unsigned 8 bit data at start of buffer
+    };
+};
+
+// The buffer_provider_s structure contains functions that can be used
+// by the effect engine process() function to query and release input
+// or output audio buffer.
+// The getBuffer() function is called to retrieve a buffer where data
+// should read from or written to by process() function.
+// The releaseBuffer() function MUST be called when the buffer retrieved
+// with getBuffer() is not needed anymore.
+// The process function should use the buffer provider mechanism to retrieve
+// input or output buffer if the in_buffer or out_buffer passed as argument is NULL
+// and the buffer configuration (buffer_config_t) given by the QAHW_EFFECT_CMD_SET_CONFIG
+// command did not specify an audio buffer.
+
+typedef int32_t (* qahw_buffer_function_t)(void *cookie, qahw_audio_buffer_t *buffer);
+
+typedef struct qahw_buffer_provider_s {
+    qahw_buffer_function_t getBuffer;       // retrieve next buffer
+    qahw_buffer_function_t releaseBuffer;   // release used buffer
+    void       *cookie;                // for use by client of buffer provider functions
+} qahw_buffer_provider_t;
+
+
+// The qahw_buffer_config_s structure specifies the input or output audio format
+// to be used by the effect engine. It is part of the effect_config_t
+// structure that defines both input and output buffer configurations and is
+// passed by the QAHW_EFFECT_CMD_SET_CONFIG or QAHW_EFFECT_CMD_SET_CONFIG_REVERSE command.
+typedef struct qahw_buffer_config_s {
+    qahw_audio_buffer_t  buffer; // buffer for use by process() function if not passed explicitly
+    uint32_t   samplingRate;     // sampling rate
+    uint32_t   channels;         // channel mask (see audio_channel_mask_t in audio.h)
+    qahw_buffer_provider_t bufferProvider;   // buffer provider
+    uint8_t    format;           // Audio format (see audio_format_t in audio.h)
+    uint8_t    accessMode;       // read/write or accumulate in buffer (qahw_effect_buffer_access_e)
+    uint16_t   mask;             // indicates which of the above fields is valid
+} qahw_buffer_config_t;
+
+// Values for "accessMode" field of buffer_config_t:
+//   overwrite, read only, accumulate (read/modify/write)
+enum qahw_effect_buffer_access_e {
+    QAHW_EFFECT_BUFFER_ACCESS_WRITE,
+    QAHW_EFFECT_BUFFER_ACCESS_READ,
+    QAHW_EFFECT_BUFFER_ACCESS_ACCUMULATE
+
+};
+
+// feature identifiers for QAHW_EFFECT_CMD_GET_FEATURE_SUPPORTED_CONFIGS command
+enum qahw_effect_feature_e {
+    QAHW_EFFECT_FEATURE_AUX_CHANNELS, // supports auxiliary channels (e.g. dual mic noise suppressor)
+    QAHW_EFFECT_FEATURE_CNT
+};
+
+// QAHW_EFFECT_FEATURE_AUX_CHANNELS feature configuration descriptor. Describe a combination
+// of main and auxiliary channels supported
+typedef struct qahw_channel_config_s {
+    audio_channel_mask_t main_channels; // channel mask for main channels
+    audio_channel_mask_t aux_channels;  // channel mask for auxiliary channels
+} qahw_channel_config_t;
+
+
+// Values for bit field "mask" in buffer_config_t. If a bit is set, the corresponding field
+// in buffer_config_t must be taken into account when executing the QAHW_EFFECT_CMD_SET_CONFIG command
+#define QAHW_EFFECT_CONFIG_BUFFER    0x0001  // buffer field must be taken into account
+#define QAHW_EFFECT_CONFIG_SMP_RATE  0x0002  // samplingRate field must be taken into account
+#define QAHW_EFFECT_CONFIG_CHANNELS  0x0004  // channels field must be taken into account
+#define QAHW_EFFECT_CONFIG_FORMAT    0x0008  // format field must be taken into account
+#define QAHW_EFFECT_CONFIG_ACC_MODE  0x0010  // accessMode field must be taken into account
+#define QAHW_EFFECT_CONFIG_PROVIDER  0x0020  // bufferProvider field must be taken into account
+#define QAHW_EFFECT_CONFIG_ALL (QAHW_EFFECT_CONFIG_BUFFER | QAHW_EFFECT_CONFIG_SMP_RATE | \
+                                QAHW_EFFECT_CONFIG_CHANNELS | QAHW_EFFECT_CONFIG_FORMAT | \
+                                QAHW_EFFECT_CONFIG_ACC_MODE | QAHW_EFFECT_CONFIG_PROVIDER)
+
+
+// effect_config_s structure describes the format of the pCmdData argument of QAHW_EFFECT_CMD_SET_CONFIG
+// command to configure audio parameters and buffers for effect engine input and output.
+typedef struct qahw_effect_config_s {
+    qahw_buffer_config_t   input_cfg;
+    qahw_buffer_config_t   output_cfg;
+} qahw_effect_config_t;
+
+
+// effect_param_s structure describes the format of the pCmdData argument of QAHW_EFFECT_CMD_SET_PARAM
+// command and pCmdData and pReplyData of QAHW_EFFECT_CMD_GET_PARAM command.
+// psize and vsize represent the actual size of parameter and value.
+//
+// NOTE: the start of value field inside the data field is always on a 32 bit boundary:
+//
+//  +-----------+
+//  | status    | sizeof(int)
+//  +-----------+
+//  | psize     | sizeof(int)
+//  +-----------+
+//  | vsize     | sizeof(int)
+//  +-----------+
+//  |           |   |           |
+//  ~ parameter ~   > psize     |
+//  |           |   |           >  ((psize - 1)/sizeof(int) + 1) * sizeof(int)
+//  +-----------+               |
+//  | padding   |               |
+//  +-----------+
+//  |           |   |
+//  ~ value     ~   > vsize
+//  |           |   |
+//  +-----------+
+
+typedef struct qahw_effect_param_s {
+    int32_t     status;     // Transaction status (unused for command, used for reply)
+    uint32_t    psize;      // Parameter size
+    uint32_t    vsize;      // Value size
+    char        data[];     // Start of Parameter + Value data
+} qahw_effect_param_t;
+
+// structure used by QAHW_EFFECT_CMD_OFFLOAD command
+typedef struct qahw_effect_offload_param_s {
+    bool isOffload;         // true if the playback thread the effect is attached to is offloaded
+    int ioHandle;           // io handle of the playback thread the effect is attached to
+} qahw_effect_offload_param_t;
+
+
+/////////////////////////////////////////////////
+//      Effect library interface
+/////////////////////////////////////////////////
+
+// Effect library interface version 3.0
+// Note that EffectsFactory.c only checks the major version component, so changes to the minor
+// number can only be used for fully backwards compatible changes
+#define QAHW_EFFECT_LIBRARY_API_VERSION QAHW_EFFECT_MAKE_API_VERSION(3, 0)
+
+typedef void* qahw_effect_lib_handle_t;
+
+////////////////////////////////////////////////////////////////////////////////
+//
+//    Function:       qahw_effect_load_library
+//
+//    Description:    Loads an effect library
+//
+//    Input:
+//        lib_name:   Effect library name.
+//
+//    Output:
+//        returned value:    NULL       if fails to load library.
+//                           valid effect library handle
+//
+////////////////////////////////////////////////////////////////////////////////
+qahw_effect_lib_handle_t qahw_effect_load_library(const char *lib_name);
+
+////////////////////////////////////////////////////////////////////////////////
+//
+//    Function:       qahw_effect_unload_library
+//
+//    Description:    Unload the audio effect library
+//
+//    Input:
+//        handle:     Effect library handle.
+//
+//    Output:
+//        returned value:    0          successful operation.
+//                          -EINVAL     invalid effect library handle
+//
+////////////////////////////////////////////////////////////////////////////////
+int32_t qahw_effect_unload_library(qahw_effect_lib_handle_t handle);
+
+////////////////////////////////////////////////////////////////////////////////
+//
+//    Function:       qahw_effect_create
+//
+//    Description:    Creates an effect engine of the specified implementation uuid and
+//          returns an effect control interface on this engine. The function will allocate the
+//          resources for an instance of the requested effect engine and return
+//          a handle on the effect control interface.
+//
+//    Input:
+//          handle:     handle on the effect library.
+//          uuid:       pointer to the effect uuid.
+//          sessionId:  audio session to which this effect instance will be attached.
+//                      All effects created with the same session ID are connected in series
+//                      and process the same signal stream. Knowing that two effects are part
+//                      of the same effect chain can help the library implement some kind of
+//                      optimizations.
+//          io_handle:  identifies the output or input stream this effect is directed to in
+//                      audio HAL.
+//                      For future use especially with tunneled HW accelerated effects
+//
+//    Input/Output:
+//          effect_handle:   address where to return the effect interface handle.
+//
+//    Output:
+//        returned value:    0          successful operation.
+//                          -ENODEV     library failed to initialize
+//                          -EINVAL     invalid pEffectUuid or effect_handle
+//                          -ENOENT     no effect with this uuid found
+//        *effect_handle:    updated with the effect interface handle.
+//
+////////////////////////////////////////////////////////////////////////////////
+int32_t qahw_effect_create(qahw_effect_lib_handle_t handle,
+                           const qahw_effect_uuid_t *uuid,
+                           int32_t io_handle,
+                           qahw_effect_handle_t *effect_handle);
+
+////////////////////////////////////////////////////////////////////////////////
+//
+//    Function:       qahw_effect_release
+//
+//    Description:    Releases the effect engine whose handle is given as argument.
+//          All resources allocated to this particular instance of the effect are
+//          released.
+//
+//    Input:
+//          handle:         handle on the effect library.
+//          effect_handle:  handle on the effect interface to be released.
+//
+//    Output:
+//        returned value:    0          successful operation.
+//                          -EINVAL     invalid interface handle
+//
+////////////////////////////////////////////////////////////////////////////////
+int32_t qahw_effect_release(qahw_effect_lib_handle_t handle,
+                            qahw_effect_handle_t effect_handle);
+
+////////////////////////////////////////////////////////////////////////////////
+//
+//    Function:        qahw_effect_get_descriptor
+//
+//    Description:     Returns the descriptor of the effect engine which implementation UUID is
+//          given as argument.
+//
+//    Input/Output:
+//          handle:         handle on the effect library.
+//          uuid:           pointer to the effect uuid.
+//          effect_desc:    address where to return the effect descriptor.
+//
+//    Output:
+//        returned value:    0          successful operation.
+//                          -ENODEV     library failed to initialize
+//                          -EINVAL     invalid effect_desc or uuid
+//        *effect_desc:     updated with the effect descriptor.
+//
+////////////////////////////////////////////////////////////////////////////////
+int32_t qahw_effect_get_descriptor(qahw_effect_lib_handle_t handle,
+                                   const qahw_effect_uuid_t *uuid,
+                                   qahw_effect_descriptor_t *effect_desc);
+
+////////////////////////////////////////////////////////////////////////////////
+//
+//    Function:        qahw_effect_get_version
+//
+//    Description:     Get version of IOT effect APIs.
+//
+//    Output:
+//        returned value:    version number
+//
+////////////////////////////////////////////////////////////////////////////////
+int32_t qahw_effect_get_version();
+
+////////////////////////////////////////////////////////////////////////////////
+//
+//    Function:        qahw_effect_process
+//
+//    Description:     Effect process function. Takes input samples as specified
+//          (count and location) in input buffer descriptor and output processed
+//          samples as specified in output buffer descriptor. If the buffer descriptor
+//          is not specified the function must use either the buffer or the
+//          buffer provider function installed by the QAHW_EFFECT_CMD_SET_CONFIG command.
+//          The effect framework will call the process() function after the QAHW_EFFECT_CMD_ENABLE
+//          command is received and until the QAHW_EFFECT_CMD_DISABLE is received. When the engine
+//          receives the QAHW_EFFECT_CMD_DISABLE command it should turn off the effect gracefully
+//          and when done indicate that it is OK to stop calling the process() function by
+//          returning the -ENODATA status.
+//
+//    NOTE: the process() function implementation should be "real-time safe" that is
+//      it should not perform blocking calls: malloc/free, sleep, read/write/open/close,
+//      pthread_cond_wait/pthread_mutex_lock...
+//
+//    Input:
+//          self:       handle to the effect interface this function is called on.
+//          in_buffer:  buffer descriptor indicating where to read samples to process.
+//                      If NULL, use the configuration passed by QAHW_EFFECT_CMD_SET_CONFIG command.
+//          out_buffer: buffer descriptor indicating where to write processed samples.
+//                      If NULL, use the configuration passed by QAHW_EFFECT_CMD_SET_CONFIG command.
+//
+//    Output:
+//        returned value:    0 successful operation
+//                          -ENODATA the engine has finished the disable phase and the framework
+//                                  can stop calling process()
+//                          -EINVAL invalid interface handle or
+//                                  invalid input/output buffer description
+////////////////////////////////////////////////////////////////////////////////
+int32_t qahw_effect_process(qahw_effect_handle_t self,
+                            qahw_audio_buffer_t *in_buffer,
+                            qahw_audio_buffer_t *out_buffer);
+////////////////////////////////////////////////////////////////////////////////
+//
+//    Function:       qahw_effect_command
+//
+//    Description:    Send a command and receive a response to/from effect engine.
+//
+//    Input:
+//          self:       handle to the effect interface this function is called on.
+//          cmd_code:   command code: the command can be a standardized command defined in
+//                      qahw_effect_command_e (see below) or a proprietary command.
+//          cmd_size:   size of command in bytes
+//          cmd_data:   pointer to command data
+//          reply_data: pointer to reply data
+//
+//    Input/Output:
+//          reply_size: maximum size of reply data as input
+//                      actual size of reply data as output
+//
+//    Output:
+//          returned value: 0       successful operation
+//                          -EINVAL invalid interface handle or
+//                                  invalid command/reply size or format according to
+//                                  command code
+//              The return code should be restricted to indicate problems related to this API
+//              specification. Status related to the execution of a particular command should be
+//              indicated as part of the reply field.
+//
+//          *reply_data updated with command response
+//
+////////////////////////////////////////////////////////////////////////////////
+int32_t qahw_effect_command(qahw_effect_handle_t self,
+                            uint32_t cmd_code,
+                            uint32_t cmd_size,
+                            void *cmd_data,
+                            uint32_t *reply_size,
+                            void *reply_data);
+
+////////////////////////////////////////////////////////////////////////////////
+//
+//    Function:       qahw_effect_process_reverse
+//
+//    Description:    Process reverse stream function. This function is used to pass
+//          a reference stream to the effect engine. If the engine does not need a reference
+//          stream, this function pointer can be set to NULL.
+//          This function would typically implemented by an Echo Canceler.
+//
+//    Input:
+//          self:       handle to the effect interface this function is called on.
+//          in_buffer:  buffer descriptor indicating where to read samples to process.
+//                      If NULL, use the configuration passed by
+//                      QAHW_EFFECT_CMD_SET_CONFIG_REVERSE command.
+//
+//          out_buffer: buffer descriptor indicating where to write processed samples.
+//                      If NULL, use the configuration passed by
+//                      QAHW_EFFECT_CMD_SET_CONFIG_REVERSE command.
+//              If the buffer and buffer provider in the configuration received by
+//              QAHW_EFFECT_CMD_SET_CONFIG_REVERSE are also NULL, do not return modified reverse
+//              stream data
+//
+//    Output:
+//        returned value:    0 successful operation
+//                          -ENODATA the engine has finished the disable phase and the framework
+//                                  can stop calling process_reverse()
+//                          -EINVAL invalid interface handle or
+//                                  invalid input/output buffer description
+////////////////////////////////////////////////////////////////////////////////
+int32_t qahw_effect_process_reverse(qahw_effect_handle_t self,
+                                    qahw_audio_buffer_t *in_buffer,
+                                    qahw_audio_buffer_t *out_buffer);
+
+
+__END_DECLS
+
+#endif  // ANDROID_AUDIO_QAHW_EFFECT_H
diff --git a/qahw_api/inc/qahw_effect_bassboost.h b/qahw_api/inc/qahw_effect_bassboost.h
new file mode 100644
index 0000000..376c4a7
--- /dev/null
+++ b/qahw_api/inc/qahw_effect_bassboost.h
@@ -0,0 +1,51 @@
+/*
+ * Copyright (c) 2017, The Linux Foundation. All rights reserved.
+ * Not a Contribution.
+ *
+ * Copyright (C) 2011 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 QAHW_EFFECT_BASSBOOST_H_
+#define QAHW_EFFECT_BASSBOOST_H_
+
+#include <qahw_effect_api.h>
+
+#if __cplusplus
+extern "C" {
+#endif
+
+#define QAHW_EFFECT_BASSBOOST_LIBRARY "libqcompostprocbundle.so"
+
+static const qahw_effect_uuid_t SL_IID_BASSBOOST_ = { 0x0634f220, 0xddd4, 0x11db, 0xa0fc,
+        { 0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b } };
+const qahw_effect_uuid_t * const SL_IID_BASSBOOST = &SL_IID_BASSBOOST_;
+
+static const qahw_effect_uuid_t SL_IID_BASSBOOST_UUID_ = { 0x2c4a8c24, 0x1581, 0x487f, 0x94f6,
+        { 0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b } };
+const qahw_effect_uuid_t * const SL_IID_BASSBOOST_UUID = &SL_IID_BASSBOOST_UUID_;
+
+/* enumerated parameter settings for BassBoost effect */
+typedef enum
+{
+    BASSBOOST_PARAM_STRENGTH_SUPPORTED,
+    BASSBOOST_PARAM_STRENGTH
+} qahw_bassboost_params;
+
+#if __cplusplus
+}  // extern "C"
+#endif
+
+
+#endif /*QAHW_EFFECT_BASSBOOST_H_*/
diff --git a/qahw_api/inc/qahw_effect_environmentalreverb.h b/qahw_api/inc/qahw_effect_environmentalreverb.h
new file mode 100644
index 0000000..9e36ccf
--- /dev/null
+++ b/qahw_api/inc/qahw_effect_environmentalreverb.h
@@ -0,0 +1,81 @@
+/*
+ * Copyright (c) 2017, The Linux Foundation. All rights reserved.
+ * Not a Contribution.
+ *
+ * Copyright (C) 2011 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 QAHW_EFFECT_ENVIRONMENTALREVERB_H_
+#define QAHW_EFFECT_ENVIRONMENTALREVERB_H_
+
+#include <qahw_effect_api.h>
+
+#if __cplusplus
+extern "C" {
+#endif
+
+#define QAHW_EFFECT_ENV_REVERB_LIBRARY "libqcompostprocbundle.so"
+
+static const qahw_effect_uuid_t SL_IID_ENVIRONMENTALREVERB_ = { 0xc2e5d5f0, 0x94bd, 0x4763, 0x9cac,
+        { 0x4e, 0x23, 0x4d, 0x6, 0x83, 0x9e } };
+const qahw_effect_uuid_t * const SL_IID_ENVIRONMENTALREVERB = &SL_IID_ENVIRONMENTALREVERB_;
+
+static const qahw_effect_uuid_t SL_IID_INS_ENVIRONMENTALREVERB_UUID_ = { 0xeb64ea04, 0x973b, 0x43d2, 0x8f5e,
+        { 0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b } };
+const qahw_effect_uuid_t * const SL_IID_INS_ENVIRONMENTALREVERB_UUID = &SL_IID_INS_ENVIRONMENTALREVERB_UUID_;
+
+static const qahw_effect_uuid_t SL_IID_AUX_ENVIRONMENTALREVERB_UUID_ = { 0x79a18026, 0x18fd, 0x4185, 0x8233,
+        { 0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b } };
+const qahw_effect_uuid_t * const SL_IID_AUX_ENVIRONMENTALREVERB_UUID = &SL_IID_AUX_ENVIRONMENTALREVERB_UUID_;
+
+/* enumerated parameter settings for environmental reverb effect */
+typedef enum
+{
+    // Parameters below are as defined in OpenSL ES specification for environmental reverb interface
+    REVERB_PARAM_ROOM_LEVEL,            // in millibels,    range -6000 to 0
+    REVERB_PARAM_ROOM_HF_LEVEL,         // in millibels,    range -4000 to 0
+    REVERB_PARAM_DECAY_TIME,            // in milliseconds, range 100 to 20000
+    REVERB_PARAM_DECAY_HF_RATIO,        // in permilles,    range 100 to 1000
+    REVERB_PARAM_REFLECTIONS_LEVEL,     // in millibels,    range -6000 to 0
+    REVERB_PARAM_REFLECTIONS_DELAY,     // in milliseconds, range 0 to 65
+    REVERB_PARAM_REVERB_LEVEL,          // in millibels,    range -6000 to 0
+    REVERB_PARAM_REVERB_DELAY,          // in milliseconds, range 0 to 65
+    REVERB_PARAM_DIFFUSION,             // in permilles,    range 0 to 1000
+    REVERB_PARAM_DENSITY,               // in permilles,    range 0 to 1000
+    REVERB_PARAM_PROPERTIES,
+    REVERB_PARAM_BYPASS
+} qahw_env_reverb_params;
+
+//t_reverb_settings is equal to SLEnvironmentalReverbSettings defined in OpenSL ES specification.
+typedef struct s_reverb_settings {
+    int16_t     roomLevel;
+    int16_t     roomHFLevel;
+    uint32_t    decayTime;
+    int16_t     decayHFRatio;
+    int16_t     reflectionsLevel;
+    uint32_t    reflectionsDelay;
+    int16_t     reverbLevel;
+    uint32_t    reverbDelay;
+    int16_t     diffusion;
+    int16_t     density;
+} __attribute__((packed)) qahw_reverb_settings;
+
+
+#if __cplusplus
+}  // extern "C"
+#endif
+
+
+#endif /*QAHW_EFFECT_ENVIRONMENTALREVERB_H_*/
diff --git a/qahw_api/inc/qahw_effect_equalizer.h b/qahw_api/inc/qahw_effect_equalizer.h
new file mode 100644
index 0000000..029ea7e
--- /dev/null
+++ b/qahw_api/inc/qahw_effect_equalizer.h
@@ -0,0 +1,84 @@
+/*
+ * Copyright (c) 2017, The Linux Foundation. All rights reserved.
+ * Not a Contribution.
+ *
+ * Copyright (C) 2011 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 QAHW_EFFECT_EQUALIZER_H_
+#define QAHW_EFFECT_EQUALIZER_H_
+
+#include <qahw_effect_api.h>
+
+#if __cplusplus
+extern "C" {
+#endif
+
+#define QAHW_EFFECT_EQUALIZER_LIBRARY "libqcompostprocbundle.so"
+
+static const qahw_effect_uuid_t SL_IID_EQUALIZER_ = { 0x0bed4300, 0xddd6, 0x11db, 0x8f34,
+        { 0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b } };
+const qahw_effect_uuid_t * const SL_IID_EQUALIZER = &SL_IID_EQUALIZER_;
+
+static const qahw_effect_uuid_t SL_IID_EQUALIZER_UUID_ = { 0xa0dac280, 0x401c, 0x11e3, 0x9379,
+        { 0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b } };
+const qahw_effect_uuid_t * const SL_IID_EQUALIZER_UUID = &SL_IID_EQUALIZER_UUID_;
+
+/* enumerated parameters for Equalizer effect */
+typedef enum
+{
+    EQ_PARAM_NUM_BANDS,             // Gets the number of frequency bands that the equalizer
+                                    // supports.
+    EQ_PARAM_LEVEL_RANGE,           // Returns the minimum and maximum band levels supported.
+    EQ_PARAM_BAND_LEVEL,            // Gets/Sets the gain set for the given equalizer band.
+    EQ_PARAM_CENTER_FREQ,           // Gets the center frequency of the given band.
+    EQ_PARAM_BAND_FREQ_RANGE,       // Gets the frequency range of the given frequency band.
+    EQ_PARAM_GET_BAND,              // Gets the band that has the most effect on the given
+                                    // frequency.
+    EQ_PARAM_CUR_PRESET,            // Gets/Sets the current preset.
+    EQ_PARAM_GET_NUM_OF_PRESETS,    // Gets the total number of presets the equalizer supports.
+    EQ_PARAM_GET_PRESET_NAME,       // Gets the preset name based on the index.
+    EQ_PARAM_PROPERTIES             // Gets/Sets all parameters at a time.
+} qahw_equalizer_params;
+
+enum
+{
+    EQ_PRESET_NORMAL = 0,
+    EQ_PRESET_CLASSICAL,
+    EQ_PRESET_DANCE,
+    EQ_PRESET_FLAT,
+    EQ_PRESET_FOLK,
+    EQ_PRESET_HEAVY_METAL,
+    EQ_PRESET_HIPHOP,
+    EQ_PRESET_JAZZ,
+    EQ_PRESET_POP,
+    EQ_PRESET_ROCK,
+    EQ_PRESET_FX_BOOSTER,
+    EQ_PRESET_MAX_NUM,
+};
+
+//t_equalizer_settings groups all current equalizer setting for backup and restore.
+typedef struct s_equalizer_settings {
+    uint16_t curPreset;
+    uint16_t numBands;
+    uint16_t bandLevels[];
+} qahw_equalizer_settings;
+
+#if __cplusplus
+}  // extern "C"
+#endif
+
+
+#endif /*QAHW_EFFECT_EQUALIZER_H_*/
diff --git a/qahw_api/inc/qahw_effect_presetreverb.h b/qahw_api/inc/qahw_effect_presetreverb.h
new file mode 100644
index 0000000..169d40b
--- /dev/null
+++ b/qahw_api/inc/qahw_effect_presetreverb.h
@@ -0,0 +1,67 @@
+/*
+ * Copyright (c) 2017, The Linux Foundation. All rights reserved.
+ * Not a Contribution.
+ *
+ * Copyright (C) 2011 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 QAHW_EFFECT_PRESETREVERB_H_
+#define QAHW_EFFECT_PRESETREVERB_H_
+
+#include <qahw_effect_api.h>
+
+#if __cplusplus
+extern "C" {
+#endif
+
+#define QAHW_EFFECT_PRESET_REVERB_LIBRARY "libqcompostprocbundle.so"
+
+static const qahw_effect_uuid_t SL_IID_PRESETREVERB_ = { 0x47382d60, 0xddd8, 0x11db, 0xbf3a,
+        { 0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b } };
+const qahw_effect_uuid_t * const SL_IID_PRESETREVERB = &SL_IID_PRESETREVERB_;
+
+static const qahw_effect_uuid_t SL_IID_INS_PRESETREVERB_ = { 0xaa2bebf6, 0x47cf, 0x4613, 0x9bca,
+        { 0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b } };
+const qahw_effect_uuid_t * const SL_IID_INS_PRESETREVERB = &SL_IID_INS_PRESETREVERB_;
+
+static const qahw_effect_uuid_t SL_IID_AUX_PRESETREVERB_ = { 0x6987be09, 0xb142, 0x4b41, 0x9056,
+        { 0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b } };
+const qahw_effect_uuid_t * const SL_IID_AUX_PRESETREVERB = &SL_IID_AUX_PRESETREVERB_;
+
+/* enumerated parameter settings for preset reverb effect */
+typedef enum
+{
+    REVERB_PARAM_PRESET
+} qahw_preset_reverb_params;
+
+
+typedef enum
+{
+    REVERB_PRESET_NONE,
+    REVERB_PRESET_SMALLROOM,
+    REVERB_PRESET_MEDIUMROOM,
+    REVERB_PRESET_LARGEROOM,
+    REVERB_PRESET_MEDIUMHALL,
+    REVERB_PRESET_LARGEHALL,
+    REVERB_PRESET_PLATE,
+    REVERB_PRESET_LAST = REVERB_PRESET_PLATE
+} qahw_reverb_presets;
+
+#if __cplusplus
+}  // extern "C"
+#endif
+
+
+#endif /*QAHW_EFFECT_PRESETREVERB_H_*/
diff --git a/qahw_api/inc/qahw_effect_virtualizer.h b/qahw_api/inc/qahw_effect_virtualizer.h
new file mode 100644
index 0000000..138b850
--- /dev/null
+++ b/qahw_api/inc/qahw_effect_virtualizer.h
@@ -0,0 +1,86 @@
+/*
+ * Copyright (c) 2017, The Linux Foundation. All rights reserved.
+ * Not a Contribution.
+ *
+ * Copyright (C) 2011 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 QAHW_EFFECT_VIRTUALIZER_H_
+#define QAHW_EFFECT_VIRTUALIZER_H_
+
+#include <qahw_effect_api.h>
+
+#if __cplusplus
+extern "C" {
+#endif
+
+#define QAHW_EFFECT_VIRTUALIZER_LIBRARY "libqcompostprocbundle.so"
+
+static const qahw_effect_uuid_t SL_IID_VIRTUALIZER_ = { 0x37cc2c00, 0xdddd, 0x11db, 0x8577,
+        { 0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b } };
+const qahw_effect_uuid_t * const SL_IID_VIRTUALIZER = &SL_IID_VIRTUALIZER_;
+
+static const qahw_effect_uuid_t SL_IID_VIRTUALIZER_UUID_ = { 0x509a4498, 0x561a, 0x4bea, 0xb3b1,
+        { 0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b } };
+const qahw_effect_uuid_t * const SL_IID_VIRTUALIZER_UUID = &SL_IID_VIRTUALIZER_UUID_;
+
+/* enumerated parameter settings for virtualizer effect */
+/* to keep in sync with frameworks/base/media/java/android/media/audiofx/Virtualizer.java */
+typedef enum
+{
+    VIRTUALIZER_PARAM_STRENGTH_SUPPORTED,
+    VIRTUALIZER_PARAM_STRENGTH,
+    // used with EFFECT_CMD_GET_PARAM
+    // format:
+    //   parameters int32_t              VIRTUALIZER_PARAM_VIRTUAL_SPEAKER_ANGLES
+    //              audio_channel_mask_t input channel mask
+    //              audio_devices_t      audio output device
+    //   output     int32_t*             an array of length 3 * the number of channels in the mask
+    //                                       where entries are the succession of the channel mask
+    //                                       of each speaker (i.e. a single bit is selected in the
+    //                                       channel mask) followed by the azimuth and the
+    //                                       elevation angles.
+    //   status     int -EINVAL  if configuration is not supported or invalid or not forcing
+    //                   0       if configuration is supported and the mode is forced
+    // notes:
+    // - all angles are expressed in degrees and are relative to the listener,
+    // - for azimuth: 0 is the direction the listener faces, 180 is behind the listener, and
+    //    -90 is to her/his left,
+    // - for elevation: 0 is the horizontal plane, +90 is above the listener, -90 is below.
+    VIRTUALIZER_PARAM_VIRTUAL_SPEAKER_ANGLES,
+    // used with EFFECT_CMD_SET_PARAM
+    // format:
+    //   parameters  int32_t           VIRTUALIZER_PARAM_FORCE_VIRTUALIZATION_MODE
+    //               audio_devices_t   audio output device
+    //   status      int -EINVAL   if the device is not supported or invalid
+    //                   0         if the device is supported and the mode is forced, or forcing
+    //                               was disabled for the AUDIO_DEVICE_NONE audio device.
+    VIRTUALIZER_PARAM_FORCE_VIRTUALIZATION_MODE,
+    // used with EFFECT_CMD_GET_PARAM
+    // format:
+    //   parameters int32_t              VIRTUALIZER_PARAM_VIRTUALIZATION_MODE
+    //   output     audio_device_t       audio device reflecting the current virtualization mode,
+    //                                   AUDIO_DEVICE_NONE when not virtualizing
+    //   status     int -EINVAL if an error occurred
+    //                  0       if the output value is successfully retrieved
+    VIRTUALIZER_PARAM_VIRTUALIZATION_MODE
+} qahw_virtualizer_params;
+
+#if __cplusplus
+}  // extern "C"
+#endif
+
+
+#endif /*QAHW_EFFECT_VIRTUALIZER_H_*/
diff --git a/qahw_api/inc/qahw_effect_visualizer.h b/qahw_api/inc/qahw_effect_visualizer.h
new file mode 100644
index 0000000..ce79bab
--- /dev/null
+++ b/qahw_api/inc/qahw_effect_visualizer.h
@@ -0,0 +1,79 @@
+/*
+ * Copyright (c) 2017, The Linux Foundation. All rights reserved.
+ * Not a Contribution.
+ *
+ * Copyright (C) 2011 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 QAHW_EFFECT_VISUALIZER_H_
+#define QAHW_EFFECT_VISUALIZER_H_
+
+#include <qahw_effect_api.h>
+
+#if __cplusplus
+extern "C" {
+#endif
+
+#define QAHW_EFFECT_VISUALIZER_LIBRARY "libqcomvisualizer.so"
+
+static const qahw_effect_uuid_t SL_IID_VISUALIZATION_ =
+    { 0xe46b26a0, 0xdddd, 0x11db, 0x8afd, { 0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b } };
+const qahw_effect_uuid_t * const SL_IID_VISUALIZATION = &SL_IID_VISUALIZATION_;
+
+static const qahw_effect_uuid_t SL_IID_VISUALIZATION_UUID_ =
+    { 0x7a8044a0, 0x1a71, 0x11e3, 0xa184, { 0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b } };
+const qahw_effect_uuid_t * const SL_IID_VISUALIZATION_UUID = &SL_IID_VISUALIZATION_UUID_;
+
+#define VISUALIZER_CAPTURE_SIZE_MAX 1024  // maximum capture size in samples
+#define VISUALIZER_CAPTURE_SIZE_MIN 128   // minimum capture size in samples
+
+// to keep in sync with frameworks/base/media/java/android/media/audiofx/Visualizer.java
+#define VISUALIZER_SCALING_MODE_NORMALIZED 0
+#define VISUALIZER_SCALING_MODE_AS_PLAYED  1
+
+#define MEASUREMENT_MODE_NONE      0x0
+#define MEASUREMENT_MODE_PEAK_RMS  0x1
+
+#define MEASUREMENT_IDX_PEAK 0
+#define MEASUREMENT_IDX_RMS  1
+
+/* enumerated parameters for Visualizer effect */
+typedef enum
+{
+    VISUALIZER_PARAM_CAPTURE_SIZE, // Sets the number PCM samples in the capture.
+    VISUALIZER_PARAM_SCALING_MODE, // Sets the way the captured data is scaled
+    VISUALIZER_PARAM_LATENCY,      // Informs the visualizer about the downstream latency
+    VISUALIZER_PARAM_MEASUREMENT_MODE, // Sets which measurements are to be made
+} qahw_visualizer_params;
+
+/* commands */
+typedef enum
+{
+    VISUALIZER_CMD_CAPTURE = QAHW_EFFECT_CMD_FIRST_PROPRIETARY, // Gets the latest PCM capture.
+    VISUALIZER_CMD_MEASURE, // Gets the current measurements
+} qahw_visualizer_cmds;
+
+// VISUALIZER_CMD_CAPTURE retrieves the latest PCM snapshot captured by the visualizer engine.
+// It returns the number of samples specified by VISUALIZER_PARAM_CAPTURE_SIZE
+// in 8 bit unsigned format (0 = 0x80)
+
+// VISUALIZER_CMD_MEASURE retrieves the lastest measurements as int32_t saved in the
+// MEASUREMENT_IDX_* array index order.
+
+#if __cplusplus
+}  // extern "C"
+#endif
+
+#endif /*QAHW_EFFECT_VISUALIZER_H_*/
diff --git a/qahw_api/src/qahw_effect.c b/qahw_api/src/qahw_effect.c
new file mode 100644
index 0000000..cf7b3fd
--- /dev/null
+++ b/qahw_api/src/qahw_effect.c
@@ -0,0 +1,321 @@
+/*
+* Copyright (c) 2017, The Linux Foundation. All rights reserved.
+*
+* Redistribution and use in source and binary forms, with or without
+* modification, are permitted provided that the following conditions are
+* met:
+*     * Redistributions of source code must retain the above copyright
+*       notice, this list of conditions and the following disclaimer.
+*     * Redistributions in binary form must reproduce the above
+*       copyright notice, this list of conditions and the following
+*       disclaimer in the documentation and/or other materials provided
+*       with the distribution.
+*     * Neither the name of The Linux Foundation nor the names of its
+*       contributors may be used to endorse or promote products derived
+*       from this software without specific prior written permission.
+*
+* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+* ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#define LOG_TAG "qahw_effect"
+//#define LOG_NDEBUG 0
+#define LOG_NDDEBUG 0
+
+#include <cutils/list.h>
+#include <dlfcn.h>
+#include <utils/Log.h>
+#include <hardware/audio.h>
+#include <hardware/audio_effect.h>
+#include <stdlib.h>
+
+#include "qahw_effect_api.h"
+
+// The current effect API version.
+#define QAHW_EFFECT_API_VERSION_CURRENT QAHW_EFFECT_API_VERSION_0_0
+#define PATH_MAX 4096
+
+typedef struct {
+    char                   lib_path[PATH_MAX];
+    pthread_mutex_t        lock;
+    uint32_t               ref_count;
+    audio_effect_library_t *desc;
+    void                   *handle;
+    struct listnode        lib_list;
+} qahw_effect_lib_t;
+
+// list of loaded effect libraries
+static struct listnode effect_libraries_list;
+static int effect_libraries_count = 0;
+static pthread_mutex_t effect_libraries_lock = PTHREAD_MUTEX_INITIALIZER;
+
+qahw_effect_lib_t *get_qahw_effect_lib_by_name(const char *lib_path) {
+    struct listnode *node = NULL;
+    qahw_effect_lib_t *effect_lib = NULL, *effect_lib_temp = NULL;
+
+    if (lib_path == NULL)
+        goto exit;
+
+    list_for_each(node, &effect_libraries_list) {
+        effect_lib_temp = node_to_item(node, qahw_effect_lib_t, lib_list);
+        if(!strncmp(lib_path, effect_lib_temp->lib_path, PATH_MAX)) {
+            effect_lib = effect_lib_temp;
+            break;
+        }
+    }
+exit:
+    return effect_lib;
+}
+
+
+qahw_effect_lib_t *get_qahw_effect_lib_by_desc(qahw_effect_lib_handle_t handle) {
+    struct listnode *node = NULL;
+    qahw_effect_lib_t *effect_lib = NULL, *effect_lib_temp = NULL;
+
+    if (handle == NULL)
+        goto exit;
+
+    list_for_each(node, &effect_libraries_list) {
+        effect_lib_temp = node_to_item(node, qahw_effect_lib_t, lib_list);
+        if (effect_lib_temp->desc == (audio_effect_library_t *)handle) {
+            effect_lib = effect_lib_temp;
+            break;
+        }
+    }
+exit:
+    return effect_lib;
+}
+
+
+qahw_effect_lib_handle_t qahw_effect_load_library(const char *lib_path) {
+    audio_effect_library_t *desc;
+    qahw_effect_lib_t      *qahw_effect_lib;
+    void                   *handle;
+
+    if (strlen(lib_path) >= PATH_MAX -1) {
+        ALOGE("%s: effect libraries path too long", __func__);
+        return NULL;
+    }
+
+    /* return existing lib handler if already loaded */
+    pthread_mutex_lock(&effect_libraries_lock);
+    if (effect_libraries_count > 0) {
+        qahw_effect_lib = get_qahw_effect_lib_by_name(lib_path);
+        if (qahw_effect_lib != NULL) {
+            desc = qahw_effect_lib->desc;
+            pthread_mutex_lock(&qahw_effect_lib->lock);
+            qahw_effect_lib->ref_count++;
+            pthread_mutex_unlock(&qahw_effect_lib->lock);
+            goto done;
+        }
+    }
+
+    handle = dlopen(lib_path, RTLD_NOW);
+    if (handle == NULL) {
+        ALOGE("%s: failed to dlopen lib %s", __func__, lib_path);
+        goto error;
+    }
+
+    desc = (audio_effect_library_t *)dlsym(handle, AUDIO_EFFECT_LIBRARY_INFO_SYM_AS_STR);
+    if (desc == NULL) {
+        ALOGE("%s: could not find symbol %s", __func__, AUDIO_EFFECT_LIBRARY_INFO_SYM_AS_STR);
+        goto error;
+    }
+
+    if (AUDIO_EFFECT_LIBRARY_TAG != desc->tag) {
+        ALOGE("%s: bad tag %08x in lib info struct", __func__, desc->tag);
+        goto error;
+    }
+
+    if (EFFECT_API_VERSION_MAJOR(desc->version) !=
+            EFFECT_API_VERSION_MAJOR(EFFECT_LIBRARY_API_VERSION)) {
+        ALOGE("%s: bad lib version %08x", __func__, desc->version);
+        goto error;
+    }
+
+    qahw_effect_lib = (qahw_effect_lib_t *)calloc(1, sizeof(qahw_effect_lib_t));
+    if (qahw_effect_lib == NULL) {
+        ALOGE("%s: calloc failed", __func__);
+        goto error;
+    }
+
+    if (!effect_libraries_count)
+        list_init(&effect_libraries_list);
+    effect_libraries_count++;
+
+    /* init and load effect lib into global list */
+    strlcpy(qahw_effect_lib->lib_path, lib_path, PATH_MAX);
+    pthread_mutex_init(&qahw_effect_lib->lock, (const pthread_mutexattr_t *) NULL);
+    qahw_effect_lib->ref_count = 1;
+    qahw_effect_lib->desc = desc;
+    qahw_effect_lib->handle = handle;
+
+    list_add_tail(&effect_libraries_list, &qahw_effect_lib->lib_list);
+
+done:
+    pthread_mutex_unlock(&effect_libraries_lock);
+    return (qahw_effect_lib_handle_t)desc;
+
+error:
+    if (handle != NULL)
+        dlclose(handle);
+
+    pthread_mutex_unlock(&effect_libraries_lock);
+    return NULL;
+}
+
+
+int32_t qahw_effect_unload_library(qahw_effect_lib_handle_t handle) {
+    qahw_effect_lib_t *qahw_effect_lib;
+
+    pthread_mutex_lock(&effect_libraries_lock);
+    if (effect_libraries_count <= 0) {
+        ALOGW("%s: no valid libraries loaded", __func__);
+        pthread_mutex_unlock(&effect_libraries_lock);
+        return -EINVAL;
+    }
+
+    qahw_effect_lib = get_qahw_effect_lib_by_desc(handle);
+    if (qahw_effect_lib == NULL) {
+        ALOGW("%s: effect lib handle(%p) not in loaded queue", __func__, (void *)handle);
+        pthread_mutex_unlock(&effect_libraries_lock);
+        return -EINVAL;
+    }
+
+    pthread_mutex_lock(&qahw_effect_lib->lock);
+    qahw_effect_lib->ref_count--;
+    if (qahw_effect_lib->ref_count > 0) {
+        ALOGW("%s: skip unloading effect lib, ref count %d", __func__, qahw_effect_lib->ref_count);
+        pthread_mutex_unlock(&qahw_effect_lib->lock);
+        goto done;
+    }
+
+    if (qahw_effect_lib->handle)
+        dlclose(qahw_effect_lib->handle);
+    effect_libraries_count--;
+    list_remove(&qahw_effect_lib->lib_list);
+    pthread_mutex_unlock(&qahw_effect_lib->lock);
+    pthread_mutex_destroy(&qahw_effect_lib->lock);
+    free(qahw_effect_lib);
+
+done:
+    pthread_mutex_unlock(&effect_libraries_lock);
+    return 0;
+}
+
+
+int32_t qahw_effect_create(qahw_effect_lib_handle_t handle,
+                           const qahw_effect_uuid_t *uuid,
+                           int32_t io_handle,
+                           qahw_effect_handle_t *effect_handle) {
+    int32_t rc = -EINVAL;
+    audio_effect_library_t *desc = (audio_effect_library_t *)handle;
+
+    if (desc != NULL) {
+        rc = desc->create_effect((const effect_uuid_t *)uuid, 0, io_handle,
+                (effect_handle_t *)effect_handle);
+    }
+
+    return rc;
+}
+
+
+int32_t qahw_effect_release(qahw_effect_lib_handle_t handle,
+                            qahw_effect_handle_t effect_handle) {
+    int32_t rc = -EINVAL;
+    audio_effect_library_t *desc = (audio_effect_library_t *)handle;
+
+    if (desc != NULL) {
+        rc = desc->release_effect((effect_handle_t)effect_handle);
+    }
+
+    return rc;
+}
+
+
+int32_t qahw_effect_get_descriptor(qahw_effect_lib_handle_t handle,
+                                   const qahw_effect_uuid_t *uuid,
+                                   qahw_effect_descriptor_t *effect_desc) {
+    int32_t rc = -EINVAL;
+    audio_effect_library_t *desc = (audio_effect_library_t *)handle;
+
+    if (desc != NULL) {
+        rc = desc->get_descriptor((const effect_uuid_t *)uuid, (effect_descriptor_t *)effect_desc);
+    }
+
+    return rc;
+}
+
+
+int32_t qahw_effect_get_version() {
+    return QAHW_EFFECT_API_VERSION_CURRENT;
+}
+
+
+int32_t qahw_effect_process(qahw_effect_handle_t self,
+                            qahw_audio_buffer_t *in_buffer,
+                            qahw_audio_buffer_t *out_buffer) {
+    int32_t rc = -EINVAL;
+    struct effect_interface_s *itfe;
+
+    if (self) {
+        itfe = *((struct effect_interface_s **)self);
+        if (itfe) {
+            rc = itfe->process((effect_handle_t)self,
+                               (audio_buffer_t *)in_buffer,
+                               (audio_buffer_t *)out_buffer);
+        }
+    }
+
+    return rc;
+}
+
+
+int32_t qahw_effect_command(qahw_effect_handle_t self,
+                            uint32_t cmd_code,
+                            uint32_t cmd_size,
+                            void *cmd_data,
+                            uint32_t *reply_size,
+                            void *reply_data) {
+    int32_t rc = -EINVAL;
+    struct effect_interface_s *itfe;
+
+    if (self) {
+        itfe = *((struct effect_interface_s **)self);
+        if (itfe) {
+            rc = itfe->command((effect_handle_t)self, cmd_code, cmd_size,
+                               cmd_data, reply_size, reply_data);
+        }
+    }
+
+    return rc;
+}
+
+
+int32_t qahw_effect_process_reverse(qahw_effect_handle_t self,
+                                    qahw_audio_buffer_t *in_buffer,
+                                    qahw_audio_buffer_t *out_buffer) {
+    int32_t rc = -EINVAL;
+    struct effect_interface_s *itfe;
+
+    if (self) {
+        itfe = *((struct effect_interface_s **)self);
+        if (itfe) {
+            rc = itfe->process_reverse((effect_handle_t)self,
+                                       (audio_buffer_t *)in_buffer,
+                                       (audio_buffer_t *)out_buffer);
+        }
+    }
+
+    return rc;
+}
+
diff --git a/qahw_api/test/Makefile.am b/qahw_api/test/Makefile.am
index c269557..46a2ee7 100644
--- a/qahw_api/test/Makefile.am
+++ b/qahw_api/test/Makefile.am
@@ -3,7 +3,8 @@
 PLAY_CPPFLAGS = -Wno-sign-compare
 PLAY_INCLUDES = -I $(top_srcdir)/qahw_api/inc
 
-hal_play_test_SOURCES = qahw_playback_test.c
+hal_play_test_SOURCES = qahw_playback_test.c \
+                        qahw_effect_test.c
 hal_play_test_CPPFLAGS = $(PLAY_CPPFLAGS) $(PLAY_INCLUDES)
 hal_play_test_CPPFLAGS += -D__unused=__attribute__\(\(__unused__\)\)
 hal_play_test_LDADD = -lutils ../libqahw.la
diff --git a/qahw_api/test/qahw_effect_test.c b/qahw_api/test/qahw_effect_test.c
new file mode 100644
index 0000000..d9ce81e
--- /dev/null
+++ b/qahw_api/test/qahw_effect_test.c
@@ -0,0 +1,231 @@
+/*
+* Copyright (c) 2017, The Linux Foundation. All rights reserved.
+*
+* Redistribution and use in source and binary forms, with or without
+* modification, are permitted provided that the following conditions are
+* met:
+*     * Redistributions of source code must retain the above copyright
+*       notice, this list of conditions and the following disclaimer.
+*     * Redistributions in binary form must reproduce the above
+*       copyright notice, this list of conditions and the following
+*       disclaimer in the documentation and/or other materials provided
+*       with the distribution.
+*     * Neither the name of The Linux Foundation nor the names of its
+*       contributors may be used to endorse or promote products derived
+*       from this software without specific prior written permission.
+*
+* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+* ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/* effect test to be applied on HAL layer */
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <errno.h>
+
+#include "qahw_api.h"
+#include "qahw_defs.h"
+#include "qahw_effect_api.h"
+#include "qahw_effect_bassboost.h"
+#include "qahw_effect_environmentalreverb.h"
+#include "qahw_effect_equalizer.h"
+#include "qahw_effect_presetreverb.h"
+#include "qahw_effect_virtualizer.h"
+#include "qahw_effect_visualizer.h"
+
+#include "qahw_effect_test.h"
+
+thread_func_t effect_thread_funcs[EFFECT_NUM] = {
+    &bassboost_thread_func,
+    &virtualizer_thread_func,
+    &equalizer_thread_func,
+    &visualizer_thread_func,
+    &reverb_thread_func,
+};
+
+const char * effect_str[EFFECT_NUM] = {
+    "bassboost",
+    "virtualizer",
+    "equalizer",
+    "visualizer",
+    "reverb",
+};
+
+void *bassboost_thread_func(void* data) {
+}
+
+void *virtualizer_thread_func(void* data) {
+}
+
+void *equalizer_thread_func(void* data) {
+    thread_data_t            *thr_ctxt = (thread_data_t *)data;
+    qahw_effect_lib_handle_t lib_handle;
+    qahw_effect_handle_t     effect_handle;
+    qahw_effect_descriptor_t effect_desc;
+    int32_t                  rc;
+    int                      reply_data;
+    uint32_t                 reply_size = sizeof(int);
+    uint32_t                 size = (sizeof(qahw_effect_param_t) + 2 * sizeof(int32_t));
+    uint32_t                 buf32[size];
+    qahw_effect_param_t      *param = (qahw_effect_param_t *)buf32;
+    uint32_t                 preset = EQ_PRESET_NORMAL;
+
+    pthread_mutex_lock(&thr_ctxt->mutex);
+    while(!thr_ctxt->exit) {
+        // suspend thread till signaled
+        fprintf(stdout, "suspend effect thread\n");
+        pthread_cond_wait(&thr_ctxt->loop_cond, &thr_ctxt->mutex);
+        fprintf(stdout, "awake effect thread\n");
+
+        switch(thr_ctxt->cmd) {
+        case(EFFECT_LOAD_LIB):
+            lib_handle = qahw_effect_load_library(QAHW_EFFECT_EQUALIZER_LIBRARY);
+            break;
+        case(EFFECT_GET_DESC):
+            rc = qahw_effect_get_descriptor(lib_handle, SL_IID_EQUALIZER_UUID, &effect_desc);
+            if (rc != 0) {
+                fprintf(stderr, "effect_get_descriptor() returns %d\n", rc);
+            }
+            break;
+        case(EFFECT_CREATE):
+            rc = qahw_effect_create(lib_handle, SL_IID_EQUALIZER_UUID,
+                                    thr_ctxt->io_handle, &effect_handle);
+            if (rc != 0) {
+                fprintf(stderr, "effect_create() returns %d\n", rc);
+            }
+            break;
+        case(EFFECT_CMD):
+            if ((thr_ctxt->cmd_code == QAHW_EFFECT_CMD_ENABLE) ||
+                (thr_ctxt->cmd_code == QAHW_EFFECT_CMD_DISABLE)) {
+                thr_ctxt->reply_size = (uint32_t *)&reply_size;
+                thr_ctxt->reply_data = (void *)&reply_data;
+            } else if (thr_ctxt->cmd_code == QAHW_EFFECT_CMD_SET_PARAM) {
+                param->psize = sizeof(int32_t);
+                *(int32_t *)param->data = EQ_PARAM_CUR_PRESET;
+                param->vsize = sizeof(int32_t);
+                memcpy((param->data + param->psize), &preset, param->vsize);
+
+                thr_ctxt->reply_size = (uint32_t *)&reply_size;
+                thr_ctxt->reply_data = (void *)&reply_data;
+                thr_ctxt->cmd_size = size;
+                thr_ctxt->cmd_data = param;
+                preset = (preset + 1) % EQ_PRESET_MAX_NUM; // enumerate through all EQ presets
+            }
+            rc = qahw_effect_command(effect_handle, thr_ctxt->cmd_code,
+                                     thr_ctxt->cmd_size, thr_ctxt->cmd_data,
+                                     thr_ctxt->reply_size, thr_ctxt->reply_data);
+            if (rc != 0) {
+                fprintf(stderr, "effect_command() returns %d\n", rc);
+            }
+            break;
+        case(EFFECT_PROC):
+            //qahw_effect_process();
+            break;
+        case(EFFECT_RELEASE):
+            rc = qahw_effect_release(lib_handle, effect_handle);
+            if (rc != 0) {
+                fprintf(stderr, "effect_release() returns %d\n", rc);
+            }
+            break;
+        case(EFFECT_UNLOAD_LIB):
+            rc = qahw_effect_unload_library(lib_handle);
+            if (rc != 0) {
+                fprintf(stderr, "effect_unload_library() returns %d\n", rc);
+            }
+            break;
+        }
+    }
+    pthread_mutex_unlock(&thr_ctxt->mutex);
+
+    return NULL;
+}
+
+void *visualizer_thread_func(void* data) {
+}
+
+void *reverb_thread_func(void* data) {
+}
+
+thread_data_t *create_effect_thread(thread_func_t func_ptr) {
+    int result;
+
+    thread_data_t *ethread_data = (thread_data_t *)calloc(1, sizeof(thread_data_t));
+    ethread_data->exit = false;
+
+    pthread_attr_init(&ethread_data->attr);
+    pthread_attr_setdetachstate(&ethread_data->attr, PTHREAD_CREATE_JOINABLE);
+    pthread_mutex_init(&ethread_data->mutex, NULL);
+    if (pthread_cond_init(&ethread_data->loop_cond, NULL) != 0) {
+        fprintf(stderr, "pthread_cond_init fails\n");
+        return NULL;
+    }
+    // create effect thread
+    result = pthread_create(&ethread_data->effect_thread, &ethread_data->attr,
+                            func_ptr, ethread_data);
+
+    if (result < 0) {
+        fprintf(stderr, "Could not create effect thread!\n");
+        return NULL;
+    }
+
+    return ethread_data;
+}
+
+void effect_thread_command(thread_data_t *ethread_data,
+                           int cmd, uint32_t cmd_code,
+                           uint32_t cmd_size, void *cmd_data) {
+    if (ethread_data == NULL) {
+        fprintf(stderr, "invalid thread data\n");
+        return;
+    }
+
+    // leave interval to let thread consume the previous cond signal
+    usleep(500000);
+
+    pthread_mutex_lock(&ethread_data->mutex);
+    ethread_data->cmd = cmd;
+    if (cmd_code >= 0) {
+        ethread_data->cmd_code = cmd_code;
+        ethread_data->cmd_size = cmd_size;
+        ethread_data->cmd_data = cmd_data;
+    }
+    pthread_mutex_unlock(&ethread_data->mutex);
+    pthread_cond_signal(&ethread_data->loop_cond);
+
+    return;
+}
+
+void destroy_effect_thread(thread_data_t *ethread_data) {
+    int result;
+
+    if (ethread_data == NULL) {
+        fprintf(stderr, "invalid thread data\n");
+        return;
+    }
+
+    pthread_mutex_lock(&ethread_data->mutex);
+    ethread_data->exit = true;
+    pthread_mutex_unlock(&ethread_data->mutex);
+    pthread_cond_signal(&ethread_data->loop_cond);
+
+    result = pthread_join(ethread_data->effect_thread, NULL);
+    if (result < 0) {
+        fprintf(stderr, "Fail to join effect thread!\n");
+        return;
+    }
+    pthread_mutex_destroy(&ethread_data->mutex);
+    pthread_cond_destroy(&ethread_data->loop_cond);
+
+    return;
+}
diff --git a/qahw_api/test/qahw_effect_test.h b/qahw_api/test/qahw_effect_test.h
new file mode 100644
index 0000000..ffb48ea
--- /dev/null
+++ b/qahw_api/test/qahw_effect_test.h
@@ -0,0 +1,73 @@
+/*
+* Copyright (c) 2017, The Linux Foundation. All rights reserved.
+*
+* Redistribution and use in source and binary forms, with or without
+* modification, are permitted provided that the following conditions are
+* met:
+*     * Redistributions of source code must retain the above copyright
+*       notice, this list of conditions and the following disclaimer.
+*     * Redistributions in binary form must reproduce the above
+*       copyright notice, this list of conditions and the following
+*       disclaimer in the documentation and/or other materials provided
+*       with the distribution.
+*     * Neither the name of The Linux Foundation nor the names of its
+*       contributors may be used to endorse or promote products derived
+*       from this software without specific prior written permission.
+*
+* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+* ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#include <pthread.h>
+
+#define EFFECT_NUM 5
+typedef void* (*thread_func_t)(void *);
+extern thread_func_t effect_thread_funcs[EFFECT_NUM];
+
+void *bassboost_thread_func(void*);   // thread main of bassboost effect
+void *virtualizer_thread_func(void*); // thread main of virtualizer effect
+void *equalizer_thread_func(void*);   // thread main of equalizer effect
+void *visualizer_thread_func(void*);  // thread main of visualizer effect
+void *reverb_thread_func(void*);      // thread main of reverb effect
+
+typedef struct thread_data {
+    pthread_t         effect_thread;
+    pthread_attr_t    attr;
+    pthread_mutex_t   mutex;
+    pthread_cond_t    loop_cond;
+    audio_io_handle_t io_handle;
+    bool              exit;
+    int               cmd;
+    uint32_t          cmd_code;
+    uint32_t          cmd_size;
+    void              *cmd_data;
+    uint32_t          *reply_size;
+    void              *reply_data;
+} thread_data_t;
+
+extern thread_data_t *create_effect_thread(thread_func_t);
+extern void effect_thread_command(thread_data_t *, int, uint32_t, uint32_t, void *);
+extern void destroy_effect_thread(thread_data_t *);
+
+extern const char *effect_str[EFFECT_NUM];
+
+enum {
+    EFFECT_LOAD_LIB = 1,
+    EFFECT_GET_DESC,
+    EFFECT_CREATE,
+    EFFECT_CMD,
+    EFFECT_PROC,
+    EFFECT_RELEASE,
+    EFFECT_UNLOAD_LIB,
+    EFFECT_EXIT
+};
+
diff --git a/qahw_api/test/qahw_playback_test.c b/qahw_api/test/qahw_playback_test.c
index 86244e8..d539ce2 100644
--- a/qahw_api/test/qahw_playback_test.c
+++ b/qahw_api/test/qahw_playback_test.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2016-2017, The Linux Foundation. All rights reserved.
  * Not a Contribution.
  *
  * Copyright (C) 2015 The Android Open Source Project *
@@ -27,6 +27,8 @@
 #include <time.h>
 #include "qahw_api.h"
 #include "qahw_defs.h"
+#include "qahw_effect_api.h"
+#include "qahw_effect_test.h"
 
 #define nullptr NULL
 
@@ -43,6 +45,8 @@
 
 #define FORMAT_PCM 1
 
+static thread_data_t *ethread_data = NULL;
+
 struct wav_header {
     uint32_t riff_id;
     uint32_t riff_sz;
@@ -377,6 +381,11 @@
         bytes_remaining -= bytes_written;
         fprintf(log_file, "bytes_written %zd, bytes_remaining %zd\n",
                 bytes_written, bytes_remaining);
+
+        // set eq preset
+        if (ethread_data) {
+            effect_thread_command(ethread_data, EFFECT_CMD, QAHW_EFFECT_CMD_SET_PARAM, 0, NULL);
+        }
     }
 
     return rc;
@@ -552,6 +561,8 @@
     printf(" -k  --kpi-mode                            - Required for Latency KPI measurement\n");
     printf("                                             file path is not used here as file playback is not done in this mode\n");
     printf("                                             file path and other file specific options would be ignored in this mode.\n\n");
+    printf(" -e  --effect-type <effect type>           - Effect used for test\n");
+    printf("                                             0:bassboost 1:virtualizer 2:equalizer 3:visualizer 4:reverb others:null");
     printf(" \n Examples \n");
     printf(" hal_play_test -f /etc/Anukoledenadu.wav     -> plays Wav stream with default params\n\n");
     printf(" hal_play_test -f /etc/MateRani.mp3 -t 2 -d 2 -v 0.01 -r 44100 -c 2 \n");
@@ -591,6 +602,10 @@
     printf("                                          ->avg_bit_rate,sample_rate,wma_bit_per_sample,wma_block_align\n");
     printf("                                          ->wma_channel_mask,wma_encode_option,wma_format_tag\n");
     printf(" hal_play_test -K -F 4                    -> Measure latency KPIs for low latency output\n\n");
+    printf(" hal_play_test /etc//Moto_320kbps.mp3 -t 2 -d 2 -v 0.1 -r 44100 -c 2 -e 2\n");
+    printf("                                          -> plays MP3 stream(-t = 2) on speaker device(-d = 2)\n");
+    printf("                                          -> 2 channels and 44100 sample rate\n\n");
+    printf("                                          -> sound effect equalizer enabled\n\n");
 }
 
 int main(int argc, char* argv[]) {
@@ -639,12 +654,15 @@
         {"kvpairs",       required_argument,    0, 'k'},
         {"flags",         required_argument,    0, 'F'},
         {"kpi-mode",      no_argument,          0, 'K'},
+        {"effect-path",   required_argument,    0, 'e'},
         {"help",          no_argument,          0, 'h'},
         {0, 0, 0, 0}
     };
 
     int opt = 0;
     int option_index = 0;
+    int effect_index = -1;
+    thread_func_t ethread_func = NULL;
     proxy_params.hdr.riff_id = ID_RIFF;
     proxy_params.hdr.riff_sz = 0;
     proxy_params.hdr.riff_fmt = ID_WAVE;
@@ -660,7 +678,7 @@
     proxy_params.hdr.data_sz = 0;
     while ((opt = getopt_long(argc,
                               argv,
-                              "-f:r:c:b:d:v:l:t:a:w:k:D:KF:h",
+                              "-f:r:c:b:d:v:l:t:a:w:k:D:KF:e:h",
                               long_options,
                               &option_index)) != -1) {
             switch (opt) {
@@ -714,6 +732,14 @@
             case 'F':
                 flags = atoll(optarg);
                 flags_set = true;
+            case 'e':
+                effect_index = atoi(optarg);
+                if (effect_index < 0 || effect_index >= EFFECT_NUM) {
+                    fprintf(stderr, "Invalid effect type %d\n", effect_index);
+                    effect_index = -1;
+                } else {
+                    ethread_func = effect_thread_funcs[effect_index];
+                }
                 break;
             case 'h':
                 usage();
@@ -754,6 +780,9 @@
     if (output_device & AUDIO_DEVICE_OUT_ALL_A2DP)
         fprintf(stdout, "Saving pcm data to file: %s\n", proxy_params.acp.file_name);
 
+    if (effect_index != -1)
+        fprintf(stdout, "Effect type:%s\n", effect_str[effect_index]);
+
     fprintf(stdout, "Starting audio hal tests.\n");
 
     qahw_mod_handle = qahw_load_module(mod_name);
@@ -776,6 +805,7 @@
 
         if (!flags_set)
             flags = AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD|AUDIO_OUTPUT_FLAG_NON_BLOCKING;
+            flags |= AUDIO_OUTPUT_FLAG_DIRECT;
 
         switch (filetype) {
         case FILE_WAV:
@@ -919,16 +949,53 @@
         if (!rc)
             proxy_thread_active = true;
     }
+
+    // create effect thread, use thread_data to transfer command
+    if (ethread_func)
+        ethread_data = create_effect_thread(ethread_func);
+
+    if (ethread_data) {
+        // load effect module
+        effect_thread_command(ethread_data, EFFECT_LOAD_LIB, -1, 0, NULL);
+
+        // get effect desc
+        effect_thread_command(ethread_data, EFFECT_GET_DESC, -1, 0, NULL);
+
+        // create effect
+        ethread_data->io_handle = handle;
+        effect_thread_command(ethread_data, EFFECT_CREATE, -1, 0, NULL);
+
+        // enable effect
+        effect_thread_command(ethread_data, EFFECT_CMD, QAHW_EFFECT_CMD_ENABLE, 0, NULL);
+    }
+
     play_file(out_handle,
               file_stream,
              (flags & AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD));
 
+    if (ethread_data) {
+        // disable effect
+        effect_thread_command(ethread_data, EFFECT_CMD, QAHW_EFFECT_CMD_DISABLE, 0, NULL);
+
+        // release effect
+        effect_thread_command(ethread_data, EFFECT_RELEASE, -1, 0, NULL);
+
+        // unload effect module
+        effect_thread_command(ethread_data, EFFECT_UNLOAD_LIB, -1, 0, NULL);
+
+        // destroy effect thread
+        destroy_effect_thread(ethread_data);
+
+        free(ethread_data);
+        ethread_data = NULL;
+    }
+
     if (proxy_thread_active) {
-        /*
-         * DSP gives drain ack for last buffer which will close proxy thread before
-         * app reads last buffer. So add sleep before exiting proxy thread to read
-         * last buffer of data. This is not a calculated value.
-         */
+       /*
+        * DSP gives drain ack for last buffer which will close proxy thread before
+        * app reads last buffer. So add sleep before exiting proxy thread to read
+        * last buffer of data. This is not a calculated value.
+        */
         usleep(500000);
         proxy_params.acp.thread_exit = true;
         fprintf(log_file, "wait for proxy thread exit\n");