gearmulator

Emulation of classic VA synths of the late 90s/2000s that are based on Motorola 56300 family DSPs
Log | Files | Refs | Submodules | README | LICENSE

os.cpp (4339B)


      1 #include "os.h"
      2 
      3 #include "baseLib/filesystem.h"
      4 
      5 #include "dsp56kEmu/logging.h"
      6 
      7 #ifndef _WIN32
      8 // filesystem is only available on macOS Catalina 10.15+
      9 // filesystem causes linker errors in gcc-8 if linked statically
     10 #define USE_DIRENT
     11 #include <cstdlib>
     12 #include <cstring>
     13 #include <pwd.h>
     14 #endif
     15 
     16 #ifdef USE_DIRENT
     17 #include <dirent.h>
     18 #include <unistd.h>
     19 #include <sys/stat.h>
     20 #else
     21 #include <filesystem>
     22 #endif
     23 
     24 #ifdef _WIN32
     25 #define NOMINMAX
     26 #define NOSERVICE
     27 #include <Windows.h>
     28 #include <shlobj_core.h>
     29 #else
     30 #include <dlfcn.h>
     31 #endif
     32 
     33 #ifdef _MSC_VER
     34 #include <cfloat>
     35 #elif defined(HAVE_SSE)
     36 #include <immintrin.h>
     37 #endif
     38 
     39 #ifdef __APPLE__
     40 #include <sys/types.h>
     41 #include <sys/sysctl.h>
     42 #endif
     43 
     44 using namespace baseLib::filesystem;
     45 
     46 namespace synthLib
     47 {
     48 	std::string getModulePath(bool _stripPluginComponentFolders/* = true*/)
     49     {
     50         std::string path;
     51 #ifdef _WIN32
     52         char buffer[MAX_PATH];
     53         HMODULE hm = nullptr;
     54 
     55         if (GetModuleHandleEx(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS | GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT,
     56                               reinterpret_cast<LPCSTR>(&getModulePath), &hm) == 0)
     57         {
     58             LOG("GetModuleHandle failed, error = " << GetLastError());
     59             return {};
     60         }
     61         if (GetModuleFileName(hm, buffer, sizeof(buffer)) == 0)
     62         {
     63             LOG("GetModuleFileName failed, error = " << GetLastError());
     64             return {};
     65         }
     66 
     67         path = buffer;
     68 #else
     69         Dl_info info;
     70         if (!dladdr(reinterpret_cast<const void *>(&getModulePath), &info))
     71         {
     72             LOG("Failed to get module path");
     73             return std::string();
     74         }
     75         else
     76         {
     77             path = info.dli_fname;
     78         }
     79 #endif
     80 
     81     	auto fixPathWithDelim = [&](const std::string& _key, const char _delim)
     82     	{
     83 			const auto end = path.rfind(_key + _delim);
     84 
     85             // strip folders such as "/foo.vst/" but do NOT strip "/.vst/"
     86 			if (end != std::string::npos && (path.find(_delim + _key) + 1) != end)
     87 				path = path.substr(0, end);
     88 		};
     89 
     90     	auto fixPath = [&](const std::string& _key)
     91     	{
     92 			fixPathWithDelim(_key, '/');
     93 			fixPathWithDelim(_key, '\\');
     94 		};
     95 
     96         if(_stripPluginComponentFolders)
     97         {
     98 			fixPath(".vst");
     99 			fixPath(".vst3");
    100 			fixPath(".clap");
    101 			fixPath(".component");
    102 			fixPath(".app");
    103         }
    104 
    105 		const auto end = path.find_last_of("/\\");
    106 
    107         if (end != std::string::npos)
    108             path = path.substr(0, end + 1);
    109 
    110         return validatePath(path);
    111     }
    112 
    113 	namespace
    114 	{
    115 	    std::string findFile(const std::string& _extension, const size_t _minSize, const size_t _maxSize, const bool _stripPluginComponentFolders)
    116 	    {
    117 	        std::string path = getModulePath(_stripPluginComponentFolders);
    118 
    119 	        if(path.empty())
    120 	            path = getCurrentDirectory();
    121 
    122 	        return baseLib::filesystem::findFile(path, _extension, _minSize, _maxSize);
    123 	    }
    124 	}
    125 
    126     std::string findFile(const std::string& _extension, const size_t _minSize, const size_t _maxSize)
    127     {
    128         auto res = findFile(_extension, _minSize, _maxSize, true);
    129 		if (!res.empty())
    130 			return res;
    131 		return findFile(_extension, _minSize, _maxSize, false);
    132     }
    133 
    134 	std::string findROM(const size_t _minSize, const size_t _maxSize)
    135     {
    136         std::string path = getModulePath();
    137 
    138         if(path.empty())
    139             path = getCurrentDirectory();
    140 
    141 		auto f = baseLib::filesystem::findFile(path, ".bin", _minSize, _maxSize);
    142         if(!f.empty())
    143             return f;
    144 
    145     	path = getModulePath(false);
    146 
    147 		return baseLib::filesystem::findFile(path, ".bin", _minSize, _maxSize);
    148     }
    149 
    150     std::string findROM(const size_t _expectedSize)
    151     {
    152 	    return findROM(_expectedSize, _expectedSize);
    153     }
    154 
    155     void setFlushDenormalsToZero()
    156     {
    157 #if defined(_MSC_VER)
    158         _controlfp(_DN_FLUSH, _MCW_DN);
    159 #elif defined(HAVE_SSE)
    160         _MM_SET_FLUSH_ZERO_MODE(_MM_FLUSH_ZERO_ON);
    161 #endif
    162     }
    163 
    164     bool isRunningUnderRosetta()
    165     {
    166 #ifdef __APPLE__
    167 		int ret = 0;
    168 		size_t size = sizeof(ret);
    169 		if (sysctlbyname("sysctl.proc_translated", &ret, &size, NULL, 0) == -1) 
    170 		{
    171 			if (errno == ENOENT)
    172 				return false;	// no, native
    173 			return false;		// unable to tell, assume native
    174 		}
    175 		return ret == 1;		// Rosetta if result is 1
    176 #else
    177 		return false;
    178 #endif
    179    	}
    180 } // namespace synthLib