#include <stdint.h>
#include <array>
#include "base/containers/span.h"
#include "base/memory/raw_ptr.h"
#define const
#include <SLES/OpenSLES.h>
#include <SLES/OpenSLES_Android.h>
#undef const
#include <stddef.h>
#include "base/files/file_path.h"
#include "base/logging.h"
#include "base/native_library.h"
SLInterfaceID SL_IID_ENGINE = nullptr;
SLInterfaceID SL_IID_ANDROIDSIMPLEBUFFERQUEUE = nullptr;
SLInterfaceID SL_IID_ANDROIDCONFIGURATION = nullptr;
SLInterfaceID SL_IID_RECORD = nullptr;
SLInterfaceID SL_IID_BUFFERQUEUE = nullptr;
SLInterfaceID SL_IID_VOLUME = nullptr;
SLInterfaceID SL_IID_PLAY = nullptr;
namespace {
const char kOpenSLLibraryName[] = "libOpenSLES.so";
base::NativeLibrary IntializeLibraryHandle() {
base::NativeLibrary handle =
base::LoadNativeLibrary(base::FilePath(kOpenSLLibraryName), nullptr);
if (!handle) {
DLOG(ERROR) << "Unable to load " << kOpenSLLibraryName;
return nullptr;
}
struct SymbolDefinition {
const char* name;
raw_ptr<SLInterfaceID> sl_iid;
};
auto kSymbols = std::to_array<const SymbolDefinition>(
{{"SL_IID_ENGINE", &SL_IID_ENGINE},
{"SL_IID_ANDROIDSIMPLEBUFFERQUEUE", &SL_IID_ANDROIDSIMPLEBUFFERQUEUE},
{"SL_IID_ANDROIDCONFIGURATION", &SL_IID_ANDROIDCONFIGURATION},
{"SL_IID_RECORD", &SL_IID_RECORD},
{"SL_IID_BUFFERQUEUE", &SL_IID_BUFFERQUEUE},
{"SL_IID_VOLUME", &SL_IID_VOLUME},
{"SL_IID_PLAY", &SL_IID_PLAY}});
for (auto& symbol : kSymbols) {
void* func_ptr =
base::GetFunctionPointerFromNativeLibrary(handle, symbol.name);
if (!func_ptr) {
DLOG(ERROR) << "Unable to find symbol for " << symbol.name;
return nullptr;
}
base::byte_span_from_ref(*symbol.sl_iid)
.copy_from(base::byte_span_from_ref(
*reinterpret_cast<SLInterfaceID*>(func_ptr)));
}
return handle;
}
base::NativeLibrary LibraryHandle() {
static base::NativeLibrary g_handle = IntializeLibraryHandle();
return g_handle;
}
}
SLresult slCreateEngine(SLObjectItf* engine,
SLuint32 num_options,
SLEngineOption* engine_options,
SLuint32 num_interfaces,
SLInterfaceID* interface_ids,
SLboolean* interfaces_required) {
typedef SLresult (*SlCreateEngineSignature)(SLObjectItf*, SLuint32,
SLEngineOption*, SLuint32,
SLInterfaceID*, SLboolean*);
base::NativeLibrary handle = LibraryHandle();
if (!handle)
return SL_RESULT_INTERNAL_ERROR;
static SlCreateEngineSignature g_sl_create_engine_handle =
reinterpret_cast<SlCreateEngineSignature>(
base::GetFunctionPointerFromNativeLibrary(handle, "slCreateEngine"));
if (!g_sl_create_engine_handle) {
DLOG(ERROR) << "Unable to find symbol for slCreateEngine";
return SL_RESULT_INTERNAL_ERROR;
}
return g_sl_create_engine_handle(engine, num_options, engine_options,
num_interfaces, interface_ids,
interfaces_required);
}