Prepare for merged OpenMAX AL and OpenSL ES engine

Field mEngine is now a reference to CEngine instead of IEngine.
Restore Android.mk.
Move mThreadPool, mEqPresetNames, mEqNumPresets from IEngine to CEngine.
IEngineCapabilities_QueryLEDCapabilities and
  IEngineCapabilities_QueryVibraCapabilities are now non-static
  so that they can be shared by OpenMAX AL's IEngine.
IEngineCapabilities is now required in the build, used by OpenMAX AL IEngine.
The default MPH tables now depend on USE_DESIGNATED_INITIALIZER,
  and generate tables for other C compilers programmatically.
Updated comments in MPH.h.
Removed conditionals from MPH_to.c so that non-GNU tables can be built more easily.
Make the interface ID hash generator less specific about hashing algorithm.
Re-build interface ID hash tables.
Update IID_to_MPH.c based on hashgen.
Add generated MPH_to_*.h.
Remove Android dependency.

Change-Id: Icdf89eedc825f9e52bc264b22d923ae157244ed3
diff --git a/libopensles/Android.mk b/libopensles/Android.mk
index 0c12d35..50fd0f9 100644
--- a/libopensles/Android.mk
+++ b/libopensles/Android.mk
@@ -66,6 +66,7 @@
         IDynamicInterfaceManagement.c \
         IEffectSend.c                 \
         IEngine.c                     \
+        IEngineCapabilities.c         \
         IEnvironmentalReverb.c        \
         IEqualizer.c                  \
         IMuteSolo.c                   \
@@ -94,7 +95,6 @@
         IAudioIODeviceCapabilities.c  \
         IDeviceVolume.c               \
         IDynamicSource.c              \
-        IEngineCapabilities.c         \
         ILEDArray.c                   \
         IMIDIMessage.c                \
         IMIDIMuteSolo.c               \
@@ -147,7 +147,7 @@
 endif
 
 ifneq ($(TARGET_SIMULATOR),true)
-		LOCAL_SHARED_LIBRARIES += libdl
+        LOCAL_SHARED_LIBRARIES += libdl
 else
         LOCAL_CFLAGS += -DTARGET_SIMULATOR
 endif
diff --git a/libopensles/CEngine.c b/libopensles/CEngine.c
index 566d793..d5aa8f9 100644
--- a/libopensles/CEngine.c
+++ b/libopensles/CEngine.c
@@ -33,7 +33,7 @@
         return result;
 #endif
     // initialize the thread pool for asynchronous operations
-    result = ThreadPool_init(&this->mEngine.mThreadPool, 0, 0);
+    result = ThreadPool_init(&this->mThreadPool, 0, 0);
     if (SL_RESULT_SUCCESS != result) {
         this->mEngine.mShutdown = SL_BOOLEAN_TRUE;
         (void) pthread_join(this->mSyncThread, (void **) NULL);
@@ -92,7 +92,22 @@
     }
 
     // Shutdown the thread pool used for asynchronous operations (there should not be any)
-    ThreadPool_deinit(&this->mEngine.mThreadPool);
+    ThreadPool_deinit(&this->mThreadPool);
+
+#if defined(ANDROID) && !defined(USE_BACKPORT)
+    // free equalizer preset names
+    if (NULL != this->mEqPresetNames) {
+        for (unsigned i = 0; i < this->mEqNumPresets; ++i) {
+            if (NULL != this->mEqPresetNames[i]) {
+                delete[] this->mEqPresetNames[i];
+                this->mEqPresetNames[i] = NULL;
+            }
+        }
+        delete[] this->mEqPresetNames;
+        this->mEqPresetNames = NULL;
+    }
+    this->mEqNumPresets = 0;
+#endif
 
 #ifdef USE_SDL
     SDL_close();
diff --git a/libopensles/COutputMix.c b/libopensles/COutputMix.c
index c8ee6e5..971acaa 100644
--- a/libopensles/COutputMix.c
+++ b/libopensles/COutputMix.c
@@ -63,7 +63,7 @@
     if (0 == outputMix->mObject.mStrongRefCount) {
 #ifdef USE_OUTPUTMIXEXT
         // We only support a single active output mix per engine, so check if this is the active mix
-        IEngine *thisEngine = outputMix->mObject.mEngine;
+        IEngine *thisEngine = &outputMix->mObject.mEngine->mEngine;
         interface_lock_exclusive(thisEngine);
         bool thisIsTheActiveOutputMix = false;
         if (outputMix == thisEngine->mOutputMix) {
diff --git a/libopensles/IEngine.c b/libopensles/IEngine.c
index f5fb2b8..ae785f4 100644
--- a/libopensles/IEngine.c
+++ b/libopensles/IEngine.c
@@ -553,7 +553,7 @@
                 android_outputMix_create(this);
 #endif
 #ifdef USE_SDL
-                IEngine *thisEngine = this->mObject.mEngine;
+                IEngine *thisEngine = &this->mObject.mEngine->mEngine;
                 interface_lock_exclusive(thisEngine);
                 bool unpause = false;
                 if (NULL == thisEngine->mOutputMix) {
@@ -851,29 +851,8 @@
     }
     this->mShutdown = SL_BOOLEAN_FALSE;
     this->mShutdownAck = SL_BOOLEAN_FALSE;
-    // mThreadPool is initialized in CEngine_Realize
-    memset(&this->mThreadPool, 0, sizeof(ThreadPool));
-#if defined(ANDROID) && !defined(USE_BACKPORT)
-    this->mEqNumPresets = 0;
-    this->mEqPresetNames = NULL;
-#endif
 }
 
 void IEngine_deinit(void *self)
 {
-#if defined(ANDROID) && !defined(USE_BACKPORT)
-    IEngine *this = (IEngine *) self;
-    // free equalizer preset names
-    if (NULL != this->mEqPresetNames) {
-        for (unsigned i = 0; i < this->mEqNumPresets; ++i) {
-            if (NULL != this->mEqPresetNames[i]) {
-                delete[] this->mEqPresetNames[i];
-                this->mEqPresetNames[i] = NULL;
-            }
-        }
-        delete[] this->mEqPresetNames;
-        this->mEqPresetNames = NULL;
-    }
-    this->mEqNumPresets = 0;
-#endif
 }
diff --git a/libopensles/IEngineCapabilities.c b/libopensles/IEngineCapabilities.c
index bbeb9c1..dbb0533 100644
--- a/libopensles/IEngineCapabilities.c
+++ b/libopensles/IEngineCapabilities.c
@@ -99,7 +99,7 @@
 }
 
 
-static SLresult IEngineCapabilities_QueryLEDCapabilities(SLEngineCapabilitiesItf self,
+SLresult IEngineCapabilities_QueryLEDCapabilities(SLEngineCapabilitiesItf self,
     SLuint32 *pIndex, SLuint32 *pLEDDeviceID, SLLEDDescriptor *pDescriptor)
 {
     SL_ENTER_INTERFACE
@@ -141,7 +141,7 @@
 }
 
 
-static SLresult IEngineCapabilities_QueryVibraCapabilities(SLEngineCapabilitiesItf self,
+SLresult IEngineCapabilities_QueryVibraCapabilities(SLEngineCapabilitiesItf self,
     SLuint32 *pIndex, SLuint32 *pVibraDeviceID, SLVibraDescriptor *pDescriptor)
 {
     SL_ENTER_INTERFACE
diff --git a/libopensles/IID_to_MPH.c b/libopensles/IID_to_MPH.c
index c83ff3b..edbecc6 100644
--- a/libopensles/IID_to_MPH.c
+++ b/libopensles/IID_to_MPH.c
@@ -14,6 +14,8 @@
  * limitations under the License.
  */
 
+// This file is automagically generated by hashgen, do not edit
+
 /** \file IID_to_MPH.c Interface ID to MPH mapping */
 
 #include "SLES/OpenSLES.h"
@@ -30,19 +32,19 @@
 #define MAX_HASH_VALUE 115
   static const unsigned char asso_values[] =
     {
-        5, 116, 116,  61, 116, 116,   7, 116, 116,   7,
-      116,  12, 116, 116, 116,  46, 116, 116, 116, 116,
-      116, 116,  56, 116, 116,  36, 116, 116, 116, 116,
+        5, 116, 116,   2, 116, 116,   7, 116, 116,   7,
+      116,  12, 116, 116, 116,  51, 116, 116, 116, 116,
+      116, 116,  61, 116, 116,  41, 116, 116, 116, 116,
       116,   7,  20, 116, 116, 116, 116, 116, 116, 116,
-      116, 116,  41,  20,  36, 116,  21, 116, 116, 116,
-      116, 116, 116,  26, 116,   2, 116, 116, 116, 116,
-      116,  51, 116,  51,  55, 116, 116, 116, 116, 116,
-      116,  16, 116, 116, 116, 116, 116, 116, 116, 116,
+      116, 116,  46,  20,  41, 116,  26, 116, 116, 116,
+      116, 116, 116,  31, 116,   2, 116, 116, 116, 116,
+      116,  56, 116,  56,  55, 116, 116, 116, 116, 116,
+      116,  21, 116, 116, 116, 116, 116, 116, 116, 116,
        21, 116, 116, 116, 116, 116,  26, 116, 116, 116,
-       11, 116, 116, 116, 116, 116,  40,  11, 116,  60,
-      116, 116, 116, 116, 116, 116,   6, 116, 116, 116,
+       11, 116, 116, 116, 116, 116,  40,  16, 116,  60,
+      116, 116, 116, 116, 116, 116,  11, 116, 116, 116,
       116, 116,   1, 116, 116, 116, 116, 116, 116, 116,
-      116,   1,  55,   6, 116, 116, 116, 116,  45, 116,
+      116,   6,  55,   6, 116, 116, 116,   1,  45, 116,
       116,   1, 116, 116, 116, 116, 116,   1, 116, 116,
       116,  60, 116, 116, 116, 116, 116, 116, 116, 116,
       116,  55, 116, 116, 116, 116, 116, 116, 116, 116,
@@ -99,72 +101,72 @@
         -1,
         -1,
         MPH_3DLOCATION,
-        MPH_OBJECT,
+        MPH_ANDROIDSTREAMSOURCE,
         -1,
         -1,
         -1,
         MPH_MIDIMESSAGE,
+        MPH_OBJECT,
+        MPH_MIDIMUTESOLO,
+        -1,
+        -1,
+        MPH_SEEK,
         MPH_ANDROIDEFFECTCAPABILITIES,
         -1,
         -1,
         -1,
-        MPH_SEEK,
+        MPH_PITCH,
         MPH_RATEPITCH,
         -1,
         -1,
         -1,
-        MPH_PITCH,
+        MPH_METADATATRAVERSAL,
         MPH_PRESETREVERB,
         -1,
         -1,
         -1,
-        MPH_METADATATRAVERSAL,
+        MPH_ENVIRONMENTALREVERB,
         MPH_AUDIODECODERCAPABILITIES,
         -1,
         -1,
         -1,
-        MPH_ENVIRONMENTALREVERB,
+        MPH_AUDIOIODEVICECAPABILITIES,
         MPH_MIDITIME,
         -1,
         -1,
         -1,
-        MPH_AUDIOIODEVICECAPABILITIES,
+        MPH_DEVICEVOLUME,
         MPH_3DCOMMIT,
         -1,
         -1,
         -1,
-        MPH_DEVICEVOLUME,
+        MPH_ANDROIDEFFECT,
         MPH_PLAYBACKRATE,
         -1,
         -1,
         -1,
-        MPH_ANDROIDEFFECT,
+        MPH_3DDOPPLER,
         MPH_LED,
         -1,
         -1,
         -1,
-        MPH_3DDOPPLER,
+        MPH_METADATAEXTRACTION,
         MPH_PREFETCHSTATUS,
         -1,
         -1,
         -1,
-        MPH_METADATAEXTRACTION,
+        MPH_OUTPUTMIX,
         MPH_ANDROIDSIMPLEBUFFERQUEUE,
         -1,
         -1,
         -1,
-        MPH_OUTPUTMIX,
+        MPH_ENGINE,
         MPH_VIBRA,
         -1,
         -1,
         -1,
-        MPH_ENGINE,
-        MPH_AUDIOENCODERCAPABILITIES,
-        -1,
-        -1,
-        -1,
         MPH_AUDIOENCODER,
-        MPH_MIDIMUTESOLO,
+        MPH_AUDIOENCODERCAPABILITIES,
         -1,
         -1,
         -1,
diff --git a/libopensles/IObject.c b/libopensles/IObject.c
index e7753c2..9022988 100644
--- a/libopensles/IObject.c
+++ b/libopensles/IObject.c
@@ -525,7 +525,7 @@
     this->mState = SL_OBJECT_STATE_DESTROYING;
     VoidHook destroy = class__->mDestroy;
     // const, no lock needed
-    IEngine *thisEngine = this->mEngine;
+    IEngine *thisEngine = &this->mEngine->mEngine;
     unsigned i = this->mInstanceID;
     assert(MAX_INSTANCE >= i);
     // avoid a recursive lock on the engine when destroying the engine itself
@@ -785,7 +785,7 @@
 
 void IObject_Publish(IObject *this)
 {
-    IEngine *thisEngine = this->mEngine;
+    IEngine *thisEngine = &this->mEngine->mEngine;
     interface_lock_exclusive(thisEngine);
     // construct earlier reserved a pending slot, but did not choose the actual slot number
     unsigned availMask = ~thisEngine->mInstanceMask;
diff --git a/libopensles/IOutputMixExt.c b/libopensles/IOutputMixExt.c
index 83d3d35..7addbc3 100644
--- a/libopensles/IOutputMixExt.c
+++ b/libopensles/IOutputMixExt.c
@@ -180,7 +180,7 @@
     unsigned activeMask;
     // If the output mix is marked for destruction, then acknowledge the request
     if (this->mDestroyRequested) {
-        IEngine *thisEngine = thisObject->mEngine;
+        IEngine *thisEngine = &thisObject->mEngine->mEngine;
         interface_lock_exclusive(thisEngine);
         assert(&thisEngine->mOutputMix->mObject == thisObject);
         thisEngine->mOutputMix = NULL;
diff --git a/libopensles/MPH.h b/libopensles/MPH.h
index cb969e6..68404ba 100644
--- a/libopensles/MPH.h
+++ b/libopensles/MPH.h
@@ -22,6 +22,7 @@
 #define MPH_NONE                      (-1)
 #define MPH_MIN                         0
 
+// OpenSL ES 1.0.1 interfaces
 #define MPH_3DCOMMIT                    0
 #define MPH_3DDOPPLER                   1
 #define MPH_3DGROUPING                  2
@@ -66,24 +67,21 @@
 #define MPH_VIRTUALIZER                41
 #define MPH_VISUALIZATION              42
 #define MPH_VOLUME                     43
-// end Khronos standard interfaces
 
-// The lack of ifdef on the remaining is intentional
-
-// start non-standard and platform-independent interface IDs
+// Wilhelm desktop extended interfaces
 #define MPH_OUTPUTMIXEXT               44
-// end non-standard and platform-independent interface IDs
 
-// start non-standard and platform-specific interface IDs
+// Android API level 9 extended interfaces
 #define MPH_ANDROIDEFFECT              45
 #define MPH_ANDROIDEFFECTCAPABILITIES  46
 #define MPH_ANDROIDEFFECTSEND          47
 #define MPH_ANDROIDCONFIGURATION       48
 #define MPH_ANDROIDSIMPLEBUFFERQUEUE   49
-#define MPH_ANDROIDSTREAMSOURCE        50
-// end non-standard and platform-specific interface IDs
 
-// total number
+// Android API level 10 extended interfaces
+#define MPH_ANDROIDSTREAMSOURCE        50
+
+// total number of interface IDs
 #define MPH_MAX                        51
 
 #endif // !defined(__MPH_H)
diff --git a/libopensles/MPH_to.c b/libopensles/MPH_to.c
index 17c97c4..26c1735 100644
--- a/libopensles/MPH_to.c
+++ b/libopensles/MPH_to.c
@@ -17,7 +17,6 @@
 // Map minimal perfect hash of an interface ID to its class index.
 
 #include "MPH.h"
-#include "MPH_to.h"
 
 // If defined, then compile with C99 such as GNU C, not GNU C++ or non-GNU C.
 //#define USE_DESIGNATED_INITIALIZERS
@@ -40,7 +39,6 @@
 // Don't cross streams, otherwise bad things happen.
 
 
-#if USE_PROFILES & USE_PROFILES_GAME
 const signed char MPH_to_3DGroup[MPH_MAX] = {
 #ifdef USE_DESIGNATED_INITIALIZERS
     [0 ... MPH_MAX-1] = -1,
@@ -51,27 +49,9 @@
     [MPH_3DSOURCE] = 4,
     [MPH_3DMACROSCOPIC] = 5
 #else
-    -1,
-    3, // MPH_3DDOPPLER
-    -1,
-    2, // MPH_3DLOCATION
-    5, // MPH_3DMACROSCOPIC
-    4, // MPH_3DSOURCE
-    -1, -1, -1, -1, -1, -1, -1,
-    1, // MPH_DYNAMICINTERFACEMANAGEMENT
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-    0, // MPH_OBJECT
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-    -1, // MPH_OUTPUTMIXEXT
-    -1, // MPH_ANDROIDEFFECT
-    -1, // MPH_ANDROIDEFFECTCAPABILITIES
-    -1, // MPH_ANDROIDEFFECTSEND
-    -1, // MPH_ANDROIDCONFIGURATION
-    -1  // MPH_ANDROIDSIMPLEBUFFERQUEUE
-    END
+#include "MPH_to_3DGroup.h"
 #endif
 };
-#endif
 
 const signed char MPH_to_AudioPlayer[MPH_MAX] = {
 #ifdef USE_DESIGNATED_INITIALIZERS
@@ -110,63 +90,10 @@
     [MPH_ANDROIDSTREAMSOURCE] = 29
 #endif
 #else
-    -1,
-    3,  // MPH_3DDOPPLER
-    4,  // MPH_3DGROUPING
-    5,  // MPH_3DLOCATION
-    16, // MPH_3DMACROSCOPIC
-    6,  // MPH_3DSOURCE
-    -1, -1, -1, -1,
-    17, // MPH_BASSBOOST
-    7,  // MPH_BUFFERQUEUE
-    -1,
-    1,  // MPH_DYNAMICINTERFACEMANAGEMENT
-    18, // MPH_DYNAMICSOURCE
-    8,  // MPH_EFFECTSEND
-    -1, -1,
-    19, // MPH_ENVIRONMENTALREVERB
-    20, // MPH_EQUALIZER
-    -1,
-    10, // MPH_METADATAEXTRACTION
-    11, // MPH_METADATATRAVERSAL
-    -1, -1, -1, -1,
-    9,  // MPH_MUTESOLO
-    -1,
-    0,  // MPH_OBJECT
-    -1,
-    21, // MPH_PITCH
-    2,  // MPH_PLAY
-    23, // MPH_PLAYBACKRATE
-    12, // MPH_PREFETCHSTATUS
-    22, // MPH_PRESETREVERB
-    13, // MPH_RATEPITCH
-    -1,
-    14, // MPH_SEEK
-    -1, -1,
-    24, // MPH_VIRTUALIZER
-    25, // MPH_VISUALIZATION
-    15, // MPH_VOLUME
-    -1, // not using MPH_OUTPUTMIXEXT
-#ifdef ANDROID
-    26, // MPH_ANDROIDEFFECT
-    -1, // MPH_ANDROIDEFFECTCAPABILITIES
-    27, // MPH_ANDROIDEFFECTSEND
-    28, // MPH_ANDROIDCONFIGURATION
-    7,  // MPH_SIMPLEBUFFERQUEUE    // alias for [MPH_BUFFERQUEUE]
-    29  // MPH_ANDROIDSTREAMSOURCE
-#else
-    -1, // not using MPH_ANDROIDEFFECT
-    -1, // not using MPH_ANDROIDEFFECTCAPABILITIES
-    -1, // not using MPH_ANDROIDEFFECTSEND
-    -1, // not using MPH_ANDROIDCONFIGURATION
-    -1, // not using MPH_ANDROIDSIMPLEBUFFERQUEUE
-    -1  // not using MPH_ANDROIDSTREAMSOURCE
-#endif
-    END
+#include "MPH_to_AudioPlayer.h"
 #endif
 };
 
-#if (USE_PROFILES & USE_PROFILES_OPTIONAL) || defined(ANDROID)
 const signed char MPH_to_AudioRecorder[MPH_MAX] = {
 #ifdef USE_DESIGNATED_INITIALIZERS
     [0 ... MPH_MAX-1] = -1,
@@ -184,38 +111,9 @@
     [MPH_ANDROIDCONFIGURATION] = 10
 #endif
 #else
-    -1, -1, -1, -1, -1, -1, -1,
-    3, // MPH_AUDIOENCODER
-    -1, -1,
-    4, // MPH_BASSBOOST
-    -1, // MPH_BUFFERQUEUE (application must specify MPH_ANDROIDSIMPLEBUFFERQUEUE)
-    -1,
-    1, // MPH_DYNAMICINTERFACEMANAGEMENT
-    5, // MPH_DYNAMICSOURCE
-    -1, -1, -1, -1,
-    6, // MPH_EQUALIZER
-    -1, -1, -1, -1, -1, -1, -1, -1, -1,
-    0, // MPH_OBJECT
-    -1, -1, -1, -1, -1, -1, -1,
-    2, // MPH_RECORD
-    -1, -1, -1, -1,
-    7, // MPH_VISUALIZATION
-    8, // MPH_VOLUME
-    -1, // not using MPH_OUTPUTMIXEXT
-    -1, // not using MPH_ANDROIDEFFECT
-    -1, // not using MPH_ANDROIDEFFECTCAPABILITIES
-    -1, // not using MPH_ANDROIDEFFECTSEND
-#ifdef ANDROID
-    10, // MPH_ANDROIDCONFIGURATION
-    9   // MPH_ANDROIDSIMPLEBUFFERQUEUE (this is not an alias)
-#else
-    -1, // not using MPH_ANDROIDCONFIGURATION
-    -1  // not using MPH_ANDROIDSIMPLEBUFFERQUEUE
-#endif
-    END
+#include "MPH_to_AudioRecorder.h"
 #endif
 };
-#endif
 
 const signed char MPH_to_Engine[MPH_MAX] = {
 #ifdef USE_DESIGNATED_INITIALIZERS
@@ -234,42 +132,10 @@
     [MPH_ANDROIDEFFECTCAPABILITIES] = 10
 #endif
 #else
-    8, // MPH_3DCOMMIT
-    -1, -1, -1, -1, -1,
-    6, // MPH_AUDIODECODERCAPABILITIES
-    -1,
-    7, // MPH_AUDIOENCODERCAPABILITIES
-    5, // MPH_AUDIOIODEVICECAPABILITIES
-    -1, -1,
-    9, // MPH_DEVICEVOLUME
-    1, // MPH_DYNAMICINTERFACEMANAGEMENT
-    -1, -1,
-    2, // MPH_ENGINE
-    3, // MPH_ENGINECAPABILITIES
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-    0, // MPH_OBJECT
-    -1, -1, -1, -1, -1, -1, -1, -1, -1,
-    4, // MPH_THREADSYNC
-    -1, -1, -1, -1,
-    -1, // MPH_OUTPUTMIXEXT
-#ifdef ANDROID
-    -1, // MPH_ANDROIDEFFECT
-    10, // MPH_ANDROIDEFFECTCAPABILITIES
-    -1, // MPH_ANDROIDEFFECTSEND
-    -1, // MPH_ANDROIDCONFIGURATION
-    -1  // MPH_ANDROIDSIMPLEBUFFERQUEUE
-#else
-    -1, // MPH_ANDROIDEFFECT
-    -1, // MPH_ANDROIDEFFECTCAPABILITIES
-    -1, // MPH_ANDROIDEFFECTSEND
-    -1, // MPH_ANDROIDCONFIGURATION
-    -1  // MPH_ANDROIDSIMPLEBUFFERQUEUE
-#endif
-    END
+#include "MPH_to_Engine.h"
 #endif
 };
 
-#if USE_PROFILES & USE_PROFILES_OPTIONAL
 const signed char MPH_to_LEDDevice[MPH_MAX] = {
 #ifdef USE_DESIGNATED_INITIALIZERS
     [0 ... MPH_MAX-1] = -1,
@@ -277,25 +143,10 @@
     [MPH_DYNAMICINTERFACEMANAGEMENT] = 1,
     [MPH_LED] = 2
 #else
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-    1, // MPH_DYNAMICINTERFACEMANAGEMENT
-    -1, -1, -1, -1, -1, -1,
-    2, // MPH_LED
-    -1, -1, -1, -1, -1, -1, -1, -1,
-    0, // MPH_OBJECT
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-    -1, // MPH_OUTPUTMIXEXT
-    -1, // MPH_ANDROIDEFFECT
-    -1, // MPH_ANDROIDEFFECTCAPABILITIES
-    -1, // MPH_ANDROIDEFFECTSEND
-    -1, // MPH_ANDROIDCONFIGURATION
-    -1  // MPH_ANDROIDSIMPLEBUFFERQUEUE
-    END
+#include "MPH_to_LEDDevice.h"
 #endif
 };
-#endif
 
-#if USE_PROFILES & USE_PROFILES_GAME
 const signed char MPH_to_Listener[MPH_MAX] = {
 #ifdef USE_DESIGNATED_INITIALIZERS
     [0 ... MPH_MAX-1] = -1,
@@ -304,27 +155,10 @@
     [MPH_3DDOPPLER] = 2,
     [MPH_3DLOCATION] = 3
 #else
-    -1,
-    2, // MPH_3DDOPPLER
-    -1,
-    3, // MPH_3DLOCATION
-    -1, -1, -1, -1, -1, -1, -1, -1, -1,
-    1, // MPH_DYNAMICINTERFACEMANAGEMENT
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-    0, // MPH_OBJECT
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-    -1, // MPH_OUTPUTMIXEXT
-    -1, // MPH_ANDROIDEFFECT
-    -1, // MPH_ANDROIDEFFECTCAPABILITIES
-    -1, // MPH_ANDROIDEFFECTSEND
-    -1, // MPH_ANDROIDCONFIGURATION
-    -1  // MPH_ANDROIDSIMPLEBUFFERQUEUE
-    END
+#include "MPH_to_Listener.h"
 #endif
 };
-#endif
 
-#if USE_PROFILES & (USE_PROFILES_GAME | USE_PROFILES_MUSIC)
 const signed char MPH_to_MetadataExtractor[MPH_MAX] = {
 #ifdef USE_DESIGNATED_INITIALIZERS
     [0 ... MPH_MAX-1] = -1,
@@ -334,27 +168,10 @@
     [MPH_METADATAEXTRACTION] = 3,
     [MPH_METADATATRAVERSAL] = 4
 #else
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-    1, // MPH_DYNAMICINTERFACEMANAGEMENT
-    2, // MPH_DYNAMICSOURCE
-    -1, -1, -1, -1, -1, -1,
-    3, // MPH_METADATAEXTRACTION
-    4, // MPH_METADATATRAVERSAL
-    -1, -1, -1, -1, -1, -1,
-    0, // MPH_OBJECT
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-    -1, // MPH_OUTPUTMIXEXT
-    -1, // MPH_ANDROIDEFFECT
-    -1, // MPH_ANDROIDEFFECTCAPABILITIES
-    -1, // MPH_ANDROIDEFFECTSEND
-    -1, // MPH_ANDROIDCONFIGURATION
-    -1  // MPH_ANDROIDSIMPLEBUFFERQUEUE
-    END
+#include "MPH_to_MetadataExtractor.h"
 #endif
 };
-#endif
 
-#if USE_PROFILES & USE_PROFILES_GAME
 const signed char MPH_to_MidiPlayer[MPH_MAX] = {
 #ifdef USE_DESIGNATED_INITIALIZERS
     [0 ... MPH_MAX-1] = -1,
@@ -388,54 +205,9 @@
     [MPH_VIRTUALIZER] = 27,
     [MPH_VISUALIZATION] = 28,
 #else
-    -1,
-    3,  // MPH_3DDOPPLER
-    4,  // MPH_3DGROUPING
-    5,  // MPH_3DLOCATION
-    19, // MPH_3DMACROSCOPIC
-    6,  // MPH_3DSOURCE
-    -1, -1, -1, -1,
-    20, // MPH_BASSBOOST
-    7,  // MPH_BUFFERQUEUE
-    -1,
-    1,  // MPH_DYNAMICINTERFACEMANAGEMENT
-    21, // MPH_DYNAMICSOURCE
-    8,  // MPH_EFFECTSEND
-    -1, -1,
-    22, // MPH_ENVIRONMENTALREVERB
-    23, // MPH_EQUALIZER
-    -1,
-    10, // MPH_METADATAEXTRACTION
-    11, // MPH_METADATATRAVERSAL
-    12, // MPH_MIDIMESSAGE
-    15, // MPH_MIDIMUTESOLO
-    14, // MPH_MIDITEMPO
-    13, // MPH_MIDITIME
-    9,  // MPH_MUTESOLO
-    -1,
-    0,  // MPH_OBJECT
-    -1,
-    24, // MPH_PITCH
-    2,  // MPH_PLAY
-    26, // MPH_PLAYBACKRATE
-    16, // MPH_PREFETCHSTATUS
-    25, // MPH_PRESETREVERB
-    -1, -1,
-    17, // MPH_SEEK
-    -1, -1,
-    27, // MPH_VIRTUALIZER
-    28, // MPH_VISUALIZATION
-    18, // MPH_VOLUME
-    -1, // MPH_OUTPUTMIXEXT
-    -1, // MPH_ANDROIDEFFECT
-    -1, // MPH_ANDROIDEFFECTCAPABILITIES
-    -1, // MPH_ANDROIDEFFECTSEND
-    -1, // MPH_ANDROIDCONFIGURATION
-    -1  // MPH_ANDROIDSIMPLEBUFFERQUEUE
-    END
+#include "MPH_to_MidiPlayer.h"
 #endif
 };
-#endif
 
 const signed char MPH_to_OutputMix[MPH_MAX] = {
 #ifdef USE_DESIGNATED_INITIALIZERS
@@ -457,41 +229,10 @@
     [MPH_ANDROIDEFFECT] = 11
 #endif
 #else
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-    9,  // MPH_BASSBOOST
-    -1, -1,
-    1,  // MPH_DYNAMICINTERFACEMANAGEMENT
-    -1, -1, -1, -1,
-    4,  // MPH_ENVIRONMENTALREVERB
-    5,  // MPH_EQUALIZER
-    -1, -1, -1, -1, -1, -1, -1, -1, -1,
-    0,  // MPH_OBJECT
-    2,  // MPH_OUTPUTMIX
-    -1, -1, -1, -1,
-    6,  // MPH_PRESETREVERB
-    -1, -1, -1, -1, -1,
-    7,  // MPH_VIRTUALIZER
-    10, // MPH_VISUALIZATION
-    8,  // MPH_VOLUME
-#ifdef USE_OUTPUTMIXEXT
-    3,  // MPH_OUTPUTMIXEXT
-#else
-    -1,
-#endif
-#ifdef ANDROID
-    11, // MPH_ANDROIDEFFECT
-#else
-    -1,
-#endif
-    -1, // MPH_ANDROIDEFFECTCAPABILITIES
-    -1, // MPH_ANDROIDEFFECTSEND
-    -1, // MPH_ANDROIDCONFIGURATION
-    -1  // MPH_ANDROIDSIMPLEBUFFERQUEUE
-    END
+#include "MPH_to_OutputMix.h"
 #endif
 };
 
-#if USE_PROFILES & USE_PROFILES_OPTIONAL
 const signed char MPH_to_Vibra[MPH_MAX] = {
 #ifdef USE_DESIGNATED_INITIALIZERS
     [0 ... MPH_MAX-1] = -1,
@@ -499,20 +240,6 @@
     [MPH_DYNAMICINTERFACEMANAGEMENT] = 1,
     [MPH_VIBRA] = 2
 #else
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-    1, // MPH_DYNAMICINTERFACEMANAGEMENT
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-    0, // MPH_OBJECT
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-    2, // MPH_VIBRA
-    -1, -1, -1,
-    -1, // MPH_OUTPUTMIXEXT
-    -1, // MPH_ANDROIDEFFECT
-    -1, // MPH_ANDROIDEFFECTCAPABILITIES
-    -1, // MPH_ANDROIDEFFECTSEND
-    -1, // MPH_ANDROIDCONFIGURATION
-    -1  // MPH_ANDROIDSIMPLEBUFFERQUEUE
-    END
+#include "MPH_to_Vibra.h"
 #endif
 };
-#endif
diff --git a/libopensles/MPH_to_3DGroup.h b/libopensles/MPH_to_3DGroup.h
new file mode 100644
index 0000000..47c8c01
--- /dev/null
+++ b/libopensles/MPH_to_3DGroup.h
@@ -0,0 +1,4 @@
+// This file is automagically generated by mphtogen, do not edit
+ -1,  3, -1,  2,  5,  4, -1, -1, -1, -1, -1, -1, -1,  1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1,  0, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1
diff --git a/libopensles/MPH_to_AudioPlayer.h b/libopensles/MPH_to_AudioPlayer.h
new file mode 100644
index 0000000..0c7ace6
--- /dev/null
+++ b/libopensles/MPH_to_AudioPlayer.h
@@ -0,0 +1,4 @@
+// This file is automagically generated by mphtogen, do not edit
+ -1,  3,  4,  5, 16,  6, -1, -1, -1, -1, 17,  7, -1,  1, 18,  8, -1, -1, 19, 20,
+ -1, 10, 11, -1, -1, -1, -1,  9, -1,  0, -1, 21,  2, 23, 12, 22, 13, -1, 14, -1,
+ -1, 24, 25, 15, -1, -1, -1, -1, -1, -1, -1
diff --git a/libopensles/MPH_to_AudioRecorder.h b/libopensles/MPH_to_AudioRecorder.h
new file mode 100644
index 0000000..006ec08
--- /dev/null
+++ b/libopensles/MPH_to_AudioRecorder.h
@@ -0,0 +1,4 @@
+// This file is automagically generated by mphtogen, do not edit
+ -1, -1, -1, -1, -1, -1, -1,  3, -1, -1,  4, -1, -1,  1,  5, -1, -1, -1, -1,  6,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1,  0, -1, -1, -1, -1, -1, -1, -1,  2, -1, -1,
+ -1, -1,  7,  8, -1, -1, -1, -1, -1, -1, -1
diff --git a/libopensles/MPH_to_Engine.h b/libopensles/MPH_to_Engine.h
new file mode 100644
index 0000000..4629939
--- /dev/null
+++ b/libopensles/MPH_to_Engine.h
@@ -0,0 +1,4 @@
+// This file is automagically generated by mphtogen, do not edit
+  8, -1, -1, -1, -1, -1,  6, -1,  7,  5, -1, -1,  9,  1, -1, -1,  2,  3, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1,  0, -1, -1, -1, -1, -1, -1, -1, -1, -1,  4,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1
diff --git a/libopensles/MPH_to_LEDDevice.h b/libopensles/MPH_to_LEDDevice.h
new file mode 100644
index 0000000..b249e3c
--- /dev/null
+++ b/libopensles/MPH_to_LEDDevice.h
@@ -0,0 +1,4 @@
+// This file is automagically generated by mphtogen, do not edit
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,  1, -1, -1, -1, -1, -1, -1,
+  2, -1, -1, -1, -1, -1, -1, -1, -1,  0, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1
diff --git a/libopensles/MPH_to_Listener.h b/libopensles/MPH_to_Listener.h
new file mode 100644
index 0000000..96d3b2c
--- /dev/null
+++ b/libopensles/MPH_to_Listener.h
@@ -0,0 +1,4 @@
+// This file is automagically generated by mphtogen, do not edit
+ -1,  2, -1,  3, -1, -1, -1, -1, -1, -1, -1, -1, -1,  1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1,  0, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1
diff --git a/libopensles/MPH_to_MetadataExtractor.h b/libopensles/MPH_to_MetadataExtractor.h
new file mode 100644
index 0000000..c12f149
--- /dev/null
+++ b/libopensles/MPH_to_MetadataExtractor.h
@@ -0,0 +1,4 @@
+// This file is automagically generated by mphtogen, do not edit
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,  1,  2, -1, -1, -1, -1, -1,
+ -1,  3,  4, -1, -1, -1, -1, -1, -1,  0, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1
diff --git a/libopensles/MPH_to_MidiPlayer.h b/libopensles/MPH_to_MidiPlayer.h
new file mode 100644
index 0000000..e9592b5
--- /dev/null
+++ b/libopensles/MPH_to_MidiPlayer.h
@@ -0,0 +1,4 @@
+// This file is automagically generated by mphtogen, do not edit
+ -1,  3,  4,  5, 19,  6, -1, -1, -1, -1, 20,  7, -1,  1, 21,  8, -1, -1, 22, 23,
+ -1, 10, 11, 12, 15, 14, 13,  9, -1,  0, -1, 24,  2, 26, 16, 25, -1, -1, 17, -1,
+ -1, 27, 28, 18, -1, -1, -1, -1, -1, -1, -1
diff --git a/libopensles/MPH_to_OutputMix.h b/libopensles/MPH_to_OutputMix.h
new file mode 100644
index 0000000..a600337
--- /dev/null
+++ b/libopensles/MPH_to_OutputMix.h
@@ -0,0 +1,4 @@
+// This file is automagically generated by mphtogen, do not edit
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,  9, -1, -1,  1, -1, -1, -1, -1,  4,  5,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1,  0,  2, -1, -1, -1, -1,  6, -1, -1, -1, -1,
+ -1,  7, 10,  8, -1, -1, -1, -1, -1, -1, -1
diff --git a/libopensles/MPH_to_Vibra.h b/libopensles/MPH_to_Vibra.h
new file mode 100644
index 0000000..1623c67
--- /dev/null
+++ b/libopensles/MPH_to_Vibra.h
@@ -0,0 +1,4 @@
+// This file is automagically generated by mphtogen, do not edit
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,  1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1,  0, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+  2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1
diff --git a/libopensles/OpenSLES_IID.c b/libopensles/OpenSLES_IID.c
index fd3641b..ddea182 100644
--- a/libopensles/OpenSLES_IID.c
+++ b/libopensles/OpenSLES_IID.c
@@ -44,7 +44,14 @@
 /* Interface IDs                                                             */
 /*****************************************************************************/
 
+// Note that the lack of an ifdef on each section is intentional. The entries in this table map
+// to an interface GUID from an MPH (a short-hand representation of the full interface GUID).
+// The presence of an entry does not represent a commitment to support that particular interface.
+
 const struct SLInterfaceID_ SL_IID_array[MPH_MAX] = {
+
+// OpenSL ES 1.0.1 interfaces
+
     // SL_IID_3DCOMMIT
     { 0x3564ad80, 0xdd0f, 0x11db, 0x9e19, { 0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b } },
     // SL_IID_3DDOPPLER
@@ -133,25 +140,36 @@
     { 0xe46b26a0, 0xdddd, 0x11db, 0x8afd, { 0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b } },
     // SL_IID_VOLUME
     { 0x09e8ede0, 0xddde, 0x11db, 0xb4f6, { 0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b } },
-    // SL_IID_OUTPUTMIXEXT (note that the lack of an ifdef is intentional)
+
+// Wilhelm desktop extended interfaces
+
+    // SL_IID_OUTPUTMIXEXT
     { 0xfe5cce00, 0x57bb, 0x11df, 0x951c, { 0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b } },
-    // SL_IID_ANDROIDEFFECT (the lack of ifdef is intentional)
+
+// Android API level 9 extended interfaces
+
+    // SL_IID_ANDROIDEFFECT
     { 0xae12da60, 0x99ac, 0x11df, 0xb456, { 0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b } },
-    // SL_IID_ANDROIDEFFECTCAPABILITIES (the lack of ifdef is intentional)
+    // SL_IID_ANDROIDEFFECTCAPABILITIES
     { 0x6a4f6d60, 0xb5e6, 0x11df, 0xbb3b, { 0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b } },
-    // SL_IID_ANDROIDEFFECTSEND (the lack of ifdef is intentional)
+    // SL_IID_ANDROIDEFFECTSEND
     { 0x7be462c0, 0xbc43, 0x11df, 0x8670, { 0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b } },
-    // SL_IID_ANDROIDCONFIGURATION (the lack of ifdef is intentional)
+    // SL_IID_ANDROIDCONFIGURATION
     { 0x89f6a7e0, 0xbeac, 0x11df, 0x8b5c, { 0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b } },
-    // SL_IID_ANDROIDSIMPLEBUFERQUEUE (the lack of ifdef is intentional)
+    // SL_IID_ANDROIDSIMPLEBUFERQUEUE
     { 0x198e4940, 0xc5d7, 0x11df, 0xa2a6, { 0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b } },
-    // SL_IID_ANDROIDSTREAMSOURCE (the lack of ifdef is intentional)
-    { 0x7fc1a460, 0xeec1, 0x11df, 0xa306, { 0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b } }
+
+// Android API level 10 extended interfaces
+    // SL_IID_ANDROIDSTREAMSOURCE
+    { 0x7fc1a460, 0xeec1, 0x11df, 0xa306, { 0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b } },
+
 };
 
 #ifdef __cplusplus
 extern "C" {
 #endif
+
+// OpenSL ES 1.0.1 interfaces
 const SLInterfaceID SL_IID_3DCOMMIT = &SL_IID_array[MPH_3DCOMMIT];
 const SLInterfaceID SL_IID_3DDOPPLER = &SL_IID_array[MPH_3DDOPPLER];
 const SLInterfaceID SL_IID_3DGROUPING = &SL_IID_array[MPH_3DGROUPING];
@@ -197,15 +215,21 @@
 const SLInterfaceID SL_IID_VIRTUALIZER = &SL_IID_array[MPH_VIRTUALIZER];
 const SLInterfaceID SL_IID_VISUALIZATION = &SL_IID_array[MPH_VISUALIZATION];
 const SLInterfaceID SL_IID_VOLUME = &SL_IID_array[MPH_VOLUME];
+
+// Wilhelm desktop extended interfaces
 extern const SLInterfaceID SL_IID_OUTPUTMIXEXT;
-// The lack of an ifdef is intentional on these
 const SLInterfaceID SL_IID_OUTPUTMIXEXT = &SL_IID_array[MPH_OUTPUTMIXEXT];
+
+// Android API level 9 extended interfaces
 const SLInterfaceID SL_IID_ANDROIDEFFECT = &SL_IID_array[MPH_ANDROIDEFFECT];
 const SLInterfaceID SL_IID_ANDROIDEFFECTCAPABILITIES = &SL_IID_array[MPH_ANDROIDEFFECTCAPABILITIES];
 const SLInterfaceID SL_IID_ANDROIDEFFECTSEND = &SL_IID_array[MPH_ANDROIDEFFECTSEND];
 const SLInterfaceID SL_IID_ANDROIDCONFIGURATION = &SL_IID_array[MPH_ANDROIDCONFIGURATION];
 const SLInterfaceID SL_IID_ANDROIDSIMPLEBUFFERQUEUE = &SL_IID_array[MPH_ANDROIDSIMPLEBUFFERQUEUE];
+
+// Android API level 10 extended interfaces
 const SLInterfaceID SL_IID_ANDROIDSTREAMSOURCE = &SL_IID_array[MPH_ANDROIDSTREAMSOURCE];
+
 #ifdef __cplusplus
 }
 #endif
diff --git a/libopensles/android_Effect.cpp b/libopensles/android_Effect.cpp
index 1bc0a9e..bb2dd6f 100644
--- a/libopensles/android_Effect.cpp
+++ b/libopensles/android_Effect.cpp
@@ -292,7 +292,7 @@
         ieq->mNumPresets = numPresets;
     }
 
-    interface_lock_exclusive(ieq->mThis->mEngine);
+    object_lock_exclusive(&ieq->mThis->mEngine->mObject);
     char name[EFFECT_STRING_LEN_MAX];
     if ((0 < numPresets) && (NULL == ieq->mThis->mEngine->mEqPresetNames)) {
         ieq->mThis->mEngine->mEqPresetNames = (char **)new char *[numPresets];
@@ -305,7 +305,7 @@
             }
         }
     }
-    interface_unlock_exclusive(ieq->mThis->mEngine);
+    object_unlock_exclusive(&ieq->mThis->mEngine->mObject);
 
 #if 0
     // configure the EQ so it can easily be heard, for test only
diff --git a/libopensles/interfaces.c b/libopensles/interfaces.c
index 3d650f9..2c5e428 100644
--- a/libopensles/interfaces.c
+++ b/libopensles/interfaces.c
@@ -16,9 +16,13 @@
 
 // Map minimal perfect hash of an interface ID to its name
 
+#include <assert.h>
+#include <string.h>
 #include "MPH.h"
 
 const char * const interface_names[MPH_MAX] = {
+
+    // OpenSL ES 1.0.1 interfaces
     "3DCOMMIT",
     "3DDOPPLER",
     "3DGROUPING",
@@ -63,12 +67,32 @@
     "VIRTUALIZER",
     "VISUALIZATION",
     "VOLUME",
-    // The lack of ifdef is intentional
+
+    // Wilhelm desktop extended interfaces
     "OUTPUTMIXEXT",
+
+    // Android API level 9 extended interfaces
     "ANDROIDEFFECT",
     "ANDROIDEFFECTCAPABILITIES",
     "ANDROIDEFFECTSEND",
     "ANDROIDCONFIGURATION",
     "ANDROIDSIMPLEBUFFERQUEUE",
+
+    // Android API level 10 extended interfaces
     "ANDROIDSTREAMSOURCE"
+
 };
+
+
+/** Convert an MPH value to an MPH identifier */
+
+void MPH_to_MPH_string(unsigned MPH, char buffer[40])
+{
+    assert(MPH_MAX > MPH);
+    const char *infix;
+    infix = "";
+    strcpy(buffer, "MPH");
+    strcpy(&buffer[3], infix);
+    strcat(buffer, "_");
+    strcat(buffer, interface_names[MPH]);
+}
diff --git a/libopensles/locks.c b/libopensles/locks.c
index a2f08a9..8ab18bb 100644
--- a/libopensles/locks.c
+++ b/libopensles/locks.c
@@ -217,7 +217,7 @@
         if (0 != id) {
             --id;
             assert(MAX_INSTANCE > id);
-            IEngine *thisEngine = this->mEngine;
+            IEngine *thisEngine = &this->mEngine->mEngine;
             interface_lock_exclusive(thisEngine);
             thisEngine->mChangedMask |= 1 << id;
             interface_unlock_exclusive(thisEngine);
diff --git a/libopensles/sles.c b/libopensles/sles.c
index dc950a9..8520552 100644
--- a/libopensles/sles.c
+++ b/libopensles/sles.c
@@ -1002,6 +1002,7 @@
 #define IAndroidEffect_deinit             NULL
 #define IAndroidEffectCapabilities_deinit NULL
 #define IAndroidEffectCapabilities_Expose NULL
+#define IAndroidStreamSource_init         NULL
 #endif
 
 #ifndef USE_OUTPUTMIXEXT
@@ -1059,14 +1060,17 @@
         NULL },
     { /* MPH_VISUALIZATION, */ IVisualization_init, NULL, NULL, NULL, NULL },
     { /* MPH_VOLUME, */ IVolume_init, NULL, NULL, NULL, NULL },
+// Wilhelm desktop extended interfaces
     { /* MPH_OUTPUTMIXEXT, */ IOutputMixExt_init, NULL, NULL, NULL, NULL },
+// Android API level 9 extended interfaces
     { /* MPH_ANDROIDEFFECT */ IAndroidEffect_init, NULL, IAndroidEffect_deinit, NULL, NULL },
     { /* MPH_ANDROIDEFFECTCAPABILITIES */ IAndroidEffectCapabilities_init, NULL,
         IAndroidEffectCapabilities_deinit, IAndroidEffectCapabilities_Expose, NULL },
     { /* MPH_ANDROIDEFFECTSEND */ IAndroidEffectSend_init, NULL, NULL, NULL, NULL },
     { /* MPH_ANDROIDCONFIGURATION */ IAndroidConfiguration_init, NULL, NULL, NULL, NULL },
     { /* MPH_ANDROIDSIMPLEBUFFERQUEUE */ IBufferQueue_init /* alias */, NULL, NULL, NULL, NULL },
-    { /* MPH_ANDROIDSTREAMSOURCE */ IAndroidStreamSource_init, NULL, NULL, NULL, NULL }
+// Android API level 10 extended interfaces
+    { /* MPH_ANDROIDSTREAMSOURCE */ IAndroidStreamSource_init, NULL, NULL, NULL, NULL },
 };
 
 
@@ -1083,8 +1087,10 @@
         // a NULL engine means we are constructing the engine
         IEngine *thisEngine = (IEngine *) engine;
         if (NULL == thisEngine) {
-            thisEngine = &((CEngine *) this)->mEngine;
+            // thisEngine = &((CEngine *) this)->mEngine;
+            this->mEngine = (CEngine *) this;
         } else {
+            this->mEngine = (CEngine *) thisEngine->mThis;
             interface_lock_exclusive(thisEngine);
             if (MAX_INSTANCE <= thisEngine->mInstanceCount) {
                 SL_LOGE("Too many objects");
@@ -1103,7 +1109,6 @@
         }
         this->mLossOfControlMask = lossOfControlMask;
         this->mClass = class__;
-        this->mEngine = thisEngine;
         const struct iid_vtable *x = class__->mInterfaces;
         SLuint8 *interfaceStateP = this->mInterfaceStates;
         SLuint32 index;
@@ -1183,13 +1188,14 @@
 /* Initial global entry points */
 
 
-/** \brief slCreateEngine Function */
+/** \brief Internal code shared by slCreateEngine and xaCreateEngine */
 
-SLresult SLAPIENTRY slCreateEngine(SLObjectItf *pEngine, SLuint32 numOptions,
+static SLresult liCreateEngine(SLObjectItf *pEngine, SLuint32 numOptions,
     const SLEngineOption *pEngineOptions, SLuint32 numInterfaces,
-    const SLInterfaceID *pInterfaceIds, const SLboolean *pInterfaceRequired)
+    const SLInterfaceID *pInterfaceIds, const SLboolean *pInterfaceRequired,
+    const ClassTable *pCEngine_class)
 {
-    SL_ENTER_GLOBAL
+    SLresult result;
 
     int ok;
     ok = pthread_mutex_lock(&theOneTrueMutex);
@@ -1265,7 +1271,13 @@
         }
 
         // initialize fields not associated with an interface
+        // mThreadPool is initialized in CEngine_Realize
+        memset(&this->mThreadPool, 0, sizeof(ThreadPool));
         memset(&this->mSyncThread, 0, sizeof(pthread_t));
+#if defined(ANDROID) && !defined(USE_BACKPORT)
+        this->mEqNumPresets = 0;
+        this->mEqPresetNames = NULL;
+#endif
         // initialize fields related to an interface
         this->mObject.mLossOfControlMask = lossOfControlGlobal ? ~0 : 0;
         this->mEngine.mLossOfControlGlobal = lossOfControlGlobal;
@@ -1280,20 +1292,34 @@
     ok = pthread_mutex_unlock(&theOneTrueMutex);
     assert(0 == ok);
 
+    return result;
+}
+
+
+/** \brief slCreateEngine Function */
+
+SL_API SLresult SLAPIENTRY slCreateEngine(SLObjectItf *pEngine, SLuint32 numOptions,
+    const SLEngineOption *pEngineOptions, SLuint32 numInterfaces,
+    const SLInterfaceID *pInterfaceIds, const SLboolean *pInterfaceRequired)
+{
+    SL_ENTER_GLOBAL
+
+    result = liCreateEngine(pEngine, numOptions, pEngineOptions, numInterfaces, pInterfaceIds,
+            pInterfaceRequired, objectIDtoClass(SL_OBJECTID_ENGINE));
+
     SL_LEAVE_GLOBAL
 }
 
 
-/** \brief slQueryNumSupportedEngineInterfaces Function */
+/** Internal function for slQuerySupportedEngineInterfaces and xaQuerySupportedEngineInterfaces */
 
-SLresult SLAPIENTRY slQueryNumSupportedEngineInterfaces(SLuint32 *pNumSupportedInterfaces)
+static SLresult liQueryNumSupportedInterfaces(SLuint32 *pNumSupportedInterfaces,
+        const ClassTable *class__)
 {
-    SL_ENTER_GLOBAL
-
+    SLresult result;
     if (NULL == pNumSupportedInterfaces) {
         result = SL_RESULT_PARAMETER_INVALID;
     } else {
-        const ClassTable *class__ = objectIDtoClass(SL_OBJECTID_ENGINE);
         assert(NULL != class__);
         SLuint32 count = 0;
         SLuint32 i;
@@ -1316,22 +1342,33 @@
         *pNumSupportedInterfaces = count;
         result = SL_RESULT_SUCCESS;
     }
+    return result;
+}
+
+
+/** \brief slQueryNumSupportedEngineInterfaces Function */
+
+SL_API SLresult SLAPIENTRY slQueryNumSupportedEngineInterfaces(SLuint32 *pNumSupportedInterfaces)
+{
+    SL_ENTER_GLOBAL
+
+    result = liQueryNumSupportedInterfaces(pNumSupportedInterfaces,
+            objectIDtoClass(SL_OBJECTID_ENGINE));
 
     SL_LEAVE_GLOBAL
 }
 
 
-/** \brief slQuerySupportedEngineInterfaces Function */
+/** Internal function for slQuerySupportedEngineInterfaces and xaQuerySupportedEngineInterfaces */
 
-SLresult SLAPIENTRY slQuerySupportedEngineInterfaces(SLuint32 index, SLInterfaceID *pInterfaceId)
+static SLresult liQuerySupportedInterfaces(SLuint32 index, SLInterfaceID *pInterfaceId,
+        const ClassTable *class__)
 {
-    SL_ENTER_GLOBAL
-
+    SLresult result;
     if (NULL == pInterfaceId) {
         result = SL_RESULT_PARAMETER_INVALID;
     } else {
         *pInterfaceId = NULL;
-        const ClassTable *class__ = objectIDtoClass(SL_OBJECTID_ENGINE);
         assert(NULL != class__);
         result = SL_RESULT_PARAMETER_INVALID;   // will be reset later
         SLuint32 i;
@@ -1350,7 +1387,6 @@
                 break;
             }
             if (index == 0) {
-                // The engine has no aliases, but if it did, this would return only the primary
                 *pInterfaceId = &SL_IID_array[class__->mInterfaces[i].mMPH];
                 result = SL_RESULT_SUCCESS;
                 break;
@@ -1358,6 +1394,18 @@
             --index;
         }
     }
+    return result;
+}
+
+
+/** \brief slQuerySupportedEngineInterfaces Function */
+
+SL_API SLresult SLAPIENTRY slQuerySupportedEngineInterfaces(SLuint32 index,
+        SLInterfaceID *pInterfaceId)
+{
+    SL_ENTER_GLOBAL
+
+    result = liQuerySupportedInterfaces(index, pInterfaceId, objectIDtoClass(SL_OBJECTID_ENGINE));
 
     SL_LEAVE_GLOBAL
 }
diff --git a/libopensles/sles_allinclusive.h b/libopensles/sles_allinclusive.h
index 03c8b3e..4b47ffd 100644
--- a/libopensles/sles_allinclusive.h
+++ b/libopensles/sles_allinclusive.h
@@ -20,6 +20,7 @@
 #ifdef ANDROID
 #include "SLES/OpenSLES_Android.h"
 #endif
+#define SL_API
 #include <stddef.h> // offsetof
 #include <stdlib.h> // malloc
 #include <string.h> // memcmp
@@ -56,6 +57,7 @@
 #include "OpenSLESUT.h"
 #include "ThreadPool.h"
 
+typedef struct CEngine_struct CEngine;
 typedef struct CAudioPlayer_struct CAudioPlayer;
 typedef struct CAudioRecorder_struct CAudioRecorder;
 typedef struct C3DGroup_struct C3DGroup;
@@ -283,7 +285,7 @@
 typedef struct Object_interface {
     const struct SLObjectItf_ *mItf;    // const
     // field mThis would be redundant within an IObject, so we substitute mEngine
-    struct Engine_interface *mEngine;   // const
+    CEngine *mEngine;               // const
     const ClassTable *mClass;       // const
     SLuint32 mInstanceID;           // const for debugger and for RPC, 0 means unpublished
     slObjectCallback mCallback;
@@ -552,12 +554,7 @@
     IObject *mInstances[MAX_INSTANCE];
     SLboolean mShutdown;
     SLboolean mShutdownAck;
-    ThreadPool mThreadPool; // for asynchronous operations
-#if defined(ANDROID) && !defined(USE_BACKPORT)
-    // FIXME number of presets will only be saved in IEqualizer, preset names will not be stored
-    SLuint32 mEqNumPresets;
-    char** mEqPresetNames;
-#endif
+    // SLuint32 mVersion;      // 0xXXYYZZ where XX=major, YY=minor, ZZ=step
 } IEngine;
 
 typedef struct {
@@ -1059,7 +1056,7 @@
 } /*CAudioRecorder*/;
 
 
-typedef struct {
+/*typedef*/ struct CEngine_struct {
     // mandated implicit interfaces
     IObject mObject;
 #ifdef ANDROID
@@ -1077,14 +1074,20 @@
     IAudioDecoderCapabilities mAudioDecoderCapabilities;
     IAudioEncoderCapabilities mAudioEncoderCapabilities;
     I3DCommit m3DCommit;
+    // optional interfaces
+    IDeviceVolume mDeviceVolume;
 #ifdef ANDROID
     IAndroidEffectCapabilities mAndroidEffectCapabilities;
 #endif
-    // optional interfaces
-    IDeviceVolume mDeviceVolume;
     // remaining are per-instance private fields not associated with an interface
+    ThreadPool mThreadPool; // for asynchronous operations
     pthread_t mSyncThread;
-} CEngine;
+#if defined(ANDROID) && !defined(USE_BACKPORT)
+    // FIXME number of presets will only be saved in IEqualizer, preset names will not be stored
+    SLuint32 mEqNumPresets;
+    char** mEqPresetNames;
+#endif
+} /*CEngine*/;
 
 typedef struct {
     // mandated interfaces
@@ -1375,3 +1378,7 @@
 extern void ReleaseStrongRefAndUnlockExclusive(IObject *object);
 
 extern COutputMix *CAudioPlayer_GetOutputMix(CAudioPlayer *audioPlayer);
+extern SLresult IEngineCapabilities_QueryLEDCapabilities(SLEngineCapabilitiesItf self,
+    SLuint32 *pIndex, SLuint32 *pLEDDeviceID, SLLEDDescriptor *pDescriptor);
+extern SLresult IEngineCapabilities_QueryVibraCapabilities(SLEngineCapabilitiesItf self,
+    SLuint32 *pIndex, SLuint32 *pVibraDeviceID, SLVibraDescriptor *pDescriptor);
diff --git a/libopensles/sync.c b/libopensles/sync.c
index 2e1e2e2..e081cd6 100644
--- a/libopensles/sync.c
+++ b/libopensles/sync.c
@@ -49,7 +49,7 @@
             object_cond_broadcast(&this->mObject);
             // here is where we would process the enqueued 3D commands
         }
-        unsigned instanceMask = this->mEngine.mInstanceMask;
+        // unsigned instanceMask = this->mEngine.mInstanceMask; // for debugger
         unsigned changedMask = this->mEngine.mChangedMask;
         this->mEngine.mChangedMask = 0;
         object_unlock_exclusive(&this->mObject);
diff --git a/tests/sandbox/multithread.c b/tests/sandbox/multithread.c
index 3d3a297..8864c2c 100644
--- a/tests/sandbox/multithread.c
+++ b/tests/sandbox/multithread.c
@@ -23,7 +23,6 @@
 #include <stdio.h>
 #include <stdlib.h>
 #include <unistd.h>
-#include <utils/Log.h>
 
 typedef struct {
     SLuint32 mObjectID;
@@ -50,7 +49,6 @@
         SLresult result;
 
         ++ta->mCounter;
-        //LOGE("mCounter %d", ta->mCounter);
         switch (ta->mObjectID) {
         case SL_OBJECTID_OUTPUTMIX:
             {
diff --git a/tools/hashgen/Makefile b/tools/hashgen/Makefile
index 50e937f..3486d55 100644
--- a/tools/hashgen/Makefile
+++ b/tools/hashgen/Makefile
@@ -3,7 +3,7 @@
 install :
 	cp IID_to_MPH.c ../../libopensles
 
-CFLAGS = -I../../include
+CFLAGS = -I../../include -g
 
 %.o : %.c
 	gcc -c -o $@ $(CFLAGS) $<
@@ -21,7 +21,7 @@
 part3.c : part23in.c
 	$(RM) $@
 # was 26,54p
-	sed -n '/static const unsigned char asso_values.. =/,/^    };/p' < part23in.c >> $@
+	sed -n '/static const unsigned .* asso_values.. =/,/^    };/p' < part23in.c >> $@
 
 # part4.c is human-generated
 
@@ -32,7 +32,7 @@
 
 part7.c : part23in.c hash.sed
 # was 55p
-	sed -n '/return asso_values.(unsigned char)str.3.. + asso_values.(unsigned char)str.0..;/p' < part23in.c | sed -f hash.sed >> $@
+	sed -n '/return asso_values/p' < part23in.c | sed -f hash.sed >> $@
 
 # part8.c is human_generated
 
diff --git a/tools/hashgen/frag2.c b/tools/hashgen/frag2.c
index a30f56a..998682a 100644
--- a/tools/hashgen/frag2.c
+++ b/tools/hashgen/frag2.c
@@ -1,5 +1,6 @@
 #include "SLES/OpenSLES.h"
 #include "MPH.h"
+#include <assert.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
diff --git a/tools/hashgen/frag3.c b/tools/hashgen/frag3.c
index 40609f9..99eb3a0 100644
--- a/tools/hashgen/frag3.c
+++ b/tools/hashgen/frag3.c
@@ -1,6 +1,7 @@
 
 extern const struct SLInterfaceID_ SL_IID_array[MPH_MAX];
 extern const char * const interface_names[MPH_MAX];
+extern void MPH_to_MPH_string(unsigned MPH, char buffer[40]);
 
 int main(int argc, char **argv)
 {
@@ -14,7 +15,11 @@
             unsigned MPH;
             for (MPH = 0; MPH < MPH_MAX; ++MPH, ++xx) {
                 if (!memcmp(x, xx, 16)) {
-                    printf("        MPH_%s", interface_names[MPH]);
+                    char buffer[40];
+                    buffer[39] = 'x';
+                    MPH_to_MPH_string(MPH, buffer);
+                    assert('x' == buffer[39]);
+                    printf("        %s", buffer);
                     goto out;
                 }
             }
diff --git a/tools/hashgen/part1.c b/tools/hashgen/part1.c
index 09e3372..7422682 100644
--- a/tools/hashgen/part1.c
+++ b/tools/hashgen/part1.c
@@ -14,6 +14,8 @@
  * limitations under the License.
  */
 
+// This file is automagically generated by hashgen, do not edit
+
 /** \file IID_to_MPH.c Interface ID to MPH mapping */
 
 #include "SLES/OpenSLES.h"
diff --git a/tools/mphtogen/MPH.h b/tools/mphtogen/MPH.h
new file mode 120000
index 0000000..4216a79
--- /dev/null
+++ b/tools/mphtogen/MPH.h
@@ -0,0 +1 @@
+../../libopensles/MPH.h
\ No newline at end of file
diff --git a/tools/mphtogen/MPH_to.c b/tools/mphtogen/MPH_to.c
new file mode 120000
index 0000000..5d27b69
--- /dev/null
+++ b/tools/mphtogen/MPH_to.c
@@ -0,0 +1 @@
+../../libopensles/MPH_to.c
\ No newline at end of file
diff --git a/tools/mphtogen/MPH_to.h b/tools/mphtogen/MPH_to.h
new file mode 120000
index 0000000..36b84ea
--- /dev/null
+++ b/tools/mphtogen/MPH_to.h
@@ -0,0 +1 @@
+../../libopensles/MPH_to.h
\ No newline at end of file
diff --git a/tools/mphtogen/Makefile b/tools/mphtogen/Makefile
new file mode 100644
index 0000000..8a3a17c
--- /dev/null
+++ b/tools/mphtogen/Makefile
@@ -0,0 +1,14 @@
+DIR = ../../libopensles
+ALL = $(DIR)/MPH_to_3DGroup.h $(DIR)/MPH_to_AudioPlayer.h $(DIR)/MPH_to_AudioRecorder.h \
+    $(DIR)/MPH_to_Engine.h $(DIR)/MPH_to_LEDDevice.h $(DIR)/MPH_to_Listener.h \
+    $(DIR)/MPH_to_MetadataExtractor.h $(DIR)/MPH_to_MidiPlayer.h $(DIR)/MPH_to_OutputMix.h \
+    $(DIR)/MPH_to_Vibra.h
+
+$(ALL) : mphtogen
+	./mphtogen
+
+mphtogen : mphtogen.c MPH_to.c MPH.h MPH_to.h
+	gcc -o $@ -DUSE_DESIGNATED_INITIALIZERS mphtogen.c MPH_to.c
+
+clean :
+	$(RM) mphtogen
diff --git a/tools/mphtogen/mphtogen.c b/tools/mphtogen/mphtogen.c
new file mode 100644
index 0000000..8907eaf
--- /dev/null
+++ b/tools/mphtogen/mphtogen.c
@@ -0,0 +1,65 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+// Generate the MPH_to_*.h tables for C compilers that don't support designated initializers
+
+#include <assert.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include "MPH.h"
+#include "MPH_to.h"
+
+static void convert(const signed char MPH_to[MPH_MAX], const char *filename)
+{
+    FILE *fp = fopen(filename, "w");
+    assert(NULL != fp);
+    fputs("// This file is automagically generated by mphtogen, do not edit\n", fp);
+    unsigned i;
+    unsigned len = 0;
+    for (i = 0; i < MPH_MAX; ++i) {
+        if (len > 0) {
+            fputc(',', fp);
+            ++len;
+        }
+        if (len > 78) {
+            fputc('\n', fp);
+            len = 0;
+        }
+        fprintf(fp, "%3d", MPH_to[i]);
+        len += 3;
+    }
+    if (len > 0) {
+        fputc('\n', fp);
+    }
+    fclose(fp);
+}
+
+#define _(x) convert(MPH_to_##x, "../../libopensles/MPH_to_" #x ".h");
+
+int main(int argc, char **argv)
+{
+    _(3DGroup)
+    _(AudioPlayer)
+    _(AudioRecorder)
+    _(Engine)
+    _(LEDDevice)
+    _(Listener)
+    _(MetadataExtractor)
+    _(MidiPlayer)
+    _(OutputMix)
+    _(Vibra)
+    return EXIT_SUCCESS;
+}