| Chris@4 | 1 /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*-  vi:set ts=8 sts=4 sw=4: */ | 
| Chris@5 | 2 /* | 
| Chris@35 | 3   Copyright (c) 2016-2018 Queen Mary, University of London | 
| Chris@5 | 4 | 
| Chris@20 | 5   Permission is hereby granted, free of charge, to any person | 
| Chris@20 | 6   obtaining a copy of this software and associated documentation | 
| Chris@20 | 7   files (the "Software"), to deal in the Software without | 
| Chris@20 | 8   restriction, including without limitation the rights to use, copy, | 
| Chris@20 | 9   modify, merge, publish, distribute, sublicense, and/or sell copies | 
| Chris@20 | 10   of the Software, and to permit persons to whom the Software is | 
| Chris@20 | 11   furnished to do so, subject to the following conditions: | 
| Chris@5 | 12 | 
| Chris@20 | 13   The above copyright notice and this permission notice shall be | 
| Chris@20 | 14   included in all copies or substantial portions of the Software. | 
| Chris@5 | 15 | 
| Chris@20 | 16   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, | 
| Chris@20 | 17   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF | 
| Chris@20 | 18   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND | 
| Chris@20 | 19   NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY | 
| Chris@20 | 20   CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF | 
| Chris@20 | 21   CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION | 
| Chris@20 | 22   WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | 
| Chris@5 | 23 | 
| Chris@20 | 24   Except as contained in this notice, the names of the Centre for | 
| Chris@20 | 25   Digital Music and Queen Mary, University of London shall not be | 
| Chris@20 | 26   used in advertising or otherwise to promote the sale, use or other | 
| Chris@20 | 27   dealings in this Software without prior written authorization. | 
| Chris@5 | 28 */ | 
| Chris@4 | 29 | 
| Chris@4 | 30 #include "knownplugins.h" | 
| Chris@4 | 31 | 
| Chris@4 | 32 using namespace std; | 
| Chris@4 | 33 | 
| Chris@4 | 34 #if defined(_WIN32) | 
| Chris@4 | 35 #define PATH_SEPARATOR ';' | 
| Chris@4 | 36 #else | 
| Chris@4 | 37 #define PATH_SEPARATOR ':' | 
| Chris@4 | 38 #endif | 
| Chris@4 | 39 | 
| Chris@35 | 40 KnownPlugins::KnownPlugins(BinaryFormat format) : | 
| Chris@35 | 41     m_format(format) | 
| Chris@4 | 42 { | 
| Chris@35 | 43     string variableSuffix = ""; | 
| Chris@35 | 44     if (m_format == FormatNonNative32Bit) { | 
| Chris@34 | 45         variableSuffix = "_32"; | 
| Chris@34 | 46     } | 
| Chris@6 | 47 | 
| Chris@34 | 48     m_known[VampPlugin] = { | 
| Chris@34 | 49         "vamp", | 
| Chris@34 | 50         "VAMP_PATH" + variableSuffix, | 
| Chris@35 | 51         {}, {}, | 
| Chris@34 | 52         "vampGetPluginDescriptor" | 
| Chris@34 | 53     }; | 
| Chris@34 | 54 | 
| Chris@34 | 55     m_known[LADSPAPlugin] = { | 
| Chris@34 | 56         "ladspa", | 
| Chris@34 | 57         "LADSPA_PATH" + variableSuffix, | 
| Chris@35 | 58         {}, {}, | 
| Chris@34 | 59         "ladspa_descriptor" | 
| Chris@34 | 60     }; | 
| Chris@34 | 61 | 
| Chris@34 | 62     m_known[DSSIPlugin] = { | 
| Chris@34 | 63         "dssi", | 
| Chris@34 | 64         "DSSI_PATH" + variableSuffix, | 
| Chris@35 | 65         {}, {}, | 
| Chris@34 | 66         "dssi_descriptor" | 
| Chris@4 | 67     }; | 
| Chris@4 | 68 | 
| Chris@35 | 69     for (auto &k: m_known) { | 
| Chris@35 | 70         k.second.defaultPath = expandPathString(getDefaultPathString(k.first)); | 
| Chris@35 | 71         k.second.path = expandConventionalPath(k.first, k.second.variable); | 
| Chris@4 | 72     } | 
| Chris@4 | 73 } | 
| Chris@4 | 74 | 
| Chris@35 | 75 vector<KnownPlugins::PluginType> | 
| Chris@34 | 76 KnownPlugins::getKnownPluginTypes() const | 
| Chris@34 | 77 { | 
| Chris@35 | 78     vector<PluginType> kt; | 
| Chris@34 | 79 | 
| Chris@34 | 80     for (const auto &k: m_known) { | 
| Chris@34 | 81         kt.push_back(k.first); | 
| Chris@34 | 82     } | 
| Chris@34 | 83 | 
| Chris@34 | 84     return kt; | 
| Chris@34 | 85 } | 
| Chris@34 | 86 | 
| Chris@4 | 87 string | 
| Chris@35 | 88 KnownPlugins::getUnexpandedDefaultPathString(PluginType type) | 
| Chris@4 | 89 { | 
| Chris@4 | 90     switch (type) { | 
| Chris@4 | 91 | 
| Chris@4 | 92 #if defined(_WIN32) | 
| Chris@4 | 93 | 
| Chris@4 | 94     case VampPlugin: | 
| Chris@19 | 95         return "%ProgramFiles%\\Vamp Plugins"; | 
| Chris@4 | 96     case LADSPAPlugin: | 
| Chris@19 | 97         return "%ProgramFiles%\\LADSPA Plugins;%ProgramFiles%\\Audacity\\Plug-Ins"; | 
| Chris@4 | 98     case DSSIPlugin: | 
| Chris@19 | 99         return "%ProgramFiles%\\DSSI Plugins"; | 
| Chris@19 | 100 | 
| Chris@4 | 101 #elif defined(__APPLE__) | 
| Chris@19 | 102 | 
| Chris@4 | 103     case VampPlugin: | 
| Chris@19 | 104         return "$HOME/Library/Audio/Plug-Ins/Vamp:/Library/Audio/Plug-Ins/Vamp"; | 
| Chris@4 | 105     case LADSPAPlugin: | 
| Chris@19 | 106         return "$HOME/Library/Audio/Plug-Ins/LADSPA:/Library/Audio/Plug-Ins/LADSPA"; | 
| Chris@4 | 107     case DSSIPlugin: | 
| Chris@19 | 108         return "$HOME/Library/Audio/Plug-Ins/DSSI:/Library/Audio/Plug-Ins/DSSI"; | 
| Chris@19 | 109 | 
| Chris@4 | 110 #else /* Linux, BSDs, etc */ | 
| Chris@19 | 111 | 
| Chris@4 | 112     case VampPlugin: | 
| Chris@19 | 113         return "$HOME/vamp:$HOME/.vamp:/usr/local/lib/vamp:/usr/lib/vamp"; | 
| Chris@4 | 114     case LADSPAPlugin: | 
| Chris@19 | 115         return "$HOME/ladspa:$HOME/.ladspa:/usr/local/lib/ladspa:/usr/lib/ladspa"; | 
| Chris@4 | 116     case DSSIPlugin: | 
| Chris@19 | 117         return "$HOME/dssi:$HOME/.dssi:/usr/local/lib/dssi:/usr/lib/dssi"; | 
| Chris@4 | 118 #endif | 
| Chris@4 | 119     } | 
| Chris@4 | 120 | 
| Chris@4 | 121     throw logic_error("unknown or unhandled plugin type"); | 
| Chris@4 | 122 } | 
| Chris@4 | 123 | 
| Chris@35 | 124 string | 
| Chris@35 | 125 KnownPlugins::getDefaultPathString(PluginType type) | 
| Chris@35 | 126 { | 
| Chris@35 | 127     string path = getUnexpandedDefaultPathString(type); | 
| Chris@35 | 128 | 
| Chris@35 | 129     if (path == "") { | 
| Chris@35 | 130         return path; | 
| Chris@35 | 131     } | 
| Chris@35 | 132 | 
| Chris@35 | 133     char *home = getenv("HOME"); | 
| Chris@35 | 134     if (home) { | 
| Chris@35 | 135         string::size_type f; | 
| Chris@35 | 136         while ((f = path.find("$HOME")) != string::npos && | 
| Chris@35 | 137                f < path.length()) { | 
| Chris@35 | 138             path.replace(f, 5, home); | 
| Chris@35 | 139         } | 
| Chris@35 | 140     } | 
| Chris@35 | 141 | 
| Chris@35 | 142 #ifdef _WIN32 | 
| Chris@35 | 143     const char *pfiles = 0; | 
| Chris@35 | 144     const char *pfiles32 = 0; | 
| Chris@35 | 145 | 
| Chris@35 | 146     pfiles = getenv("ProgramFiles"); | 
| Chris@35 | 147     if (!pfiles) { | 
| Chris@35 | 148         pfiles = "C:\\Program Files"; | 
| Chris@35 | 149     } | 
| Chris@35 | 150 | 
| Chris@35 | 151     pfiles32 = getenv("ProgramFiles(x86)"); | 
| Chris@35 | 152     if (!pfiles32) { | 
| Chris@35 | 153         pfiles32 = "C:\\Program Files (x86)"; | 
| Chris@35 | 154     } | 
| Chris@35 | 155 | 
| Chris@35 | 156     string::size_type f; | 
| Chris@35 | 157     while ((f = path.find("%ProgramFiles%")) != string::npos && | 
| Chris@35 | 158            f < path.length()) { | 
| Chris@35 | 159         if (m_format == FormatNonNative32Bit) { | 
| Chris@35 | 160             path.replace(f, 14, pfiles32); | 
| Chris@35 | 161         } else { | 
| Chris@35 | 162             path.replace(f, 14, pfiles); | 
| Chris@35 | 163         } | 
| Chris@35 | 164     } | 
| Chris@35 | 165 #endif | 
| Chris@35 | 166 | 
| Chris@35 | 167     return path; | 
| Chris@35 | 168 } | 
| Chris@35 | 169 | 
| Chris@4 | 170 vector<string> | 
| Chris@35 | 171 KnownPlugins::expandPathString(string path) | 
| Chris@4 | 172 { | 
| Chris@4 | 173     vector<string> pathList; | 
| Chris@4 | 174 | 
| Chris@4 | 175     string::size_type index = 0, newindex = 0; | 
| Chris@4 | 176 | 
| Chris@4 | 177     while ((newindex = path.find(PATH_SEPARATOR, index)) < path.size()) { | 
| Chris@19 | 178         pathList.push_back(path.substr(index, newindex - index).c_str()); | 
| Chris@19 | 179         index = newindex + 1; | 
| Chris@4 | 180     } | 
| Chris@4 | 181 | 
| Chris@4 | 182     pathList.push_back(path.substr(index)); | 
| Chris@4 | 183 | 
| Chris@4 | 184     return pathList; | 
| Chris@4 | 185 } | 
| Chris@4 | 186 | 
| Chris@35 | 187 vector<string> | 
| Chris@35 | 188 KnownPlugins::expandConventionalPath(PluginType type, string var) | 
| Chris@4 | 189 { | 
| Chris@35 | 190     string path; | 
| Chris@4 | 191 | 
| Chris@35 | 192     char *cpath = getenv(var.c_str()); | 
| Chris@35 | 193     if (cpath) path = cpath; | 
| Chris@35 | 194     if (path == "") { | 
| Chris@35 | 195         path = getDefaultPathString(type); | 
| Chris@4 | 196     } | 
| Chris@4 | 197 | 
| Chris@35 | 198     return expandPathString(path); | 
| Chris@4 | 199 } |