Browse Source

Unity Client: Avoid returning pointer to stack memory

v7.0.9
reuk 2 years ago
parent
commit
c51bfd7429
No known key found for this signature in database GPG Key ID: FCB43929F012EE5C
1 changed files with 74 additions and 85 deletions
  1. +74
    -85
      modules/juce_audio_plugin_client/Unity/juce_Unity_Wrapper.cpp

+ 74
- 85
modules/juce_audio_plugin_client/Unity/juce_Unity_Wrapper.cpp View File

@@ -510,9 +510,28 @@ static void onWrapperDeletion (AudioProcessorUnityWrapper* wrapperToRemove)
} }
//============================================================================== //==============================================================================
namespace UnityCallbacks
static UnityAudioEffectDefinition getEffectDefinition()
{ {
static int UNITY_INTERFACE_API createCallback (UnityAudioEffectState* state)
const auto wrapper = std::make_unique<AudioProcessorUnityWrapper> (true);
const String originalName { JucePlugin_Name };
const auto name = (! originalName.startsWithIgnoreCase ("audioplugin") ? "audioplugin_" : "") + originalName;
UnityAudioEffectDefinition result{};
name.copyToUTF8 (result.name, (size_t) numElementsInArray (result.name));
result.structSize = sizeof (UnityAudioEffectDefinition);
result.parameterStructSize = sizeof (UnityAudioParameterDefinition);
result.apiVersion = UNITY_AUDIO_PLUGIN_API_VERSION;
result.pluginVersion = JucePlugin_VersionCode;
// effects must set this to 0, generators > 0
result.channels = (wrapper->getNumInputChannels() != 0 ? 0
: static_cast<uint32> (wrapper->getNumOutputChannels()));
wrapper->declareParameters (result);
result.create = [] (UnityAudioEffectState* state)
{ {
auto* pluginInstance = new AudioProcessorUnityWrapper (false); auto* pluginInstance = new AudioProcessorUnityWrapper (false);
pluginInstance->create (state); pluginInstance->create (state);
@@ -522,9 +541,9 @@ namespace UnityCallbacks
onWrapperCreation (pluginInstance); onWrapperCreation (pluginInstance);
return 0; return 0;
}
};
static int UNITY_INTERFACE_API releaseCallback (UnityAudioEffectState* state)
result.release = [] (UnityAudioEffectState* state)
{ {
auto* pluginInstance = state->getEffectData<AudioProcessorUnityWrapper>(); auto* pluginInstance = state->getEffectData<AudioProcessorUnityWrapper>();
pluginInstance->release(); pluginInstance->release();
@@ -536,32 +555,58 @@ namespace UnityCallbacks
shutdownJuce_GUI(); shutdownJuce_GUI();
return 0; return 0;
}
};
static int UNITY_INTERFACE_API resetCallback (UnityAudioEffectState* state)
result.reset = [] (UnityAudioEffectState* state)
{ {
auto* pluginInstance = state->getEffectData<AudioProcessorUnityWrapper>(); auto* pluginInstance = state->getEffectData<AudioProcessorUnityWrapper>();
pluginInstance->reset(); pluginInstance->reset();
return 0; return 0;
}
};
static int UNITY_INTERFACE_API setPositionCallback (UnityAudioEffectState* state, unsigned int pos)
result.setPosition = [] (UnityAudioEffectState* state, unsigned int pos)
{ {
ignoreUnused (state, pos); ignoreUnused (state, pos);
return 0; return 0;
}
};
result.process = [] (UnityAudioEffectState* state,
float* inBuffer,
float* outBuffer,
unsigned int bufferSize,
int numInChannels,
int numOutChannels)
{
auto* pluginInstance = state->getEffectData<AudioProcessorUnityWrapper>();
if (pluginInstance != nullptr)
{
auto isPlaying = ((state->flags & stateIsPlaying) != 0);
auto isMuted = ((state->flags & stateIsMuted) != 0);
auto isPaused = ((state->flags & stateIsPaused) != 0);
static int UNITY_INTERFACE_API setFloatParameterCallback (UnityAudioEffectState* state, int index, float value)
const auto bypassed = ! isPlaying || (isMuted || isPaused);
pluginInstance->process (inBuffer, outBuffer, static_cast<int> (bufferSize), numInChannels, numOutChannels, bypassed);
}
else
{
FloatVectorOperations::clear (outBuffer, static_cast<int> (bufferSize) * numOutChannels);
}
return 0;
};
result.setFloatParameter = [] (UnityAudioEffectState* state, int index, float value)
{ {
auto* pluginInstance = state->getEffectData<AudioProcessorUnityWrapper>(); auto* pluginInstance = state->getEffectData<AudioProcessorUnityWrapper>();
pluginInstance->setParameter (index, value); pluginInstance->setParameter (index, value);
return 0; return 0;
}
};
static int UNITY_INTERFACE_API getFloatParameterCallback (UnityAudioEffectState* state, int index, float* value, char* valueStr)
result.getFloatParameter = [] (UnityAudioEffectState* state, int index, float* value, char* valueStr)
{ {
auto* pluginInstance = state->getEffectData<AudioProcessorUnityWrapper>(); auto* pluginInstance = state->getEffectData<AudioProcessorUnityWrapper>();
*value = pluginInstance->getParameter (index); *value = pluginInstance->getParameter (index);
@@ -569,21 +614,21 @@ namespace UnityCallbacks
pluginInstance->getParameterString (index).copyToUTF8 (valueStr, 15); pluginInstance->getParameterString (index).copyToUTF8 (valueStr, 15);
return 0; return 0;
}
};
static int UNITY_INTERFACE_API getFloatBufferCallback (UnityAudioEffectState* state, const char* name, float* buffer, int numSamples)
result.getFloatBuffer = [] (UnityAudioEffectState* state, const char* kind, float* buffer, int numSamples)
{ {
ignoreUnused (numSamples); ignoreUnused (numSamples);
auto nameStr = String (name);
const StringRef kindStr { kind };
if (nameStr == "Editor")
if (kindStr == StringRef ("Editor"))
{ {
auto* pluginInstance = state->getEffectData<AudioProcessorUnityWrapper>(); auto* pluginInstance = state->getEffectData<AudioProcessorUnityWrapper>();
buffer[0] = pluginInstance->hasEditor() ? 1.0f : 0.0f; buffer[0] = pluginInstance->hasEditor() ? 1.0f : 0.0f;
} }
else if (nameStr == "ID")
else if (kindStr == StringRef ("ID"))
{ {
auto* pluginInstance = state->getEffectData<AudioProcessorUnityWrapper>(); auto* pluginInstance = state->getEffectData<AudioProcessorUnityWrapper>();
@@ -598,7 +643,7 @@ namespace UnityCallbacks
return 0; return 0;
} }
else if (nameStr == "Size")
else if (kindStr == StringRef ("Size"))
{ {
auto* pluginInstance = state->getEffectData<AudioProcessorUnityWrapper>(); auto* pluginInstance = state->getEffectData<AudioProcessorUnityWrapper>();
@@ -613,87 +658,31 @@ namespace UnityCallbacks
} }
return 0; return 0;
}
static int UNITY_INTERFACE_API processCallback (UnityAudioEffectState* state, float* inBuffer, float* outBuffer,
unsigned int bufferSize, int numInChannels, int numOutChannels)
{
auto* pluginInstance = state->getEffectData<AudioProcessorUnityWrapper>();
if (pluginInstance != nullptr)
{
auto isPlaying = ((state->flags & stateIsPlaying) != 0);
auto isMuted = ((state->flags & stateIsMuted) != 0);
auto isPaused = ((state->flags & stateIsPaused) != 0);
const auto bypassed = ! isPlaying || (isMuted || isPaused);
pluginInstance->process (inBuffer, outBuffer, static_cast<int> (bufferSize), numInChannels, numOutChannels, bypassed);
}
else
{
FloatVectorOperations::clear (outBuffer, static_cast<int> (bufferSize) * numOutChannels);
}
return 0;
}
}
//==============================================================================
static void declareEffect (UnityAudioEffectDefinition& definition)
{
memset (&definition, 0, sizeof (definition));
std::unique_ptr<AudioProcessorUnityWrapper> wrapper = std::make_unique<AudioProcessorUnityWrapper> (true);
String name (JucePlugin_Name);
if (! name.startsWithIgnoreCase ("audioplugin"))
name = "audioplugin_" + name;
name.copyToUTF8 (definition.name, (size_t) numElementsInArray (definition.name));
definition.structSize = sizeof (UnityAudioEffectDefinition);
definition.parameterStructSize = sizeof (UnityAudioParameterDefinition);
definition.apiVersion = UNITY_AUDIO_PLUGIN_API_VERSION;
definition.pluginVersion = JucePlugin_VersionCode;
};
// effects must set this to 0, generators > 0
definition.channels = (wrapper->getNumInputChannels() != 0 ? 0
: static_cast<uint32> (wrapper->getNumOutputChannels()));
wrapper->declareParameters (definition);
definition.create = UnityCallbacks::createCallback;
definition.release = UnityCallbacks::releaseCallback;
definition.reset = UnityCallbacks::resetCallback;
definition.setPosition = UnityCallbacks::setPositionCallback;
definition.process = UnityCallbacks::processCallback;
definition.setFloatParameter = UnityCallbacks::setFloatParameterCallback;
definition.getFloatParameter = UnityCallbacks::getFloatParameterCallback;
definition.getFloatBuffer = UnityCallbacks::getFloatBufferCallback;
return result;
} }
} // namespace juce } // namespace juce
// From reading the example code, it seems that the triple indirection indicates
// an out-value of an array of pointers. That is, after calling this function, definitionsPtr
// should point to a pre-existing/static array of pointer-to-effect-definition.
UNITY_INTERFACE_EXPORT int UNITY_INTERFACE_API UnityGetAudioEffectDefinitions (UnityAudioEffectDefinition*** definitionsPtr) UNITY_INTERFACE_EXPORT int UNITY_INTERFACE_API UnityGetAudioEffectDefinitions (UnityAudioEffectDefinition*** definitionsPtr)
{ {
if (juce::getWrapperMap().size() == 0) if (juce::getWrapperMap().size() == 0)
juce::initialiseJuce_GUI(); juce::initialiseJuce_GUI();
static bool hasInitialised = false;
if (! hasInitialised)
static std::once_flag flag;
std::call_once (flag, []
{ {
juce::PluginHostType::jucePlugInClientCurrentWrapperType = juce::AudioProcessor::wrapperType_Unity; juce::PluginHostType::jucePlugInClientCurrentWrapperType = juce::AudioProcessor::wrapperType_Unity;
juce::juce_createUnityPeerFn = juce::createUnityPeer; juce::juce_createUnityPeerFn = juce::createUnityPeer;
});
hasInitialised = true;
}
auto* definition = new UnityAudioEffectDefinition();
juce::declareEffect (*definition);
*definitionsPtr = &definition;
static auto definition = juce::getEffectDefinition();
static UnityAudioEffectDefinition* definitions[] { &definition };
*definitionsPtr = definitions;
return 1; return 1;
} }


Loading…
Cancel
Save