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);
pluginInstance->create (state);
@@ -522,9 +541,9 @@ namespace UnityCallbacks
onWrapperCreation (pluginInstance);
return 0;
}
};
static int UNITY_INTERFACE_API releaseCallback (UnityAudioEffectState* state)
result.release = [] (UnityAudioEffectState* state)
{
auto* pluginInstance = state->getEffectData<AudioProcessorUnityWrapper>();
pluginInstance->release();
@@ -536,32 +555,58 @@ namespace UnityCallbacks
shutdownJuce_GUI();
return 0;
}
};
static int UNITY_INTERFACE_API resetCallback (UnityAudioEffectState* state)
result.reset = [] (UnityAudioEffectState* state)
{
auto* pluginInstance = state->getEffectData<AudioProcessorUnityWrapper>();
pluginInstance->reset();
return 0;
}
};
static int UNITY_INTERFACE_API setPositionCallback (UnityAudioEffectState* state, unsigned int pos)
result.setPosition = [] (UnityAudioEffectState* state, unsigned int pos)
{
ignoreUnused (state, pos);
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>();
pluginInstance->setParameter (index, value);
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>();
*value = pluginInstance->getParameter (index);
@@ -569,21 +614,21 @@ namespace UnityCallbacks
pluginInstance->getParameterString (index).copyToUTF8 (valueStr, 15);
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);
auto nameStr = String (name);
const StringRef kindStr { kind };
if (nameStr == "Editor")
if (kindStr == StringRef ("Editor"))
{
auto* pluginInstance = state->getEffectData<AudioProcessorUnityWrapper>();
buffer[0] = pluginInstance->hasEditor() ? 1.0f : 0.0f;
}
else if (nameStr == "ID")
else if (kindStr == StringRef ("ID"))
{
auto* pluginInstance = state->getEffectData<AudioProcessorUnityWrapper>();
@@ -598,7 +643,7 @@ namespace UnityCallbacks
return 0;
}
else if (nameStr == "Size")
else if (kindStr == StringRef ("Size"))
{
auto* pluginInstance = state->getEffectData<AudioProcessorUnityWrapper>();
@@ -613,87 +658,31 @@ namespace UnityCallbacks
}
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
// 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)
{
if (juce::getWrapperMap().size() == 0)
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::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;
}


Loading…
Cancel
Save