diff DPF-Prymula-audioplugins/dpf/distrho/src/DistrhoPluginVST.hpp @ 3:84e66ea83026

DPF-Prymula-audioplugins-0.231015-2
author prymula <prymula76@outlook.com>
date Mon, 16 Oct 2023 21:53:34 +0200
parents
children
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/DPF-Prymula-audioplugins/dpf/distrho/src/DistrhoPluginVST.hpp	Mon Oct 16 21:53:34 2023 +0200
@@ -0,0 +1,386 @@
+/*
+ * DISTRHO Plugin Framework (DPF)
+ * Copyright (C) 2012-2022 Filipe Coelho <falktx@falktx.com>
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any purpose with
+ * or without fee is hereby granted, provided that the above copyright notice and this
+ * permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD
+ * TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN
+ * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
+ * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#ifndef DISTRHO_PLUGIN_VST_HPP_INCLUDED
+#define DISTRHO_PLUGIN_VST_HPP_INCLUDED
+
+#include "DistrhoPluginChecks.h"
+#include "../DistrhoUtils.hpp"
+
+#include <algorithm>
+#include <cmath>
+
+#if DISTRHO_PLUGIN_HAS_UI && ! DISTRHO_PLUGIN_HAS_EMBED_UI
+# undef DISTRHO_PLUGIN_HAS_UI
+# define DISTRHO_PLUGIN_HAS_UI 0
+#endif
+
+#if DISTRHO_PLUGIN_HAS_UI && ! defined(HAVE_DGL) && ! DISTRHO_PLUGIN_HAS_EXTERNAL_UI
+# undef DISTRHO_PLUGIN_HAS_UI
+# define DISTRHO_PLUGIN_HAS_UI 0
+#endif
+
+#if DISTRHO_PLUGIN_HAS_UI && ! DISTRHO_PLUGIN_HAS_EXTERNAL_UI
+# include "Base.hpp"
+#endif
+
+#if DISTRHO_PLUGIN_HAS_UI == 1 && DISTRHO_PLUGIN_WANT_DIRECT_ACCESS == 0
+# define DPF_VST3_USES_SEPARATE_CONTROLLER 1
+#else
+# define DPF_VST3_USES_SEPARATE_CONTROLLER 0
+#endif
+
+// --------------------------------------------------------------------------------------------------------------------
+
+#ifdef DISTRHO_PROPER_CPP11_SUPPORT
+# include <atomic>
+#else
+// quick and dirty std::atomic replacement for the things we need
+namespace std {
+    struct atomic_int {
+        volatile int value;
+        explicit atomic_int(volatile int v) noexcept : value(v) {}
+        int operator++() volatile noexcept { return __atomic_add_fetch(&value, 1, __ATOMIC_RELAXED); }
+        int operator--() volatile noexcept { return __atomic_sub_fetch(&value, 1, __ATOMIC_RELAXED); }
+        operator int() volatile noexcept { return __atomic_load_n(&value, __ATOMIC_RELAXED); }
+    };
+};
+#endif
+
+// --------------------------------------------------------------------------------------------------------------------
+
+START_NAMESPACE_DISTRHO
+
+// --------------------------------------------------------------------------------------------------------------------
+
+enum Vst3InternalParameters {
+   #if DPF_VST3_USES_SEPARATE_CONTROLLER
+    kVst3InternalParameterBufferSize,
+    kVst3InternalParameterSampleRate,
+   #endif
+   #if DISTRHO_PLUGIN_WANT_LATENCY
+    kVst3InternalParameterLatency,
+   #endif
+   #if DISTRHO_PLUGIN_WANT_PROGRAMS
+    kVst3InternalParameterProgram,
+   #endif
+    kVst3InternalParameterBaseCount,
+   #if DISTRHO_PLUGIN_WANT_MIDI_INPUT
+    kVst3InternalParameterMidiCC_start = kVst3InternalParameterBaseCount,
+    kVst3InternalParameterMidiCC_end = kVst3InternalParameterMidiCC_start + 130*16,
+    kVst3InternalParameterCount = kVst3InternalParameterMidiCC_end
+   #else
+    kVst3InternalParameterCount = kVst3InternalParameterBaseCount
+   #endif
+};
+
+#if DPF_VST3_USES_SEPARATE_CONTROLLER || DISTRHO_PLUGIN_WANT_LATENCY || DISTRHO_PLUGIN_WANT_PROGRAMS || DISTRHO_PLUGIN_WANT_MIDI_INPUT
+# define DPF_VST3_HAS_INTERNAL_PARAMETERS 1
+#else
+# define DPF_VST3_HAS_INTERNAL_PARAMETERS 0
+#endif
+
+#if DPF_VST3_HAS_INTERNAL_PARAMETERS && DISTRHO_PLUGIN_WANT_MIDI_INPUT && \
+    !(DPF_VST3_USES_SEPARATE_CONTROLLER || DISTRHO_PLUGIN_WANT_LATENCY || DISTRHO_PLUGIN_WANT_PROGRAMS)
+# define DPF_VST3_PURE_MIDI_INTERNAL_PARAMETERS 1
+#else
+# define DPF_VST3_PURE_MIDI_INTERNAL_PARAMETERS 0
+#endif
+
+// --------------------------------------------------------------------------------------------------------------------
+
+static inline
+bool strcmp_utf16(const int16_t* const str16, const char* const str8)
+{
+    size_t i = 0;
+    for (; str8[i] != '\0'; ++i)
+    {
+        const uint8_t char8 = static_cast<uint8_t>(str8[i]);
+
+        // skip non-ascii chars, unsupported
+        if (char8 >= 0x80)
+            return false;
+
+        if (str16[i] != char8)
+            return false;
+    }
+
+    return str16[i] == str8[i];
+}
+
+// --------------------------------------------------------------------------------------------------------------------
+
+static inline
+size_t strlen_utf16(const int16_t* const str)
+{
+    size_t i = 0;
+
+    while (str[i] != 0)
+        ++i;
+
+    return i;
+}
+
+// --------------------------------------------------------------------------------------------------------------------
+
+static inline
+void strncpy_utf8(char* const dst, const int16_t* const src, const size_t length)
+{
+    DISTRHO_SAFE_ASSERT_RETURN(length > 0,);
+
+    if (const size_t len = std::min(strlen_utf16(src), length-1U))
+    {
+        for (size_t i=0; i<len; ++i)
+        {
+            // skip non-ascii chars, unsupported
+            if (src[i] >= 0x80)
+                continue;
+
+            dst[i] = src[i];
+        }
+        dst[len] = 0;
+    }
+    else
+    {
+        dst[0] = 0;
+    }
+}
+
+static inline
+void strncpy_utf16(int16_t* const dst, const char* const src, const size_t length)
+{
+    DISTRHO_SAFE_ASSERT_RETURN(length > 0,);
+
+    if (const size_t len = std::min(std::strlen(src), length-1U))
+    {
+        for (size_t i=0; i<len; ++i)
+        {
+            // skip non-ascii chars, unsupported
+            if ((uint8_t)src[i] >= 0x80)
+                continue;
+
+            dst[i] = src[i];
+        }
+        dst[len] = 0;
+    }
+    else
+    {
+        dst[0] = 0;
+    }
+}
+
+// --------------------------------------------------------------------------------------------------------------------
+
+template<typename T>
+static inline
+void snprintf_utf16_t(int16_t* const dst, const T value, const char* const format, const size_t size)
+{
+    DISTRHO_SAFE_ASSERT_RETURN(size > 0,);
+
+    char* const tmpbuf = (char*)std::malloc(size);
+    DISTRHO_SAFE_ASSERT_RETURN(tmpbuf != nullptr,);
+
+    std::snprintf(tmpbuf, size-1, format, value);
+    tmpbuf[size-1] = '\0';
+
+    strncpy_utf16(dst, tmpbuf, size);
+    std::free(tmpbuf);
+}
+
+static inline
+void snprintf_f32_utf16(int16_t* const dst, const float value, const size_t size)
+{
+    return snprintf_utf16_t<float>(dst, value, "%f", size);
+}
+
+static inline
+void snprintf_f32_utf16(int16_t* const dst, const double value, const size_t size)
+{
+    return snprintf_utf16_t<double>(dst, value, "%f", size);
+}
+
+static inline
+void snprintf_i32_utf16(int16_t* const dst, const int32_t value, const size_t size)
+{
+    return snprintf_utf16_t<int32_t>(dst, value, "%d", size);
+}
+
+static inline
+void snprintf_u32_utf16(int16_t* const dst, const uint32_t value, const size_t size)
+{
+    return snprintf_utf16_t<uint32_t>(dst, value, "%u", size);
+}
+
+#if DISTRHO_PLUGIN_HAS_UI && ! DISTRHO_PLUGIN_HAS_EXTERNAL_UI
+// --------------------------------------------------------------------------------------------------------------------
+// translate a vstgui-based key character and code to matching values used by DPF
+
+static inline
+uint translateVstKeyCode(bool& special, const int16_t keychar, const int16_t keycode) noexcept
+{
+    using namespace DGL_NAMESPACE;
+
+    // special stuff first
+    special = true;
+    switch (keycode)
+    {
+    case 1: return kKeyBackspace;
+    // 2 \t (handled below)
+    // 3 clear
+    // 4 \r (handled below)
+    case 6: return kKeyEscape;
+    //  7 space (handled below)
+    //  8 next
+    // 17 select
+    // 18 print
+    // 19 \n (handled below)
+    // 20 snapshot
+    case 22: return kKeyDelete; 
+    // 23 help
+    // 57 = (handled below)
+    // numpad stuff follows
+    // 24 0 (handled below)
+    // 25 1 (handled below)
+    // 26 2 (handled below)
+    // 27 3 (handled below)
+    // 28 4 (handled below)
+    // 29 5 (handled below)
+    // 30 6 (handled below)
+    // 31 7 (handled below)
+    // 32 8 (handled below)
+    // 33 9 (handled below)
+    // 34 * (handled below)
+    // 35 + (handled below)
+    // 36 separator
+    // 37 - (handled below)
+    // 38 . (handled below)
+    // 39 / (handled below)
+    // handle rest of special keys
+    /* these special keys are missing:
+        - kKeySuper
+        - kKeyCapsLock
+        - kKeyPrintScreen
+        */
+    case 40: return kKeyF1;
+    case 41: return kKeyF2;
+    case 42: return kKeyF3;
+    case 43: return kKeyF4;
+    case 44: return kKeyF5;
+    case 45: return kKeyF6;
+    case 46: return kKeyF7;
+    case 47: return kKeyF8;
+    case 48: return kKeyF9;
+    case 49: return kKeyF10;
+    case 50: return kKeyF11;
+    case 51: return kKeyF12;
+    case 11: return kKeyLeft;
+    case 12: return kKeyUp;
+    case 13: return kKeyRight;
+    case 14: return kKeyDown;
+    case 15: return kKeyPageUp;
+    case 16: return kKeyPageDown;
+    case 10: return kKeyHome;
+    case  9: return kKeyEnd;
+    case 21: return kKeyInsert;
+    case 54: return kKeyShift;
+    case 55: return kKeyControl;
+    case 56: return kKeyAlt;
+    case 58: return kKeyMenu;
+    case 52: return kKeyNumLock;
+    case 53: return kKeyScrollLock;
+    case  5: return kKeyPause;
+    }
+
+    // regular keys next
+    special = false;
+    switch (keycode)
+    {
+    case  2: return '\t';
+    case  4: return '\r';
+    case  7: return ' ';
+    case 19: return '\n';
+    case 57: return '=';
+    case 24: return '0';
+    case 25: return '1';
+    case 26: return '2';
+    case 27: return '3';
+    case 28: return '4';
+    case 29: return '5';
+    case 30: return '6';
+    case 31: return '7';
+    case 32: return '8';
+    case 33: return '9';
+    case 34: return '*';
+    case 35: return '+';
+    case 37: return '-';
+    case 38: return '.';
+    case 39: return '/';
+    }
+
+    // fallback
+    return keychar;
+}
+#endif
+
+// --------------------------------------------------------------------------------------------------------------------
+// handy way to create a utf16 string from a utf8 one on the current function scope, used for message strings
+
+struct ScopedUTF16String {
+    int16_t* str;
+    ScopedUTF16String(const char* const s) noexcept
+        : str(nullptr)
+    {
+        const size_t len = std::strlen(s);
+        str = static_cast<int16_t*>(std::malloc(sizeof(int16_t) * (len + 1)));
+        DISTRHO_SAFE_ASSERT_RETURN(str != nullptr,);
+        strncpy_utf16(str, s, len + 1);
+    }
+
+    ~ScopedUTF16String() noexcept
+    {
+        std::free(str);
+    }
+
+    operator const int16_t*() const noexcept
+    {
+        return str;
+    }
+};
+
+// --------------------------------------------------------------------------------------------------------------------
+// handy way to create a utf8 string from a utf16 one on the current function scope (limited to 128 chars)
+
+struct ScopedUTF8String {
+    char str[128];
+
+    ScopedUTF8String(const int16_t* const s) noexcept
+    {
+        strncpy_utf8(str, s, 128);
+    }
+
+    operator const char*() const noexcept
+    {
+        return str;
+    }
+};
+
+// --------------------------------------------------------------------------------------------------------------------
+
+END_NAMESPACE_DISTRHO
+
+// --------------------------------------------------------------------------------------------------------------------
+
+#endif // DISTRHO_PLUGIN_VST_HPP_INCLUDED