upgrade to JUCE 5.4.3. Remove (probably) unused JUCE modules. Remove VST2 target (it's been end-of-life'd by Steinberg and by JUCE)
This commit is contained in:
		@ -0,0 +1,191 @@
 | 
			
		||||
/*
 | 
			
		||||
  ==============================================================================
 | 
			
		||||
 | 
			
		||||
   This file is part of the JUCE library.
 | 
			
		||||
   Copyright (c) 2017 - ROLI Ltd.
 | 
			
		||||
 | 
			
		||||
   JUCE is an open source library subject to commercial or open-source
 | 
			
		||||
   licensing.
 | 
			
		||||
 | 
			
		||||
   By using JUCE, you agree to the terms of both the JUCE 5 End-User License
 | 
			
		||||
   Agreement and JUCE 5 Privacy Policy (both updated and effective as of the
 | 
			
		||||
   27th April 2017).
 | 
			
		||||
 | 
			
		||||
   End User License Agreement: www.juce.com/juce-5-licence
 | 
			
		||||
   Privacy Policy: www.juce.com/juce-5-privacy-policy
 | 
			
		||||
 | 
			
		||||
   Or: You may also use this code under the terms of the GPL v3 (see
 | 
			
		||||
   www.gnu.org/licenses).
 | 
			
		||||
 | 
			
		||||
   JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
 | 
			
		||||
   EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
 | 
			
		||||
   DISCLAIMED.
 | 
			
		||||
 | 
			
		||||
  ==============================================================================
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
#pragma once
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
//==============================================================================
 | 
			
		||||
#define UNITY_AUDIO_PLUGIN_API_VERSION 0x010401
 | 
			
		||||
 | 
			
		||||
#if JUCE_WINDOWS
 | 
			
		||||
 #define UNITY_INTERFACE_API __stdcall
 | 
			
		||||
 #define UNITY_INTERFACE_EXPORT __declspec(dllexport)
 | 
			
		||||
#else
 | 
			
		||||
 #define UNITY_INTERFACE_API
 | 
			
		||||
 #define UNITY_INTERFACE_EXPORT __attribute__ ((visibility("default")))
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
//==============================================================================
 | 
			
		||||
struct UnityAudioEffectState;
 | 
			
		||||
 | 
			
		||||
typedef int  (UNITY_INTERFACE_API * createCallback)              (UnityAudioEffectState* state);
 | 
			
		||||
typedef int  (UNITY_INTERFACE_API * releaseCallback)             (UnityAudioEffectState* state);
 | 
			
		||||
typedef int  (UNITY_INTERFACE_API * resetCallback)               (UnityAudioEffectState* state);
 | 
			
		||||
 | 
			
		||||
typedef int  (UNITY_INTERFACE_API * processCallback)             (UnityAudioEffectState* state, float* inBuffer, float* outBuffer, unsigned int bufferSize,
 | 
			
		||||
                                                                  int numInChannels, int numOutChannels);
 | 
			
		||||
 | 
			
		||||
typedef int  (UNITY_INTERFACE_API * setPositionCallback)         (UnityAudioEffectState* state, unsigned int pos);
 | 
			
		||||
 | 
			
		||||
typedef int  (UNITY_INTERFACE_API * setFloatParameterCallback)   (UnityAudioEffectState* state, int index, float value);
 | 
			
		||||
typedef int  (UNITY_INTERFACE_API * getFloatParameterCallback)   (UnityAudioEffectState* state, int index, float* value, char* valuestr);
 | 
			
		||||
typedef int  (UNITY_INTERFACE_API * getFloatBufferCallback)      (UnityAudioEffectState* state, const char* name, float* buffer, int numsamples);
 | 
			
		||||
 | 
			
		||||
typedef int  (UNITY_INTERFACE_API * distanceAttenuationCallback) (UnityAudioEffectState* state, float distanceIn, float attenuationIn, float* attenuationOut);
 | 
			
		||||
 | 
			
		||||
typedef void (UNITY_INTERFACE_API * renderCallback)              (int eventId);
 | 
			
		||||
 | 
			
		||||
//==============================================================================
 | 
			
		||||
enum UnityAudioEffectDefinitionFlags
 | 
			
		||||
{
 | 
			
		||||
    isSideChainTarget = 1,
 | 
			
		||||
    isSpatializer = 2,
 | 
			
		||||
    isAmbisonicDecoder = 4,
 | 
			
		||||
    appliesDistanceAttenuation = 8
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
enum UnityAudioEffectStateFlags
 | 
			
		||||
{
 | 
			
		||||
    stateIsPlaying = 1,
 | 
			
		||||
    stateIsPaused = 2,
 | 
			
		||||
    stateIsMuted = 8,
 | 
			
		||||
    statIsSideChainTarget = 16
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
enum UnityEventModifiers
 | 
			
		||||
{
 | 
			
		||||
    shift = 1,
 | 
			
		||||
    control = 2,
 | 
			
		||||
    alt = 4,
 | 
			
		||||
    command = 8,
 | 
			
		||||
    numeric = 16,
 | 
			
		||||
    capsLock = 32,
 | 
			
		||||
    functionKey = 64
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
//==============================================================================
 | 
			
		||||
struct UnityAudioSpatializerData
 | 
			
		||||
{
 | 
			
		||||
    float                          listenerMatrix[16];
 | 
			
		||||
    float                          sourceMatrix[16];
 | 
			
		||||
    float                          spatialBlend;
 | 
			
		||||
    float                          reverbZoneMix;
 | 
			
		||||
    float                          spread;
 | 
			
		||||
    float                          stereoPan;
 | 
			
		||||
    distanceAttenuationCallback    attenuationCallback;
 | 
			
		||||
    float                          minDistance;
 | 
			
		||||
    float                          maxDistance;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
struct UnityAudioAmbisonicData
 | 
			
		||||
{
 | 
			
		||||
    float                          listenerMatrix[16];
 | 
			
		||||
    float                          sourceMatrix[16];
 | 
			
		||||
    float                          spatialBlend;
 | 
			
		||||
    float                          reverbZoneMix;
 | 
			
		||||
    float                          spread;
 | 
			
		||||
    float                          stereoPan;
 | 
			
		||||
    distanceAttenuationCallback    attenuationCallback;
 | 
			
		||||
    int                            ambisonicOutChannels;
 | 
			
		||||
    float                          volume;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
struct UnityAudioEffectState
 | 
			
		||||
{
 | 
			
		||||
    juce::uint32               structSize;
 | 
			
		||||
    juce::uint32               sampleRate;
 | 
			
		||||
    juce::uint64               dspCurrentTick;
 | 
			
		||||
    juce::uint64               dspPreviousTick;
 | 
			
		||||
    float*                     sidechainBuffer;
 | 
			
		||||
    void*                      effectData;
 | 
			
		||||
    juce::uint32               flags;
 | 
			
		||||
    void*                      internal;
 | 
			
		||||
 | 
			
		||||
    UnityAudioSpatializerData* spatializerData;
 | 
			
		||||
    juce::uint32               dspBufferSize;
 | 
			
		||||
    juce::uint32               hostAPIVersion;
 | 
			
		||||
 | 
			
		||||
    UnityAudioAmbisonicData*   ambisonicData;
 | 
			
		||||
 | 
			
		||||
    template<typename T>
 | 
			
		||||
    inline T* getEffectData() const
 | 
			
		||||
    {
 | 
			
		||||
        jassert (effectData != nullptr);
 | 
			
		||||
        jassert (internal != nullptr);
 | 
			
		||||
 | 
			
		||||
        return (T*) effectData;
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
struct UnityAudioParameterDefinition
 | 
			
		||||
{
 | 
			
		||||
    char        name[16];
 | 
			
		||||
    char        unit[16];
 | 
			
		||||
    const char* description;
 | 
			
		||||
    float       min;
 | 
			
		||||
    float       max;
 | 
			
		||||
    float       defaultVal;
 | 
			
		||||
    float       displayScale;
 | 
			
		||||
    float       displayExponent;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
struct UnityAudioEffectDefinition
 | 
			
		||||
{
 | 
			
		||||
    juce::uint32                   structSize;
 | 
			
		||||
    juce::uint32                   parameterStructSize;
 | 
			
		||||
    juce::uint32                   apiVersion;
 | 
			
		||||
    juce::uint32                   pluginVersion;
 | 
			
		||||
    juce::uint32                   channels;
 | 
			
		||||
    juce::uint32                   numParameters;
 | 
			
		||||
    juce::uint64                   flags;
 | 
			
		||||
    char                           name[32];
 | 
			
		||||
    createCallback                 create;
 | 
			
		||||
    releaseCallback                release;
 | 
			
		||||
    resetCallback                  reset;
 | 
			
		||||
    processCallback                process;
 | 
			
		||||
    setPositionCallback            setPosition;
 | 
			
		||||
    UnityAudioParameterDefinition* parameterDefintions;
 | 
			
		||||
    setFloatParameterCallback      setFloatParameter;
 | 
			
		||||
    getFloatParameterCallback      getFloatParameter;
 | 
			
		||||
    getFloatBufferCallback         getFloatBuffer;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
//==============================================================================
 | 
			
		||||
// Unity callback
 | 
			
		||||
extern "C" UNITY_INTERFACE_EXPORT int  UNITY_INTERFACE_API UnityGetAudioEffectDefinitions (UnityAudioEffectDefinition*** definitionsPtr);
 | 
			
		||||
 | 
			
		||||
// GUI script callbacks
 | 
			
		||||
extern "C" UNITY_INTERFACE_EXPORT renderCallback UNITY_INTERFACE_API getRenderCallback();
 | 
			
		||||
 | 
			
		||||
extern "C" UNITY_INTERFACE_EXPORT void UNITY_INTERFACE_API unityInitialiseTexture (int id, void* textureHandle, int w, int h);
 | 
			
		||||
 | 
			
		||||
extern "C" UNITY_INTERFACE_EXPORT void UNITY_INTERFACE_API unityMouseDown (int id, float x, float y, UnityEventModifiers mods, int button);
 | 
			
		||||
extern "C" UNITY_INTERFACE_EXPORT void UNITY_INTERFACE_API unityMouseDrag (int id, float x, float y, UnityEventModifiers mods, int button);
 | 
			
		||||
extern "C" UNITY_INTERFACE_EXPORT void UNITY_INTERFACE_API unityMouseUp   (int id, float x, float y, UnityEventModifiers mods);
 | 
			
		||||
 | 
			
		||||
extern "C" UNITY_INTERFACE_EXPORT void UNITY_INTERFACE_API unityKeyEvent (int id, int code, UnityEventModifiers mods, const char* name);
 | 
			
		||||
 | 
			
		||||
extern "C" UNITY_INTERFACE_EXPORT void UNITY_INTERFACE_API unitySetScreenBounds (int id, float x, float y, float w, float h);
 | 
			
		||||
							
								
								
									
										768
									
								
								modules/juce_audio_plugin_client/Unity/juce_Unity_Wrapper.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										768
									
								
								modules/juce_audio_plugin_client/Unity/juce_Unity_Wrapper.cpp
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,768 @@
 | 
			
		||||
/*
 | 
			
		||||
  ==============================================================================
 | 
			
		||||
 | 
			
		||||
   This file is part of the JUCE library.
 | 
			
		||||
   Copyright (c) 2017 - ROLI Ltd.
 | 
			
		||||
 | 
			
		||||
   JUCE is an open source library subject to commercial or open-source
 | 
			
		||||
   licensing.
 | 
			
		||||
 | 
			
		||||
   By using JUCE, you agree to the terms of both the JUCE 5 End-User License
 | 
			
		||||
   Agreement and JUCE 5 Privacy Policy (both updated and effective as of the
 | 
			
		||||
   27th April 2017).
 | 
			
		||||
 | 
			
		||||
   End User License Agreement: www.juce.com/juce-5-licence
 | 
			
		||||
   Privacy Policy: www.juce.com/juce-5-privacy-policy
 | 
			
		||||
 | 
			
		||||
   Or: You may also use this code under the terms of the GPL v3 (see
 | 
			
		||||
   www.gnu.org/licenses).
 | 
			
		||||
 | 
			
		||||
   JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
 | 
			
		||||
   EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
 | 
			
		||||
   DISCLAIMED.
 | 
			
		||||
 | 
			
		||||
  ==============================================================================
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
#if JucePlugin_Build_Unity
 | 
			
		||||
 | 
			
		||||
#include "../../juce_core/system/juce_TargetPlatform.h"
 | 
			
		||||
#include "../utility/juce_IncludeModuleHeaders.h"
 | 
			
		||||
#include "../../juce_audio_processors/format_types/juce_LegacyAudioParameter.cpp"
 | 
			
		||||
 | 
			
		||||
#if JUCE_WINDOWS
 | 
			
		||||
 #include "../utility/juce_IncludeSystemHeaders.h"
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#include "juce_UnityPluginInterface.h"
 | 
			
		||||
 | 
			
		||||
//==============================================================================
 | 
			
		||||
namespace juce
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
typedef ComponentPeer* (*createUnityPeerFunctionType) (Component&);
 | 
			
		||||
extern createUnityPeerFunctionType juce_createUnityPeerFn;
 | 
			
		||||
 | 
			
		||||
//==============================================================================
 | 
			
		||||
class UnityPeer    : public ComponentPeer,
 | 
			
		||||
                     public AsyncUpdater
 | 
			
		||||
{
 | 
			
		||||
public:
 | 
			
		||||
    UnityPeer (Component& ed)
 | 
			
		||||
        : ComponentPeer (ed, 0),
 | 
			
		||||
          mouseWatcher (*this)
 | 
			
		||||
    {
 | 
			
		||||
        getEditor().setResizable (false, false);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    //==============================================================================
 | 
			
		||||
    Rectangle<int> getBounds() const override                              { return bounds; }
 | 
			
		||||
    Point<float> localToGlobal (Point<float> relativePosition) override    { return relativePosition + getBounds().getPosition().toFloat(); }
 | 
			
		||||
    Point<float> globalToLocal (Point<float> screenPosition) override      { return screenPosition - getBounds().getPosition().toFloat(); }
 | 
			
		||||
 | 
			
		||||
    StringArray getAvailableRenderingEngines() override                    { return StringArray ("Software Renderer"); }
 | 
			
		||||
 | 
			
		||||
    void setBounds (const Rectangle<int>& newBounds, bool) override
 | 
			
		||||
    {
 | 
			
		||||
        bounds = newBounds;
 | 
			
		||||
        mouseWatcher.setBoundsToWatch (bounds);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    bool contains (Point<int> localPos, bool) const override
 | 
			
		||||
    {
 | 
			
		||||
        if (isPositiveAndBelow (localPos.getX(), getBounds().getWidth())
 | 
			
		||||
               && isPositiveAndBelow (localPos.getY(), getBounds().getHeight()))
 | 
			
		||||
            return true;
 | 
			
		||||
 | 
			
		||||
        return false;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void handleAsyncUpdate() override
 | 
			
		||||
    {
 | 
			
		||||
        fillPixels();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    //==============================================================================
 | 
			
		||||
    AudioProcessorEditor& getEditor()    { return *dynamic_cast<AudioProcessorEditor*> (&getComponent()); }
 | 
			
		||||
 | 
			
		||||
    void setPixelDataHandle (uint8* handle, int width, int height)
 | 
			
		||||
    {
 | 
			
		||||
        pixelData = handle;
 | 
			
		||||
 | 
			
		||||
        textureWidth = width;
 | 
			
		||||
        textureHeight = height;
 | 
			
		||||
 | 
			
		||||
        renderImage = Image (new UnityBitmapImage (pixelData, width, height));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // N.B. This is NOT an efficient way to do this and you shouldn't use this method in your own code.
 | 
			
		||||
    // It works for our purposes here but a much more efficient way would be to use a GL texture.
 | 
			
		||||
    void fillPixels()
 | 
			
		||||
    {
 | 
			
		||||
        if (pixelData == nullptr)
 | 
			
		||||
            return;
 | 
			
		||||
 | 
			
		||||
        LowLevelGraphicsSoftwareRenderer renderer (renderImage);
 | 
			
		||||
        renderer.addTransform (AffineTransform::verticalFlip ((float) getComponent().getHeight()));
 | 
			
		||||
 | 
			
		||||
        handlePaint (renderer);
 | 
			
		||||
 | 
			
		||||
        for (int i = 0; i < textureWidth * textureHeight * 4; i += 4)
 | 
			
		||||
        {
 | 
			
		||||
            auto r = pixelData[i + 2];
 | 
			
		||||
            auto g = pixelData[i + 1];
 | 
			
		||||
            auto b = pixelData[i + 0];
 | 
			
		||||
 | 
			
		||||
            pixelData[i + 0] = r;
 | 
			
		||||
            pixelData[i + 1] = g;
 | 
			
		||||
            pixelData[i + 2] = b;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void forwardMouseEvent (Point<float> position, ModifierKeys mods)
 | 
			
		||||
    {
 | 
			
		||||
        ModifierKeys::currentModifiers = mods;
 | 
			
		||||
 | 
			
		||||
        handleMouseEvent (juce::MouseInputSource::mouse, position, mods, juce::MouseInputSource::invalidPressure,
 | 
			
		||||
                          juce::MouseInputSource::invalidOrientation, juce::Time::currentTimeMillis());
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void forwardKeyPress (int code, String name, ModifierKeys mods)
 | 
			
		||||
    {
 | 
			
		||||
        ModifierKeys::currentModifiers = mods;
 | 
			
		||||
 | 
			
		||||
        handleKeyPress (getKeyPress (code, name));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
private:
 | 
			
		||||
    //==============================================================================
 | 
			
		||||
    struct UnityBitmapImage    : public ImagePixelData
 | 
			
		||||
    {
 | 
			
		||||
        UnityBitmapImage (uint8* data, int w, int h)
 | 
			
		||||
            : ImagePixelData (Image::PixelFormat::ARGB, w, h),
 | 
			
		||||
              imageData (data),
 | 
			
		||||
              lineStride (width * pixelStride)
 | 
			
		||||
        {
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        ImageType* createType() const override                       { return new SoftwareImageType(); }
 | 
			
		||||
        LowLevelGraphicsContext* createLowLevelContext() override    { return new LowLevelGraphicsSoftwareRenderer (Image (this)); }
 | 
			
		||||
 | 
			
		||||
        void initialiseBitmapData (Image::BitmapData& bitmap, int x, int y, Image::BitmapData::ReadWriteMode mode) override
 | 
			
		||||
        {
 | 
			
		||||
            ignoreUnused (mode);
 | 
			
		||||
 | 
			
		||||
            bitmap.data = imageData + x * pixelStride + y * lineStride;
 | 
			
		||||
            bitmap.pixelFormat = pixelFormat;
 | 
			
		||||
            bitmap.lineStride = lineStride;
 | 
			
		||||
            bitmap.pixelStride = pixelStride;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        ImagePixelData::Ptr clone() override
 | 
			
		||||
        {
 | 
			
		||||
            auto im = new UnityBitmapImage (imageData, width, height);
 | 
			
		||||
 | 
			
		||||
            for (int i = 0; i < height; ++i)
 | 
			
		||||
                memcpy (im->imageData + i * lineStride, imageData + i * lineStride, (size_t) lineStride);
 | 
			
		||||
 | 
			
		||||
            return im;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        uint8* imageData;
 | 
			
		||||
        int pixelStride = 4, lineStride;
 | 
			
		||||
 | 
			
		||||
        JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (UnityBitmapImage)
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    //==============================================================================
 | 
			
		||||
    struct MouseWatcher    : public Timer
 | 
			
		||||
    {
 | 
			
		||||
        MouseWatcher (ComponentPeer& o)    : owner (o)    {}
 | 
			
		||||
 | 
			
		||||
        void timerCallback() override
 | 
			
		||||
        {
 | 
			
		||||
            auto pos = Desktop::getMousePosition();
 | 
			
		||||
 | 
			
		||||
            if (boundsToWatch.contains (pos) && pos != lastMousePos)
 | 
			
		||||
            {
 | 
			
		||||
                auto ms = Desktop::getInstance().getMainMouseSource();
 | 
			
		||||
 | 
			
		||||
                if (! ms.getCurrentModifiers().isLeftButtonDown())
 | 
			
		||||
                    owner.handleMouseEvent (juce::MouseInputSource::mouse, owner.globalToLocal (pos.toFloat()), {},
 | 
			
		||||
                                            juce::MouseInputSource::invalidPressure, juce::MouseInputSource::invalidOrientation, juce::Time::currentTimeMillis());
 | 
			
		||||
 | 
			
		||||
                lastMousePos = pos;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        void setBoundsToWatch (Rectangle<int> b)
 | 
			
		||||
        {
 | 
			
		||||
            if (boundsToWatch != b)
 | 
			
		||||
                boundsToWatch = b;
 | 
			
		||||
 | 
			
		||||
            startTimer (250);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        ComponentPeer& owner;
 | 
			
		||||
        Rectangle<int> boundsToWatch;
 | 
			
		||||
        Point<int> lastMousePos;
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    //==============================================================================
 | 
			
		||||
    KeyPress getKeyPress (int keyCode, String name)
 | 
			
		||||
    {
 | 
			
		||||
        if (keyCode >= 32 && keyCode <= 64)
 | 
			
		||||
            return { keyCode, ModifierKeys::currentModifiers, juce::juce_wchar (keyCode) };
 | 
			
		||||
 | 
			
		||||
        if (keyCode >= 91 && keyCode <= 122)
 | 
			
		||||
            return { keyCode, ModifierKeys::currentModifiers, name[0] };
 | 
			
		||||
 | 
			
		||||
        if (keyCode >= 256 && keyCode <= 265)
 | 
			
		||||
            return { juce::KeyPress::numberPad0 + (keyCode - 256), ModifierKeys::currentModifiers, juce::String (keyCode - 256).getCharPointer()[0] };
 | 
			
		||||
 | 
			
		||||
        if (keyCode == 8)      return { juce::KeyPress::backspaceKey,          ModifierKeys::currentModifiers, {} };
 | 
			
		||||
        if (keyCode == 127)    return { juce::KeyPress::deleteKey,             ModifierKeys::currentModifiers, {} };
 | 
			
		||||
        if (keyCode == 9)      return { juce::KeyPress::tabKey,                ModifierKeys::currentModifiers, {} };
 | 
			
		||||
        if (keyCode == 13)     return { juce::KeyPress::returnKey,             ModifierKeys::currentModifiers, {} };
 | 
			
		||||
        if (keyCode == 27)     return { juce::KeyPress::escapeKey,             ModifierKeys::currentModifiers, {} };
 | 
			
		||||
        if (keyCode == 32)     return { juce::KeyPress::spaceKey,              ModifierKeys::currentModifiers, {} };
 | 
			
		||||
        if (keyCode == 266)    return { juce::KeyPress::numberPadDecimalPoint, ModifierKeys::currentModifiers, {} };
 | 
			
		||||
        if (keyCode == 267)    return { juce::KeyPress::numberPadDivide,       ModifierKeys::currentModifiers, {} };
 | 
			
		||||
        if (keyCode == 268)    return { juce::KeyPress::numberPadMultiply,     ModifierKeys::currentModifiers, {} };
 | 
			
		||||
        if (keyCode == 269)    return { juce::KeyPress::numberPadSubtract,     ModifierKeys::currentModifiers, {} };
 | 
			
		||||
        if (keyCode == 270)    return { juce::KeyPress::numberPadAdd,          ModifierKeys::currentModifiers, {} };
 | 
			
		||||
        if (keyCode == 272)    return { juce::KeyPress::numberPadEquals,       ModifierKeys::currentModifiers, {} };
 | 
			
		||||
        if (keyCode == 273)    return { juce::KeyPress::upKey,                 ModifierKeys::currentModifiers, {} };
 | 
			
		||||
        if (keyCode == 274)    return { juce::KeyPress::downKey,               ModifierKeys::currentModifiers, {} };
 | 
			
		||||
        if (keyCode == 275)    return { juce::KeyPress::rightKey,              ModifierKeys::currentModifiers, {} };
 | 
			
		||||
        if (keyCode == 276)    return { juce::KeyPress::leftKey,               ModifierKeys::currentModifiers, {} };
 | 
			
		||||
 | 
			
		||||
        return {};
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    //==============================================================================
 | 
			
		||||
    Rectangle<int> bounds;
 | 
			
		||||
    MouseWatcher mouseWatcher;
 | 
			
		||||
 | 
			
		||||
    uint8* pixelData = nullptr;
 | 
			
		||||
    int textureWidth, textureHeight;
 | 
			
		||||
    Image renderImage;
 | 
			
		||||
 | 
			
		||||
    //==============================================================================
 | 
			
		||||
    void setMinimised (bool) override                                 {}
 | 
			
		||||
    bool isMinimised() const override                                 { return false; }
 | 
			
		||||
    void setFullScreen (bool) override                                {}
 | 
			
		||||
    bool isFullScreen() const override                                { return false; }
 | 
			
		||||
    bool setAlwaysOnTop (bool) override                               { return false; }
 | 
			
		||||
    void toFront (bool) override                                      {}
 | 
			
		||||
    void toBehind (ComponentPeer*) override                           {}
 | 
			
		||||
    bool isFocused() const override                                   { return true; }
 | 
			
		||||
    void grabFocus() override                                         {}
 | 
			
		||||
    void* getNativeHandle() const override                            { return nullptr; }
 | 
			
		||||
    BorderSize<int> getFrameSize() const override                     { return {}; }
 | 
			
		||||
    void setVisible (bool) override                                   {}
 | 
			
		||||
    void setTitle (const String&) override                            {}
 | 
			
		||||
    void setIcon (const Image&) override                              {}
 | 
			
		||||
    void textInputRequired (Point<int>, TextInputTarget&) override    {}
 | 
			
		||||
    void setAlpha (float) override                                    {}
 | 
			
		||||
    void performAnyPendingRepaintsNow() override                      {}
 | 
			
		||||
    void repaint (const Rectangle<int>&) override                     {}
 | 
			
		||||
 | 
			
		||||
    //==============================================================================
 | 
			
		||||
    JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (UnityPeer)
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
ComponentPeer* createUnityPeer (Component& c)    { return new UnityPeer (c); }
 | 
			
		||||
 | 
			
		||||
//==============================================================================
 | 
			
		||||
class AudioProcessorUnityWrapper
 | 
			
		||||
{
 | 
			
		||||
public:
 | 
			
		||||
    AudioProcessorUnityWrapper (bool isTemporary)
 | 
			
		||||
    {
 | 
			
		||||
        pluginInstance.reset (createPluginFilterOfType (AudioProcessor::wrapperType_Unity));
 | 
			
		||||
 | 
			
		||||
        if (! isTemporary && pluginInstance->hasEditor())
 | 
			
		||||
        {
 | 
			
		||||
            pluginInstanceEditor.reset (pluginInstance->createEditorIfNeeded());
 | 
			
		||||
            pluginInstanceEditor->setVisible (true);
 | 
			
		||||
            pluginInstanceEditor->addToDesktop (0);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        juceParameters.update (*pluginInstance, false);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    ~AudioProcessorUnityWrapper()
 | 
			
		||||
    {
 | 
			
		||||
        if (pluginInstanceEditor != nullptr)
 | 
			
		||||
        {
 | 
			
		||||
            pluginInstanceEditor->removeFromDesktop();
 | 
			
		||||
 | 
			
		||||
            PopupMenu::dismissAllActiveMenus();
 | 
			
		||||
            pluginInstanceEditor->processor.editorBeingDeleted (pluginInstanceEditor.get());
 | 
			
		||||
            pluginInstanceEditor = nullptr;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void create (UnityAudioEffectState* state)
 | 
			
		||||
    {
 | 
			
		||||
        // only supported in Unity plugin API > 1.0
 | 
			
		||||
        if (state->structSize >= sizeof (UnityAudioEffectState))
 | 
			
		||||
            samplesPerBlock = static_cast<int> (state->dspBufferSize);
 | 
			
		||||
 | 
			
		||||
       #ifdef JucePlugin_PreferredChannelConfigurations
 | 
			
		||||
        short configs[][2] = { JucePlugin_PreferredChannelConfigurations };
 | 
			
		||||
        const int numConfigs = sizeof (configs) / sizeof (short[2]);
 | 
			
		||||
 | 
			
		||||
        jassert (numConfigs > 0 && (configs[0][0] > 0 || configs[0][1] > 0));
 | 
			
		||||
 | 
			
		||||
        pluginInstance->setPlayConfigDetails (configs[0][0], configs[0][1], state->sampleRate, samplesPerBlock);
 | 
			
		||||
       #else
 | 
			
		||||
        pluginInstance->setRateAndBufferSizeDetails (state->sampleRate, samplesPerBlock);
 | 
			
		||||
       #endif
 | 
			
		||||
 | 
			
		||||
        pluginInstance->prepareToPlay (state->sampleRate, samplesPerBlock);
 | 
			
		||||
 | 
			
		||||
        scratchBuffer.setSize (jmax (pluginInstance->getTotalNumInputChannels(), pluginInstance->getTotalNumOutputChannels()), samplesPerBlock);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void release()
 | 
			
		||||
    {
 | 
			
		||||
        pluginInstance->releaseResources();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void reset()
 | 
			
		||||
    {
 | 
			
		||||
        pluginInstance->reset();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void process (float* inBuffer, float* outBuffer, int bufferSize, int numInChannels, int numOutChannels, bool isBypassed)
 | 
			
		||||
    {
 | 
			
		||||
        for (int pos = 0; pos < bufferSize;)
 | 
			
		||||
        {
 | 
			
		||||
            auto max = jmin (bufferSize - pos, samplesPerBlock);
 | 
			
		||||
            processBuffers (inBuffer + (pos * numInChannels), outBuffer + (pos * numOutChannels), max, numInChannels, numOutChannels, isBypassed);
 | 
			
		||||
 | 
			
		||||
            pos += max;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void declareParameters (UnityAudioEffectDefinition& definition)
 | 
			
		||||
    {
 | 
			
		||||
        static std::unique_ptr<UnityAudioParameterDefinition> parametersPtr;
 | 
			
		||||
        static int numParams = 0;
 | 
			
		||||
 | 
			
		||||
        if (parametersPtr == nullptr)
 | 
			
		||||
        {
 | 
			
		||||
            numParams = juceParameters.params.size();
 | 
			
		||||
 | 
			
		||||
            parametersPtr.reset (static_cast<UnityAudioParameterDefinition*> (std::calloc (static_cast<size_t> (numParams),
 | 
			
		||||
                                                                              sizeof (UnityAudioParameterDefinition))));
 | 
			
		||||
 | 
			
		||||
            parameterDescriptions.clear();
 | 
			
		||||
 | 
			
		||||
            for (int i = 0; i < numParams; ++i)
 | 
			
		||||
            {
 | 
			
		||||
                auto* parameter = juceParameters.params[i];
 | 
			
		||||
                auto& paramDef = parametersPtr.get()[i];
 | 
			
		||||
 | 
			
		||||
                strncpy (paramDef.name, parameter->getName (15).toRawUTF8(), 15);
 | 
			
		||||
 | 
			
		||||
                if (parameter->getLabel().isNotEmpty())
 | 
			
		||||
                    strncpy (paramDef.unit, parameter->getLabel().toRawUTF8(), 15);
 | 
			
		||||
 | 
			
		||||
                parameterDescriptions.add (parameter->getName (15));
 | 
			
		||||
                paramDef.description = parameterDescriptions[i].toRawUTF8();
 | 
			
		||||
 | 
			
		||||
                paramDef.defaultVal = parameter->getDefaultValue();
 | 
			
		||||
                paramDef.min = 0.0f;
 | 
			
		||||
                paramDef.max = 1.0f;
 | 
			
		||||
                paramDef.displayScale = 1.0f;
 | 
			
		||||
                paramDef.displayExponent = 1.0f;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        definition.numParameters = static_cast<uint32> (numParams);
 | 
			
		||||
        definition.parameterDefintions = parametersPtr.get();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void setParameter (int index, float value)       { juceParameters.getParamForIndex (index)->setValueNotifyingHost (value); }
 | 
			
		||||
    float getParameter (int index) const noexcept    { return juceParameters.getParamForIndex (index)->getValue(); }
 | 
			
		||||
 | 
			
		||||
    String getParameterString (int index) const noexcept
 | 
			
		||||
    {
 | 
			
		||||
        auto* param = juceParameters.getParamForIndex (index);
 | 
			
		||||
        return param->getText (param->getValue(), 16);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    int getNumInputChannels() const noexcept         { return pluginInstance->getTotalNumInputChannels(); }
 | 
			
		||||
    int getNumOutputChannels() const noexcept        { return pluginInstance->getTotalNumOutputChannels(); }
 | 
			
		||||
 | 
			
		||||
    bool hasEditor() const noexcept                  { return pluginInstance->hasEditor(); }
 | 
			
		||||
 | 
			
		||||
    UnityPeer& getEditorPeer() const
 | 
			
		||||
    {
 | 
			
		||||
        auto* peer = dynamic_cast<UnityPeer*> (pluginInstanceEditor->getPeer());
 | 
			
		||||
 | 
			
		||||
        jassert (peer != nullptr);
 | 
			
		||||
        return *peer;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
private:
 | 
			
		||||
    //==============================================================================
 | 
			
		||||
    void processBuffers (float* inBuffer, float* outBuffer, int bufferSize, int numInChannels, int numOutChannels, bool isBypassed)
 | 
			
		||||
    {
 | 
			
		||||
        int ch;
 | 
			
		||||
        for (ch = 0; ch < numInChannels; ++ch)
 | 
			
		||||
        {
 | 
			
		||||
            using DstSampleType = AudioData::Pointer<AudioData::Float32, AudioData::NativeEndian, AudioData::NonInterleaved, AudioData::NonConst>;
 | 
			
		||||
            using SrcSampleType = AudioData::Pointer<AudioData::Float32, AudioData::NativeEndian, AudioData::Interleaved,    AudioData::Const>;
 | 
			
		||||
 | 
			
		||||
            DstSampleType dstData (scratchBuffer.getWritePointer (ch));
 | 
			
		||||
            SrcSampleType srcData (inBuffer + ch, numInChannels);
 | 
			
		||||
            dstData.convertSamples (srcData, bufferSize);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        for (; ch < numOutChannels; ++ch)
 | 
			
		||||
            scratchBuffer.clear (ch, 0, bufferSize);
 | 
			
		||||
 | 
			
		||||
        {
 | 
			
		||||
            const ScopedLock sl (pluginInstance->getCallbackLock());
 | 
			
		||||
 | 
			
		||||
            if (pluginInstance->isSuspended())
 | 
			
		||||
            {
 | 
			
		||||
                scratchBuffer.clear();
 | 
			
		||||
            }
 | 
			
		||||
            else
 | 
			
		||||
            {
 | 
			
		||||
                MidiBuffer mb;
 | 
			
		||||
 | 
			
		||||
                if (isBypassed)
 | 
			
		||||
                    pluginInstance->processBlockBypassed (scratchBuffer, mb);
 | 
			
		||||
                else
 | 
			
		||||
                    pluginInstance->processBlock (scratchBuffer, mb);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        for (ch = 0; ch < numOutChannels; ++ch)
 | 
			
		||||
        {
 | 
			
		||||
            using DstSampleType = AudioData::Pointer<AudioData::Float32, AudioData::NativeEndian, AudioData::Interleaved,    AudioData::NonConst>;
 | 
			
		||||
            using SrcSampleType = AudioData::Pointer<AudioData::Float32, AudioData::NativeEndian, AudioData::NonInterleaved, AudioData::Const>;
 | 
			
		||||
 | 
			
		||||
            DstSampleType dstData (outBuffer + ch, numOutChannels);
 | 
			
		||||
            SrcSampleType srcData (scratchBuffer.getReadPointer (ch));
 | 
			
		||||
            dstData.convertSamples (srcData, bufferSize);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    //==============================================================================
 | 
			
		||||
    std::unique_ptr<AudioProcessor> pluginInstance;
 | 
			
		||||
    std::unique_ptr<AudioProcessorEditor> pluginInstanceEditor;
 | 
			
		||||
 | 
			
		||||
    int samplesPerBlock = 1024;
 | 
			
		||||
    StringArray parameterDescriptions;
 | 
			
		||||
 | 
			
		||||
    AudioBuffer<float> scratchBuffer;
 | 
			
		||||
 | 
			
		||||
    LegacyAudioParametersWrapper juceParameters;
 | 
			
		||||
 | 
			
		||||
    //==============================================================================
 | 
			
		||||
    JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (AudioProcessorUnityWrapper)
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
//==============================================================================
 | 
			
		||||
HashMap<int, AudioProcessorUnityWrapper*>& getWrapperMap()
 | 
			
		||||
{
 | 
			
		||||
    static HashMap<int, AudioProcessorUnityWrapper*> wrapperMap;
 | 
			
		||||
    return wrapperMap;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void onWrapperCreation (AudioProcessorUnityWrapper* wrapperToAdd)
 | 
			
		||||
{
 | 
			
		||||
    getWrapperMap().set (std::abs (Random::getSystemRandom().nextInt (65536)), wrapperToAdd);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void onWrapperDeletion (AudioProcessorUnityWrapper* wrapperToRemove)
 | 
			
		||||
{
 | 
			
		||||
    getWrapperMap().removeValue (wrapperToRemove);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
//==============================================================================
 | 
			
		||||
namespace UnityCallbacks
 | 
			
		||||
{
 | 
			
		||||
    int UNITY_INTERFACE_API createCallback (UnityAudioEffectState* state)
 | 
			
		||||
    {
 | 
			
		||||
        auto* pluginInstance = new AudioProcessorUnityWrapper (false);
 | 
			
		||||
        pluginInstance->create (state);
 | 
			
		||||
 | 
			
		||||
        state->effectData = pluginInstance;
 | 
			
		||||
 | 
			
		||||
        onWrapperCreation (pluginInstance);
 | 
			
		||||
 | 
			
		||||
        return 0;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    int UNITY_INTERFACE_API releaseCallback (UnityAudioEffectState* state)
 | 
			
		||||
    {
 | 
			
		||||
        auto* pluginInstance = state->getEffectData<AudioProcessorUnityWrapper>();
 | 
			
		||||
        pluginInstance->release();
 | 
			
		||||
 | 
			
		||||
        onWrapperDeletion (pluginInstance);
 | 
			
		||||
        delete pluginInstance;
 | 
			
		||||
 | 
			
		||||
        if (getWrapperMap().size() == 0)
 | 
			
		||||
            shutdownJuce_GUI();
 | 
			
		||||
 | 
			
		||||
        return 0;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    int UNITY_INTERFACE_API resetCallback (UnityAudioEffectState* state)
 | 
			
		||||
    {
 | 
			
		||||
        auto* pluginInstance = state->getEffectData<AudioProcessorUnityWrapper>();
 | 
			
		||||
        pluginInstance->reset();
 | 
			
		||||
 | 
			
		||||
        return 0;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    int UNITY_INTERFACE_API setPositionCallback (UnityAudioEffectState* state, unsigned int pos)
 | 
			
		||||
    {
 | 
			
		||||
        ignoreUnused (state, pos);
 | 
			
		||||
 | 
			
		||||
        return 0;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    int UNITY_INTERFACE_API setFloatParameterCallback (UnityAudioEffectState* state, int index, float value)
 | 
			
		||||
    {
 | 
			
		||||
        auto* pluginInstance = state->getEffectData<AudioProcessorUnityWrapper>();
 | 
			
		||||
        pluginInstance->setParameter (index, value);
 | 
			
		||||
 | 
			
		||||
        return 0;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    int UNITY_INTERFACE_API getFloatParameterCallback (UnityAudioEffectState* state, int index, float* value, char* valueStr)
 | 
			
		||||
    {
 | 
			
		||||
        auto* pluginInstance = state->getEffectData<AudioProcessorUnityWrapper>();
 | 
			
		||||
        *value = pluginInstance->getParameter (index);
 | 
			
		||||
 | 
			
		||||
        strncpy (valueStr, pluginInstance->getParameterString (index).toRawUTF8(), 15);
 | 
			
		||||
 | 
			
		||||
        return 0;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    int UNITY_INTERFACE_API getFloatBufferCallback (UnityAudioEffectState* state, const char* name, float* buffer, int numSamples)
 | 
			
		||||
    {
 | 
			
		||||
        ignoreUnused (numSamples);
 | 
			
		||||
 | 
			
		||||
        auto nameStr = String (name);
 | 
			
		||||
 | 
			
		||||
        if (nameStr == "Editor")
 | 
			
		||||
        {
 | 
			
		||||
            auto* pluginInstance = state->getEffectData<AudioProcessorUnityWrapper>();
 | 
			
		||||
 | 
			
		||||
            buffer[0] = pluginInstance->hasEditor() ? 1.0f : 0.0f;
 | 
			
		||||
        }
 | 
			
		||||
        else if (nameStr == "ID")
 | 
			
		||||
        {
 | 
			
		||||
            auto* pluginInstance = state->getEffectData<AudioProcessorUnityWrapper>();
 | 
			
		||||
 | 
			
		||||
            for (HashMap<int, AudioProcessorUnityWrapper*>::Iterator i (getWrapperMap()); i.next();)
 | 
			
		||||
            {
 | 
			
		||||
                if (i.getValue() == pluginInstance)
 | 
			
		||||
                {
 | 
			
		||||
                    buffer[0] = (float) i.getKey();
 | 
			
		||||
                    break;
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            return 0;
 | 
			
		||||
        }
 | 
			
		||||
        else if (nameStr == "Size")
 | 
			
		||||
        {
 | 
			
		||||
            auto* pluginInstance = state->getEffectData<AudioProcessorUnityWrapper>();
 | 
			
		||||
 | 
			
		||||
            auto& editor = pluginInstance->getEditorPeer().getEditor();
 | 
			
		||||
 | 
			
		||||
            buffer[0] = (float) editor.getBounds().getWidth();
 | 
			
		||||
            buffer[1] = (float) editor.getBounds().getHeight();
 | 
			
		||||
            buffer[2] = (float) editor.getConstrainer()->getMinimumWidth();
 | 
			
		||||
            buffer[3] = (float) editor.getConstrainer()->getMinimumHeight();
 | 
			
		||||
            buffer[4] = (float) editor.getConstrainer()->getMaximumWidth();
 | 
			
		||||
            buffer[5] = (float) editor.getConstrainer()->getMaximumHeight();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return 0;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    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);
 | 
			
		||||
 | 
			
		||||
            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;
 | 
			
		||||
 | 
			
		||||
    strcpy (definition.name, name.toRawUTF8());
 | 
			
		||||
 | 
			
		||||
    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;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
} // namespace juce
 | 
			
		||||
 | 
			
		||||
UNITY_INTERFACE_EXPORT int UNITY_INTERFACE_API UnityGetAudioEffectDefinitions (UnityAudioEffectDefinition*** definitionsPtr)
 | 
			
		||||
{
 | 
			
		||||
    if (juce::getWrapperMap().size() == 0)
 | 
			
		||||
        juce::initialiseJuce_GUI();
 | 
			
		||||
 | 
			
		||||
    static bool hasInitialised = false;
 | 
			
		||||
 | 
			
		||||
    if (! hasInitialised)
 | 
			
		||||
    {
 | 
			
		||||
        juce::PluginHostType::jucePlugInClientCurrentWrapperType = juce::AudioProcessor::wrapperType_Unity;
 | 
			
		||||
        juce::juce_createUnityPeerFn = juce::createUnityPeer;
 | 
			
		||||
 | 
			
		||||
        hasInitialised = true;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    auto* definition = new UnityAudioEffectDefinition();
 | 
			
		||||
    juce::declareEffect (*definition);
 | 
			
		||||
 | 
			
		||||
    *definitionsPtr = &definition;
 | 
			
		||||
 | 
			
		||||
    return 1;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
//==============================================================================
 | 
			
		||||
static juce::ModifierKeys unityModifiersToJUCE (UnityEventModifiers mods, bool mouseDown, int mouseButton = -1)
 | 
			
		||||
{
 | 
			
		||||
    int flags = 0;
 | 
			
		||||
 | 
			
		||||
    if (mouseDown)
 | 
			
		||||
    {
 | 
			
		||||
        if (mouseButton == 0)
 | 
			
		||||
            flags |= juce::ModifierKeys::leftButtonModifier;
 | 
			
		||||
        else if (mouseButton == 1)
 | 
			
		||||
            flags |= juce::ModifierKeys::rightButtonModifier;
 | 
			
		||||
        else if (mouseButton == 2)
 | 
			
		||||
            flags |= juce::ModifierKeys::middleButtonModifier;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (mods == 0)
 | 
			
		||||
        return flags;
 | 
			
		||||
 | 
			
		||||
    if ((mods & UnityEventModifiers::shift) != 0)        flags |= juce::ModifierKeys::shiftModifier;
 | 
			
		||||
    if ((mods & UnityEventModifiers::control) != 0)      flags |= juce::ModifierKeys::ctrlModifier;
 | 
			
		||||
    if ((mods & UnityEventModifiers::alt) != 0)          flags |= juce::ModifierKeys::altModifier;
 | 
			
		||||
    if ((mods & UnityEventModifiers::command) != 0)      flags |= juce::ModifierKeys::commandModifier;
 | 
			
		||||
 | 
			
		||||
    return { flags };
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
//==============================================================================
 | 
			
		||||
static juce::AudioProcessorUnityWrapper* getWrapperChecked (int id)
 | 
			
		||||
{
 | 
			
		||||
    auto* wrapper = juce::getWrapperMap()[id];
 | 
			
		||||
    jassert (wrapper != nullptr);
 | 
			
		||||
 | 
			
		||||
    return wrapper;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
//==============================================================================
 | 
			
		||||
static void UNITY_INTERFACE_API onRenderEvent (int id)
 | 
			
		||||
{
 | 
			
		||||
    getWrapperChecked (id)->getEditorPeer().triggerAsyncUpdate();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
UNITY_INTERFACE_EXPORT renderCallback UNITY_INTERFACE_API getRenderCallback()
 | 
			
		||||
{
 | 
			
		||||
    return onRenderEvent;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
UNITY_INTERFACE_EXPORT void UNITY_INTERFACE_API unityInitialiseTexture (int id, void* data, int w, int h)
 | 
			
		||||
{
 | 
			
		||||
    getWrapperChecked (id)->getEditorPeer().setPixelDataHandle (reinterpret_cast<juce::uint8*> (data), w, h);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
UNITY_INTERFACE_EXPORT void UNITY_INTERFACE_API unityMouseDown (int id, float x, float y, UnityEventModifiers unityMods, int button)
 | 
			
		||||
{
 | 
			
		||||
    getWrapperChecked (id)->getEditorPeer().forwardMouseEvent ({ x, y }, unityModifiersToJUCE (unityMods, true, button));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
UNITY_INTERFACE_EXPORT void UNITY_INTERFACE_API unityMouseDrag (int id, float x, float y, UnityEventModifiers unityMods, int button)
 | 
			
		||||
{
 | 
			
		||||
    getWrapperChecked (id)->getEditorPeer().forwardMouseEvent ({ x, y }, unityModifiersToJUCE (unityMods, true, button));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
UNITY_INTERFACE_EXPORT void UNITY_INTERFACE_API unityMouseUp (int id, float x, float y, UnityEventModifiers unityMods)
 | 
			
		||||
{
 | 
			
		||||
    getWrapperChecked (id)->getEditorPeer().forwardMouseEvent ({ x, y }, unityModifiersToJUCE (unityMods, false));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
UNITY_INTERFACE_EXPORT void UNITY_INTERFACE_API unityKeyEvent (int id, int code, UnityEventModifiers mods, const char* name)
 | 
			
		||||
{
 | 
			
		||||
    getWrapperChecked (id)->getEditorPeer().forwardKeyPress (code, name, unityModifiersToJUCE (mods, false));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
UNITY_INTERFACE_EXPORT void UNITY_INTERFACE_API unitySetScreenBounds (int id, float x, float y, float w, float h)
 | 
			
		||||
{
 | 
			
		||||
    getWrapperChecked (id)->getEditorPeer().getEditor().setBounds ({ (int) x, (int) y, (int) w, (int) h });
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
//==============================================================================
 | 
			
		||||
#if JUCE_WINDOWS
 | 
			
		||||
 extern "C" BOOL WINAPI DllMain (HINSTANCE instance, DWORD reason, LPVOID)
 | 
			
		||||
 {
 | 
			
		||||
     if (reason == DLL_PROCESS_ATTACH)
 | 
			
		||||
         juce::Process::setCurrentModuleInstanceHandle (instance);
 | 
			
		||||
 | 
			
		||||
     return true;
 | 
			
		||||
 }
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
		Reference in New Issue
	
	Block a user