This commit is contained in:
bjorn 2021-02-15 13:26:08 -07:00 committed by Bjorn
parent 8bbb092497
commit f4a8a4d388
1 changed files with 155 additions and 5 deletions

View File

@ -1,24 +1,174 @@
#include "spatializer.h"
#include <phonon.h>
#include <string.h>
#ifdef _WIN32
#include <windows.h>
#define PHONON_LIBRARY "phonon.dll"
static void* phonon_dlopen(const char* library) { return LoadLibraryA(library); }
static FARPROC phonon_dlsym(void* library, const char* symbol) { return GetProcAddress(library, symbol); }
static void phonon_dlclose(void* library) { FreeLibrary(library); }
#else
#include <dlfcn.h>
#define PHONON_LIBRARY "libphonon.so"
static void* phonon_dlopen(const char* library) { return dlopen(library, RTLD_NOW | RTLD_LOCAL); }
static void* phonon_dlsym(void* library, const char* symbol) { return dlsym(library, symbol); }
static void phonon_dlclose(void* library) { dlclose(library); }
#endif
typedef IPLerror fn_iplCreateContext(IPLLogFunction logCallback, IPLAllocateFunction allocateCallback, IPLFreeFunction freeCallback, IPLhandle* context);
typedef IPLvoid fn_iplDestroyContext(IPLhandle* context);
typedef IPLvoid fn_iplCleanup(void);
typedef IPLerror fn_iplCreateEnvironment(IPLhandle context, IPLhandle computeDevice, IPLSimulationSettings simulationSettings, IPLhandle scene, IPLhandle probeManager, IPLhandle* environment);
typedef IPLvoid fn_iplDestroyEnvironment(IPLhandle* environment);
typedef IPLerror fn_iplCreateDirectSoundEffect(IPLAudioFormat inputFormat, IPLAudioFormat outputFormat, IPLRenderingSettings renderingSettings, IPLhandle* effect);
typedef IPLvoid fn_iplDestroyDirectSoundEffect(IPLhandle* effect);
typedef IPLvoid fn_iplApplyDirectSoundEffect(IPLhandle effect, IPLAudioBuffer inputAudio, IPLDirectSoundPath directSoundPath, IPLDirectSoundEffectOptions options, IPLAudioBuffer outputAudio);
typedef IPLDirectSoundPath fn_iplGetDirectSoundPath(IPLhandle environment, IPLVector3 listenerPosition, IPLVector3 listenerAhead, IPLVector3 listenerUp, IPLSource source, IPLfloat32 sourceRadius, IPLint32 numSamples, IPLDirectOcclusionMode occlusionMode, IPLDirectOcclusionMethod occlusionMethod);
#define PHONON_DECLARE(f) static fn_##f* phonon_##f;
#define PHONON_LOAD(f) phonon_##f = (fn_##f*) phonon_dlsym(state.library, #f);
#define PHONON_FOREACH(X)\
X(iplCreateContext)\
X(iplDestroyContext)\
X(iplCleanup)\
X(iplCreateEnvironment)\
X(iplDestroyEnvironment)\
X(iplCreateDirectSoundEffect)\
X(iplDestroyDirectSoundEffect)\
X(iplApplyDirectSoundEffect)\
X(iplGetDirectSoundPath)
PHONON_FOREACH(PHONON_DECLARE)
static struct {
void* library;
IPLhandle context;
IPLhandle environment;
IPLhandle directSoundEffect;
float listenerPosition[4];
float listenerOrientation[4];
} state;
static void phonon_destroy(void);
bool phonon_init(SpatializerConfig config) {
return false;
state.library = phonon_dlopen(PHONON_LIBRARY);
if (!state.library) return false;
PHONON_FOREACH(PHONON_LOAD)
IPLerror status;
status = phonon_iplCreateContext(NULL, NULL, NULL, &state.context);
if (status != IPL_STATUS_SUCCESS) {
phonon_destroy();
return false;
}
IPLSimulationSettings simulationSettings = { 0 };
status = phonon_iplCreateEnvironment(state.context, NULL, simulationSettings, NULL, NULL, &state.environment);
if (status != IPL_STATUS_SUCCESS) {
phonon_destroy();
return false;
}
IPLAudioFormat inputFormat = {
.channelLayoutType = IPL_CHANNELLAYOUTTYPE_SPEAKERS,
.channelLayout = IPL_CHANNELLAYOUT_MONO,
.channelOrder = IPL_CHANNELORDER_INTERLEAVED
};
IPLAudioFormat outputFormat = {
.channelLayoutType = IPL_CHANNELLAYOUTTYPE_SPEAKERS,
.channelLayout = IPL_CHANNELLAYOUT_STEREO,
.channelOrder = IPL_CHANNELORDER_INTERLEAVED
};
IPLRenderingSettings renderingSettings = {
.samplingRate = config.sampleRate,
.frameSize = config.fixedBufferSize
};
status = phonon_iplCreateDirectSoundEffect(inputFormat, outputFormat, renderingSettings, &state.directSoundEffect);
if (status != IPL_STATUS_SUCCESS) {
phonon_destroy();
return false;
}
return true;
}
void phonon_destroy() {
//
if (state.directSoundEffect) phonon_iplDestroyDirectSoundEffect(&state.directSoundEffect);
if (state.environment) phonon_iplDestroyEnvironment(&state.environment);
if (state.context) phonon_iplDestroyContext(&state.context);
phonon_iplCleanup();
phonon_dlclose(state.library);
}
uint32_t phonon_apply(Source* source, const float* input, float* output, uint32_t frames, uint32_t _frames) {
return 0;
uint32_t phonon_apply(Source* source, const float* input, float* output, uint32_t frames, uint32_t why) {
IPLVector3 listenerPosition = { state.listenerPosition[0], state.listenerPosition[1], state.listenerPosition[2] };
IPLVector3 listenerForward = { 0 }; // TODO
IPLVector3 listenerUp = { 0 }; // TODO
float position[4], orientation[4];
lovrSourceGetPose(source, position, orientation);
IPLSource iplSource = {
.position = (IPLVector3) { position[0], position[1], position[2] },
.ahead = (IPLVector3) { 0 /* TODO */ },
.up = (IPLVector3) { 0 /* TODO */ },
.right = (IPLVector3) { 0 /* TODO */ },
.directivity = {
.dipoleWeight = 0.f,
.dipolePower = 0.f
},
.distanceAttenuationModel.type = IPL_DISTANCEATTENUATION_DEFAULT,
.airAbsorptionModel.type = IPL_AIRABSORPTION_DEFAULT
};
IPLDirectOcclusionMode occlusionMode = IPL_DIRECTOCCLUSION_NONE;
IPLDirectOcclusionMethod occlusionMethod = IPL_DIRECTOCCLUSION_RAYCAST;
IPLDirectSoundPath path = phonon_iplGetDirectSoundPath(state.environment, listenerPosition, listenerForward, listenerUp, iplSource, 0.f, 1, occlusionMode, occlusionMethod);
IPLDirectSoundEffectOptions options = {
.applyDistanceAttenuation = IPL_TRUE,
.applyAirAbsorption = IPL_TRUE,
.applyDirectivity = IPL_TRUE,
.directOcclusionMode = occlusionMode
};
IPLAudioFormat format = {
.channelLayoutType = IPL_CHANNELLAYOUTTYPE_SPEAKERS,
.channelLayout = IPL_CHANNELLAYOUT_MONO,
.channelOrder = IPL_CHANNELORDER_INTERLEAVED
};
IPLAudioBuffer inputBuffer = {
.format = format,
.numSamples = frames,
.interleavedBuffer = (float*) input
};
IPLAudioBuffer outputBuffer = {
.format = format,
.numSamples = frames,
.interleavedBuffer = output
};
phonon_iplApplyDirectSoundEffect(state.directSoundEffect, inputBuffer, path, options, outputBuffer);
return frames;
}
uint32_t phonon_tail(float* scratch, float* output, uint32_t frames) {
return 0;
}
// TODO lock/transact
void phonon_setListenerPose(float position[4], float orientation[4]) {
//
memcpy(state.listenerPosition, position, sizeof(state.listenerPosition));
memcpy(state.listenerOrientation, orientation, sizeof(state.listenerOrientation));
}
void phonon_sourceCreate(Source* source) {