iPlug2 - C++ Audio Plug-in Framework
Loading...
Searching...
No Matches
IPlugPaths.mm
Go to the documentation of this file.
1/*
2 ==============================================================================
3
4 This file is part of the iPlug 2 library. Copyright (C) the iPlug 2 developers.
5
6 See LICENSE.txt for more info.
7
8 ==============================================================================
9*/
10
17#include "IPlugPaths.h"
18#include <string>
19#include <map>
20
21#if defined(OS_IOS) || defined(OS_MAC)
22#import <Foundation/Foundation.h>
23#include <TargetConditionals.h>
24#endif
25
26#ifdef IGRAPHICS_METAL
27extern std::map<std::string, void*> gTextureMap;
28#endif
29
30BEGIN_IPLUG_NAMESPACE
31
32#ifdef OS_MAC
33#pragma mark - macOS
34
35void HostPath(WDL_String& path, const char* bundleID)
36{
37 @autoreleasepool
38 {
39 NSBundle* pBundle = [NSBundle bundleWithIdentifier: [NSString stringWithCString:bundleID encoding:NSUTF8StringEncoding]];
40
41 if (pBundle)
42 {
43 NSString* pPath = [pBundle executablePath];
44 if (pPath)
45 {
46 path.Set([pPath UTF8String]);
47 }
48 }
49 }
50}
51
52void PluginPath(WDL_String& path, PluginIDType bundleID)
53{
54 @autoreleasepool
55 {
56 NSBundle* pBundle = [NSBundle bundleWithIdentifier: [NSString stringWithCString:bundleID encoding:NSUTF8StringEncoding]];
57
58 if (pBundle)
59 {
60 NSString* pPath = [[pBundle bundlePath] stringByDeletingLastPathComponent];
61
62 if (pPath)
63 {
64 path.Set([pPath UTF8String]);
65 path.Append("/");
66 }
67 }
68 }
69}
70
71void BundleResourcePath(WDL_String& path, PluginIDType bundleID)
72{
73 @autoreleasepool
74 {
75 NSBundle* pBundle = [NSBundle bundleWithIdentifier:[NSString stringWithCString:bundleID encoding:NSUTF8StringEncoding]];
76 NSString* pResPath = [pBundle resourcePath];
77
78 path.Set([pResPath UTF8String]);
79 }
80}
81
82void DesktopPath(WDL_String& path)
83{
84 NSArray* pPaths = NSSearchPathForDirectoriesInDomains(NSDesktopDirectory, NSUserDomainMask, YES);
85 NSString* pDesktopDirectory = [pPaths objectAtIndex:0];
86 path.Set([pDesktopDirectory UTF8String]);
87}
88
89void UserHomePath(WDL_String& path)
90{
91 NSString* pHomeDir = NSHomeDirectory();
92 path.Set([pHomeDir UTF8String]);
93}
94
95void VST3PresetsPath(WDL_String& path, const char* mfrName, const char* pluginName, bool isSystem)
96{
97 NSArray* pPaths;
98 if (isSystem)
99 pPaths = NSSearchPathForDirectoriesInDomains(NSLibraryDirectory, NSLocalDomainMask, YES);
100 else
101 pPaths = NSSearchPathForDirectoriesInDomains(NSLibraryDirectory, NSUserDomainMask, YES);
102
103 NSString* pApplicationSupportDirectory = [pPaths objectAtIndex:0];
104 path.SetFormatted(MAX_MACOS_PATH_LEN, "%s/Audio/Presets/%s/%s/", [pApplicationSupportDirectory UTF8String], mfrName, pluginName);
105}
106
107void INIPath(WDL_String& path, const char* pluginName)
108{
109 AppSupportPath(path, false);
110 path.AppendFormatted(MAX_MACOS_PATH_LEN, "/%s", pluginName);
111}
112
113void AppSupportPath(WDL_String& path, bool isSystem)
114{
115 NSArray* pPaths;
116
117 if (isSystem)
118 pPaths = NSSearchPathForDirectoriesInDomains(NSApplicationSupportDirectory, NSSystemDomainMask, YES);
119 else
120 pPaths = NSSearchPathForDirectoriesInDomains(NSApplicationSupportDirectory, NSUserDomainMask, YES);
121
122 NSString *pApplicationSupportDirectory = [pPaths objectAtIndex:0];
123 path.Set([pApplicationSupportDirectory UTF8String]);
124}
125
126void AppGroupContainerPath(WDL_String& path, const char* appGroupID)
127{
128 NSFileManager* mgr = [NSFileManager defaultManager];
129 NSURL* url = [mgr containerURLForSecurityApplicationGroupIdentifier:[NSString stringWithUTF8String:appGroupID]];
130 path.Set([[url path] UTF8String]);
131}
132
133void SharedMusicPath(WDL_String& path)
134{
135 NSArray* pPaths = NSSearchPathForDirectoriesInDomains(NSMusicDirectory, NSUserDomainMask, YES);
136 NSString* pUserMusicDirectory = [pPaths objectAtIndex:0];
137 path.Set([pUserMusicDirectory UTF8String]);
138}
139
140bool GetResourcePathFromBundle(const char* fileName, const char* searchExt, WDL_String& fullPath, const char* bundleID)
141{
142 @autoreleasepool
143 {
144 const char* ext = fileName+strlen(fileName)-1;
145 while (ext >= fileName && *ext != '.') --ext;
146 ++ext;
147
148 bool isCorrectType = !strcasecmp(ext, searchExt);
149
150 bool isAppExtension = IsOOPAuv3AppExtension();
151
152 NSBundle* pBundle = [NSBundle bundleWithIdentifier:[NSString stringWithCString:bundleID encoding:NSUTF8StringEncoding]];
153
154 NSString* pFile = [[NSString stringWithCString:fileName encoding:NSUTF8StringEncoding] stringByDeletingPathExtension];
155 NSString* pExt = [NSString stringWithCString:searchExt encoding:NSUTF8StringEncoding];
156
157 if (isCorrectType && pBundle && pFile)
158 {
159 NSString* pBasePath;
160
161 if(isAppExtension)
162 pBasePath = [[[[pBundle bundlePath] stringByDeletingLastPathComponent] stringByDeletingLastPathComponent] stringByAppendingString:@"/Resources/"];
163 else
164 pBasePath = [[pBundle resourcePath] stringByAppendingString:@"/"];
165
166 NSString* pPath = [[[pBasePath stringByAppendingString:pFile] stringByAppendingString: @"."] stringByAppendingString:pExt];
167
168 if (pPath && [[NSFileManager defaultManager] fileExistsAtPath : pPath] == YES)
169 {
170 fullPath.Set([pPath cStringUsingEncoding:NSUTF8StringEncoding]);
171 return true;
172 }
173 }
174
175 fullPath.Set("");
176 return false;
177 }
178}
179
180bool GetResourcePathFromSharedLocation(const char* fileName, const char* searchExt, WDL_String& fullPath, const char* subfolder)
181{
182 @autoreleasepool
183 {
184 const char* ext = fileName+strlen(fileName)-1;
185 while (ext >= fileName && *ext != '.') --ext;
186 ++ext;
187
188 bool isCorrectType = !strcasecmp(ext, searchExt);
189
190 NSString* pExt = [NSString stringWithCString:searchExt encoding:NSUTF8StringEncoding];
191 NSString* pFile = [[[NSString stringWithCString:fileName encoding:NSUTF8StringEncoding] lastPathComponent] stringByDeletingPathExtension];
192
193 if (isCorrectType && pFile)
194 {
195 WDL_String musicPath;
196 SharedMusicPath(musicPath);
197
198 if(subfolder)
199 {
200 NSString* pPluginName = [NSString stringWithCString: subfolder encoding:NSUTF8StringEncoding];
201 NSString* pMusicLocation = [NSString stringWithCString: musicPath.Get() encoding:NSUTF8StringEncoding];
202 NSString* pPath = [[[[pMusicLocation stringByAppendingPathComponent:pPluginName] stringByAppendingPathComponent:@"Resources"] stringByAppendingPathComponent: pFile] stringByAppendingPathExtension:pExt];
203
204 if([[NSFileManager defaultManager] fileExistsAtPath : pPath] == YES)
205 {
206 fullPath.Set([pPath cString]);
207 return true;
208 }
209 }
210 }
211
212 fullPath.Set("");
213 return false;
214 }
215}
216
217EResourceLocation LocateResource(const char* name, const char* type, WDL_String& result, const char* bundleID, void*, const char* sharedResourcesSubPath)
218{
219 if(CStringHasContents(name))
220 {
221#ifndef AUv3_API
222 // first check this bundle
223 if(GetResourcePathFromBundle(name, type, result, bundleID))
224 return EResourceLocation::kAbsolutePath;
225#endif
226
227 // then check ~/Music/sharedResourcesSubPath, which is a shared folder that can be accessed from app sandbox
228 if(GetResourcePathFromSharedLocation(name, type, result, sharedResourcesSubPath))
229 return EResourceLocation::kAbsolutePath;
230
231 // finally check name, which might be a full path - if the plug-in is trying to load a resource at runtime (e.g. skin-able UI)
232 NSString* pPath = [NSString stringWithCString:name encoding:NSUTF8StringEncoding];
233
234 if([[NSFileManager defaultManager] fileExistsAtPath : pPath] == YES)
235 {
236 result.Set([pPath UTF8String]);
237 return EResourceLocation::kAbsolutePath;
238 }
239 }
240 return EResourceLocation::kNotFound;
241}
242
243bool AppIsSandboxed()
244{
245 NSString* pHomeDir = NSHomeDirectory();
246
247 if ([pHomeDir containsString:@"Library/Containers/"])
248 return true;
249 else
250 return false;
251}
252
253bool IsXPCAuHost()
254{
255 return ([[[NSProcessInfo processInfo] processName] containsString:@"XPC"]);
256}
257
258bool IsOOPAuv3AppExtension()
259{
260 return ([[[NSBundle mainBundle] bundleIdentifier] containsString:@"AUv3"]);
261}
262
263#elif defined OS_IOS
264#pragma mark - iOS
265
266void HostPath(WDL_String& path, const char* bundleID)
267{
268}
269
270void PluginPath(WDL_String& path, PluginIDType bundleID)
271{
272}
273
274void BundleResourcePath(WDL_String& path, PluginIDType bundleID)
275{
276 NSBundle* pBundle = [NSBundle mainBundle];
277
278 if(IsOOPAuv3AppExtension())
279 pBundle = [NSBundle bundleWithPath: [[[pBundle bundlePath] stringByDeletingLastPathComponent] stringByDeletingLastPathComponent]];
280
281 path.Set([[pBundle resourcePath] UTF8String]);
282}
283
284void DesktopPath(WDL_String& path)
285{
286}
287
288void VST3PresetsPath(WDL_String& path, const char* mfrName, const char* pluginName, bool isSystem)
289{
290 path.Set("");
291}
292
293void INIPath(WDL_String& path, const char* pluginName)
294{
295 path.Set("");
296}
297
298void AppSupportPath(WDL_String& path, bool isSystem)
299{
300}
301
302void AppGroupContainerPath(WDL_String& path, const char* appGroupID)
303{
304 NSFileManager* mgr = [NSFileManager defaultManager];
305 NSURL* url = [mgr containerURLForSecurityApplicationGroupIdentifier:[NSString stringWithUTF8String:appGroupID]];
306 path.Set([[url path] UTF8String]);
307}
308
309bool GetResourcePathFromBundle(const char* fileName, const char* searchExt, WDL_String& fullPath, const char* bundleID)
310{
311 @autoreleasepool
312 {
313 const char* ext = fileName+strlen(fileName)-1;
314 while (ext >= fileName && *ext != '.') --ext;
315 ++ext;
316
317 bool isCorrectType = !strcasecmp(ext, searchExt);
318
319 bool isAppExtension = IsOOPAuv3AppExtension();
320
321 NSBundle* pBundle;
322
323 if(isAppExtension)
324 pBundle = [NSBundle bundleWithIdentifier:[NSString stringWithCString:bundleID encoding:NSUTF8StringEncoding]];
325 else
326 pBundle = [NSBundle mainBundle];
327
328 NSString* pFile = [[NSString stringWithCString:fileName encoding:NSUTF8StringEncoding] stringByDeletingPathExtension];
329 NSString* pExt = [NSString stringWithCString:searchExt encoding:NSUTF8StringEncoding];
330
331 if (isCorrectType && pBundle && pFile)
332 {
333 NSString* pRootPath;
334
335 if (isAppExtension)
336 {
337 pRootPath = [[[pBundle bundlePath] stringByDeletingLastPathComponent] stringByDeletingLastPathComponent];
338 #if TARGET_OS_MACCATALYST
339 pRootPath = [pRootPath stringByAppendingString: @"/Resources"];
340 #endif
341 }
342 else
343 {
344 pRootPath = [pBundle resourcePath];
345 }
346
347 NSString* pPath = [[[[pRootPath stringByAppendingString:@"/"] stringByAppendingString:pFile] stringByAppendingString: @"."] stringByAppendingString:pExt];
348
349 if (pPath && [[NSFileManager defaultManager] fileExistsAtPath : pPath] == YES)
350 {
351 fullPath.Set([pPath cStringUsingEncoding:NSUTF8StringEncoding]);
352 return true;
353 }
354 }
355
356 fullPath.Set("");
357 return false;
358 }
359}
360
361EResourceLocation LocateResource(const char* name, const char* type, WDL_String& result, const char* bundleID, void*, const char*)
362{
363 if (CStringHasContents(name))
364 {
365#ifdef IGRAPHICS_METAL
366 auto itr = gTextureMap.find(name);
367
368 if (itr != gTextureMap.end())
369 {
370 result.Set(name);
371 return EResourceLocation::kPreloadedTexture;
372 }
373#endif
374
375 if (GetResourcePathFromBundle(name, type, result, bundleID))
376 return EResourceLocation::kAbsolutePath;
377 }
378
379 return EResourceLocation::kNotFound;
380}
381
382bool AppIsSandboxed()
383{
384 return true;
385}
386
387bool IsXPCAuHost()
388{
389 // TODO: actually not allways the case if AUv3 is instantiated from framework
390 return true;
391}
392
393bool IsOOPAuv3AppExtension()
394{
395 return ([[[NSBundle mainBundle] bundleIdentifier] containsString:@"AUv3"]);
396}
397
398#endif
399
400END_IPLUG_NAMESPACE
Common paths useful for plug-ins.
void UserHomePath(WDL_String &path)
EResourceLocation LocateResource(const char *fileNameOrResID, const char *type, WDL_String &result, const char *bundleID, void *pHInstance, const char *sharedResourcesSubPath)
Find the absolute path of a resource based on it's file name (e.g.
void VST3PresetsPath(WDL_String &path, const char *mfrName, const char *pluginName, bool isSystem=true)
void PluginPath(WDL_String &path, PluginIDType pExtra)
Get the path to the plug-in binary.
void DesktopPath(WDL_String &path)
void HostPath(WDL_String &path, const char *bundleID=0)
Get the path to the host binary.
void AppSupportPath(WDL_String &path, bool isSystem=false)
void BundleResourcePath(WDL_String &path, PluginIDType pExtra=0)
Get the path to the plug-in bundle resource path.
void INIPath(WDL_String &path, const char *pluginName)
Get the path to the folder where the App's settings.ini file is stored.