#include #include // const attribute will not let us modify our variables #define const #include #include #ifdef __LP64__ #define LIB "/system/lib64/libOpenSLES.so" #define SKCODEC "/system/lib64/libskcodec.so" #else #define LIB "/system/lib/libOpenSLES.so" #define SKCODEC "/system/lib/libskcodec.so" #endif #define IIDS(s) \ s(SL_IID_3DCOMMIT) \ s(SL_IID_3DDOPPLER) \ s(SL_IID_3DGROUPING) \ s(SL_IID_3DLOCATION) \ s(SL_IID_3DMACROSCOPIC) \ s(SL_IID_3DSOURCE) \ s(SL_IID_ANDROIDACOUSTICECHOCANCELLATION) \ s(SL_IID_ANDROIDAUTOMATICGAINCONTROL) \ s(SL_IID_ANDROIDBUFFERQUEUESOURCE) \ s(SL_IID_ANDROIDCONFIGURATION) \ s(SL_IID_ANDROIDEFFECT) \ s(SL_IID_ANDROIDEFFECTCAPABILITIES) \ s(SL_IID_ANDROIDEFFECTSEND) \ s(SL_IID_ANDROIDNOISESUPPRESSION) \ s(SL_IID_ANDROIDSIMPLEBUFFERQUEUE) \ s(SL_IID_AUDIODECODERCAPABILITIES) \ s(SL_IID_AUDIOENCODER) \ s(SL_IID_AUDIOENCODERCAPABILITIES) \ s(SL_IID_AUDIOIODEVICECAPABILITIES) \ s(SL_IID_BASSBOOST) \ s(SL_IID_BUFFERQUEUE) \ s(SL_IID_DEVICEVOLUME) \ s(SL_IID_DYNAMICINTERFACEMANAGEMENT) \ s(SL_IID_DYNAMICSOURCE) \ s(SL_IID_EFFECTSEND) \ s(SL_IID_ENGINE) \ s(SL_IID_ENGINECAPABILITIES) \ s(SL_IID_ENVIRONMENTALREVERB) \ s(SL_IID_EQUALIZER) \ s(SL_IID_LED) \ s(SL_IID_METADATAEXTRACTION) \ s(SL_IID_METADATATRAVERSAL) \ s(SL_IID_MIDIMESSAGE) \ s(SL_IID_MIDIMUTESOLO) \ s(SL_IID_MIDITEMPO) \ s(SL_IID_MIDITIME) \ s(SL_IID_MUTESOLO) \ s(SL_IID_NULL) \ s(SL_IID_OBJECT) \ s(SL_IID_OUTPUTMIX) \ s(SL_IID_PITCH) \ s(SL_IID_PLAY) \ s(SL_IID_PLAYBACKRATE) \ s(SL_IID_PREFETCHSTATUS) \ s(SL_IID_PRESETREVERB) \ s(SL_IID_RATEPITCH) \ s(SL_IID_RECORD) \ s(SL_IID_SEEK) \ s(SL_IID_THREADSYNC) \ s(SL_IID_VIBRA) \ s(SL_IID_VIRTUALIZER) \ s(SL_IID_VISUALIZATION) \ s(SL_IID_VOLUME) #define IID(s) __typeof__(s) s; IIDS(IID) #undef IID #define FUNCTIONS(f) \ f(slCreateEngine) \ f(slQueryNumSupportedEngineInterfaces) \ f(slQuerySupportedEngineInterfaces) #define STUB(s) __typeof__(s)* s; static struct { FUNCTIONS(STUB) } stubs; #undef STUB __attribute__((constructor)) static void init() { // simulate LD_PRELOAD=/system/lib64/libskcodec.so void *skcodec_handle = dlopen(SKCODEC, RTLD_GLOBAL); // ignore errors, we only need to upload it to global namespace void* handle = dlopen(LIB, RTLD_LOCAL); if (skcodec_handle) dlclose(skcodec_handle); // if the library is needed by any of libOpenSLES dependencies it will not be unloaded // Nothing bad happened, normal case for termux-docker. if (!handle) return; #define IID(s) s = *((SLInterfaceID*) dlsym(handle, #s)); IIDS(IID) #undef IID #define LOAD(s) stubs.s = dlsym(handle, #s); FUNCTIONS(LOAD) #undef LOAD } #define CALL(f, def, ...) if (!stubs.f) return def; else return (stubs.f)(__VA_ARGS__) SL_API SLresult SLAPIENTRY slCreateEngine(SLObjectItf *pEngine, SLuint32 numOptions, const SLEngineOption *pEngineOptions, SLuint32 numInterfaces, const SLInterfaceID *pInterfaceIds, const SLboolean* pInterfaceRequired) { CALL(slCreateEngine, SL_RESULT_FEATURE_UNSUPPORTED, pEngine, numOptions, pEngineOptions, numInterfaces, pInterfaceIds, pInterfaceRequired); } SL_API SLresult SLAPIENTRY slQueryNumSupportedEngineInterfaces(SLuint32* pNumSupportedInterfaces) { CALL(slQueryNumSupportedEngineInterfaces, SL_RESULT_FEATURE_UNSUPPORTED, pNumSupportedInterfaces); } SL_API SLresult SLAPIENTRY slQuerySupportedEngineInterfaces(SLuint32 index, SLInterfaceID* pInterfaceId) { CALL(slQuerySupportedEngineInterfaces, SL_RESULT_FEATURE_UNSUPPORTED, index, pInterfaceId); }