Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
54 changes: 54 additions & 0 deletions include/clapwrapper/wrapper_host.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
#ifndef CLAPWRAPPER_WRAPPER_HOST_H
#define CLAPWRAPPER_WRAPPER_HOST_H

#include "clap/private/macros.h"
#include "clap/host.h"

// CLAP_ABI was introduced in CLAP 1.1.2, for older versions we make it transparent
#ifndef CLAP_ABI
#define CLAP_ABI
#endif

/*
clap_wrapper_host_information

a host extension every clap-wrapper host provides, so a plugin can tell it is wrapped
and in what. a null result from get_extension means not wrapped.

auto *cwh = (const clap_wrapper_host_information_t *)host->get_extension(
host, CLAP_WRAPPER_HOST_INFORMATION);
if (cwh && strcmp(cwh->get_wrapper_flavor(host), CLAP_WRAPPER_HOST_FLAVOR_AUV2) == 0)
...
*/

#ifdef __cplusplus
extern "C"
{
#endif

static const CLAP_CONSTEXPR char CLAP_WRAPPER_HOST_INFORMATION[] = "clap-wrapper.host-information/0";

// compare with strcmp; the pointers are not guaranteed to be these arrays
static const CLAP_CONSTEXPR char CLAP_WRAPPER_HOST_FLAVOR_AUV2[] = "auv2";
static const CLAP_CONSTEXPR char CLAP_WRAPPER_HOST_FLAVOR_AUV3[] = "auv3";
static const CLAP_CONSTEXPR char CLAP_WRAPPER_HOST_FLAVOR_AAX[] = "aax";
static const CLAP_CONSTEXPR char CLAP_WRAPPER_HOST_FLAVOR_VST3[] = "vst3";
static const CLAP_CONSTEXPR char CLAP_WRAPPER_HOST_FLAVOR_STANDALONE[] = "standalone";

typedef struct clap_wrapper_host_information
{
// one of CLAP_WRAPPER_HOST_FLAVOR_*, valid for the life of the host
// [thread-safe]
const char *(CLAP_ABI *get_wrapper_flavor)(const clap_host_t *host);

// the real host's name without host->name's wrapper suffix, e.g. "REAPER"
// null when unknowable
// [thread-safe]
const char *(CLAP_ABI *get_underlying_host_name)(const clap_host_t *host);
} clap_wrapper_host_information_t;

#ifdef __cplusplus
}
#endif

#endif
5 changes: 5 additions & 0 deletions src/clap_proxy.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,10 @@ static bool track_info_get(const clap_host_t *host, clap_track_info_t *info)

const clap_host_track_info trackinfo = {track_info_get};

const clap_wrapper_host_information_t wrapper_host_information = {
[](const clap_host_t *host) -> const char * { return self(host)->wrapper_flavor(); },
[](const clap_host_t *host) -> const char * { return self(host)->underlying_host_name(); }};

const clap_host_preset_load_t preset_load = {
/* on_error */
[](const clap_host_t *host, uint32_t location_kind, const char *location, const char *load_key,
Expand Down Expand Up @@ -589,6 +593,7 @@ const void *Plugin::clapExtension(const clap_host * /*host*/, const char *extens
if (!strcmp(extension, CLAP_EXT_CONTEXT_MENU)) return &HostExt::context_menu;
if (!strcmp(extension, CLAP_EXT_PRESET_LOAD) || !strcmp(extension, CLAP_EXT_PRESET_LOAD_COMPAT))
return &HostExt::preset_load;
if (!strcmp(extension, CLAP_WRAPPER_HOST_INFORMATION)) return &HostExt::wrapper_host_information;

#if LIN
if (!strcmp(extension, CLAP_EXT_POSIX_FD_SUPPORT)) return &HostExt::hostposixfd;
Expand Down
14 changes: 14 additions & 0 deletions src/clap_proxy.h
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,11 @@ class IHost
virtual bool track_info_get(clap_track_info_t *info) = 0;
virtual const char *host_get_name() = 0;

// one of CLAP_WRAPPER_HOST_FLAVOR_*, reported through CLAP_WRAPPER_HOST_INFORMATION
virtual const char *wrapper_flavor() const = 0;
// set before the plugin is created and not changed after; nullptr when unknowable
virtual const char *underlying_host_name() const = 0;

// clap.preset-load, host side. Defaulted rather than pure: only the formats
// that can show a preset list (VST3 program lists, AU factory presets) have
// anything to do here, and making these pure would force every other
Expand Down Expand Up @@ -283,6 +288,15 @@ class Plugin
return _parentHost->track_info_get(info);
}

const char *wrapper_flavor() const
{
return _parentHost->wrapper_flavor();
}
const char *underlying_host_name() const
{
return _parentHost->underlying_host_name();
}

// clap_timer support
bool register_timer(uint32_t period_ms, clap_id *timer_id);
bool unregister_timer(clap_id timer_id);
Expand Down
4 changes: 4 additions & 0 deletions src/detail/aax/audioconfig.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -196,6 +196,9 @@ plugin_bus_info_t getAvailableBusConfigs(Clap::Library *factory, uint32_t index)
static const clap_host_audio_ports_t micro_audio_ports = {
[](const clap_host_t *host, uint32_t flag) -> bool { return false; },
[](const clap_host_t *host, uint32_t flags) -> void {}};
static const clap_wrapper_host_information_t micro_wrapper_info = {
[](const clap_host_t *host) -> const char * { return CLAP_WRAPPER_HOST_FLAVOR_AAX; },
[](const clap_host_t *host) -> const char * { return nullptr; }};
clap_host_t microhost = {
CLAP_VERSION,
nullptr,
Expand All @@ -209,6 +212,7 @@ plugin_bus_info_t getAvailableBusConfigs(Clap::Library *factory, uint32_t index)
LOGDETAIL("plugin requests microhost extension {}", extension_id);
if (!strcmp(CLAP_EXT_PARAMS, extension_id)) return &micro_params;
if (!strcmp(CLAP_EXT_AUDIO_PORTS, extension_id)) return &micro_audio_ports;
if (!strcmp(CLAP_WRAPPER_HOST_INFORMATION, extension_id)) return &micro_wrapper_info;
return nullptr;
},
[](const struct clap_host *host) -> void {}, // request_restart
Expand Down
11 changes: 4 additions & 7 deletions src/detail/aax/wrapper.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -550,6 +550,9 @@ AAX_Result ClapAsAAX::EffectInit()

LOGINFO(fmt::format("AAX Effect Init for '{}'", m.StdString().c_str()));

AAX_CString hostname;
if (AAX_SUCCESS == _aax_ctrl->GetHostName(&hostname)) _underlying_hostname = hostname.StdString();

_library = CLAPAAX::guarantee_clap();
_plugin = Clap::Plugin::createInstance(_library->_pluginFactory, m.StdString(), this);

Expand Down Expand Up @@ -1163,13 +1166,7 @@ bool ClapAsAAX::track_info_get(clap_track_info_t *info)

const char *ClapAsAAX::host_get_name()
{
AAX_IController *ctrl = Controller();
AAX_CString hostname;
if (AAX_SUCCESS == ctrl->GetHostName(&hostname))
{
_wrapper_hostname = hostname.StdString();
_wrapper_hostname.append(" (CLAP-as-AAX)");
}
if (!_underlying_hostname.empty()) _wrapper_hostname = _underlying_hostname + " (CLAP-as-AAX)";
return _wrapper_hostname.c_str();
}

Expand Down
9 changes: 9 additions & 0 deletions src/detail/aax/wrapper.h
Original file line number Diff line number Diff line change
Expand Up @@ -246,6 +246,14 @@ class ClapAsAAX : public AAX_CEffectParameters,

bool track_info_get(clap_track_info_t *info) override;
const char *host_get_name() override;
const char *wrapper_flavor() const override
{
return CLAP_WRAPPER_HOST_FLAVOR_AAX;
}
const char *underlying_host_name() const override
{
return _underlying_hostname.empty() ? nullptr : _underlying_hostname.c_str();
}

bool supportsContextMenu() const override;
// context_menu
Expand Down Expand Up @@ -273,6 +281,7 @@ class ClapAsAAX : public AAX_CEffectParameters,
os::State _os_attached;

std::string _wrapper_hostname = "CLAP-As-AAX-Wrapper";
std::string _underlying_hostname;

// _parameterMap maps the AAX CParamID to the wrapped parameter
std::map<std::string, std::shared_ptr<AAXWrappedParameterInfo_t>> _parameterMap;
Expand Down
10 changes: 10 additions & 0 deletions src/detail/auv2/auv2_base_classes.h
Original file line number Diff line number Diff line change
Expand Up @@ -698,6 +698,15 @@ class WrapAsAUV2 : public ausdk::AUBase,
return false;
}

const char *wrapper_flavor() const override
{
return CLAP_WRAPPER_HOST_FLAVOR_AUV2;
}
const char *underlying_host_name() const override
{
return _underlying_hostname.empty() ? nullptr : _underlying_hostname.c_str();
}

const char *host_get_name() override
{
char text[65];
Expand Down Expand Up @@ -920,6 +929,7 @@ class WrapAsAUV2 : public ausdk::AUBase,
// std::vector<clap_note_port_info_t> _midi_outports_info;

std::string _hostname = "CLAP-as-AUv2";
std::string _underlying_hostname;

#ifdef DUAL_SCHEDULING_ENABLED
bool _midi_dualscheduling_mode = false;
Expand Down
11 changes: 11 additions & 0 deletions src/detail/auv3/auv3_audiounit.mm
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,7 @@ - (void)_applyGUISizeWidth:(uint32_t)width height:(uint32_t)height;
int _idx = 0;
os::State _os_attached;
std::string _hostname = "CLAP-as-AUv3";
std::string _underlying_hostname;
std::atomic<bool> _initialized{false};
std::atomic_bool _requestUICallback{false};
// set by mark_dirty(), serviced by the idle timer
Expand Down Expand Up @@ -600,6 +601,15 @@ void fireTimers()
}
}

const char *wrapper_flavor() const override
{
return CLAP_WRAPPER_HOST_FLAVOR_AUV3;
}
const char *underlying_host_name() const override
{
return _underlying_hostname.empty() ? nullptr : _underlying_hostname.c_str();
}

const char *host_get_name() override
{
NSBundle *mainBundle = [NSBundle mainBundle];
Expand Down Expand Up @@ -981,6 +991,7 @@ - (instancetype)initWithComponentDescription:(AudioComponentDescription)componen

// Create the plugin instance
AUV3LOG("init: creating plugin instance via factory");
_impl->_underlying_hostname = os::getHostAppName();
_impl->_plugin =
Clap::Plugin::createInstance(_library._pluginFactory, _impl->_desc->id, _impl.get());
if (!_impl->_plugin)
Expand Down
1 change: 1 addition & 0 deletions src/detail/clap/fsutil.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
#include "clapwrapper/vst3.h"
#include "clapwrapper/auv2.h"
#include "clapwrapper/aax.h"
#include "clapwrapper/wrapper_host.h"
#include "../ara/ara.h"
#include "detail/os/fs.h"

Expand Down
11 changes: 11 additions & 0 deletions src/detail/os/macos.mm
Original file line number Diff line number Diff line change
Expand Up @@ -149,4 +149,15 @@ uint64_t getTickInMS()
return getPluginPath().stem();
}

std::string getHostAppName()
{
NSBundle *mainBundle = [NSBundle mainBundle];
// AUHostingService and our own appex are both XPC! bundles
if ([[mainBundle objectForInfoDictionaryKey:@"CFBundlePackageType"] isEqualToString:@"XPC!"])
return {};
NSString *name = [mainBundle objectForInfoDictionaryKey:@"CFBundleName"];
if (!name) name = [[NSProcessInfo processInfo] processName];
return name ? std::string([name UTF8String]) : std::string();
}

} // namespace os
5 changes: 5 additions & 0 deletions src/detail/os/osutil.h
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,11 @@ fs::path getPluginPath();
std::string getParentFolderName();
std::string getBinaryName();

#if MAC
// empty when loaded into an xpc service or appex, where the real host is unknowable
std::string getHostAppName();
#endif

#ifdef WIN32
void init();
void terminate();
Expand Down
14 changes: 14 additions & 0 deletions src/detail/standalone/standalone_host.h
Original file line number Diff line number Diff line change
Expand Up @@ -230,6 +230,20 @@ struct StandaloneHost : Clap::IHost
bool unregister_timer(clap_id timer_id) override;

const char *host_get_name() override;
const char *wrapper_flavor() const override
{
return CLAP_WRAPPER_HOST_FLAVOR_STANDALONE;
}
const char *underlying_host_name() const override
{
#if MAC
return "Wrapper Mac Standalone";
#elif WIN
return "Wrapper Windows Standalone";
#else
return "Wrapper Linux Standalone";
#endif
}

bool track_info_get(clap_track_info_t *info) override
{
Expand Down
1 change: 1 addition & 0 deletions src/wrapasauv2.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -169,6 +169,7 @@ WrapAsAUV2::WrapAsAUV2(const std::string &clapname, const std::string &clapid, i
*/

// pffffrzz(); // <- enable this to have a hook to attach a debugger
_underlying_hostname = os::getHostAppName();
_plugin = Clap::Plugin::createInstance(_library._pluginFactory, _desc->id, this);
if (_plugin)
{
Expand Down
13 changes: 4 additions & 9 deletions src/wrapasvst3.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -152,6 +152,9 @@ tresult PLUGIN_API ClapAsVst3::initialize(FUnknown *context)
{
if (!_plugin)
{
Steinberg::Vst::String128 res;
if (vst3HostApplication && kResultOk == vst3HostApplication->getName(res))
underlying_hostname = stringconv::convert(res);
_plugin = Clap::Plugin::createInstance(*_library, _libraryIndex, this);
}
result = (_plugin && _plugin->initialize()) ? kResultOk : kResultFalse;
Expand Down Expand Up @@ -1759,15 +1762,7 @@ bool ClapAsVst3::unregister_timer(clap_id timer_id)

const char *ClapAsVst3::host_get_name()
{
if (vst3HostApplication)
{
Steinberg::Vst::String128 res;
if (kResultOk == vst3HostApplication->getName(res))
{
wrapper_hostname = stringconv::convert(res);
wrapper_hostname.append(" (CLAP-as-VST3)");
}
}
if (!underlying_hostname.empty()) wrapper_hostname = underlying_hostname + " (CLAP-as-VST3)";
return wrapper_hostname.c_str();
}

Expand Down
9 changes: 9 additions & 0 deletions src/wrapasvst3.h
Original file line number Diff line number Diff line change
Expand Up @@ -306,6 +306,7 @@ class ClapAsVst3 : public Steinberg::Vst::SingleComponentEffect,
IPtr<Steinberg::Vst::IContextMenu> vst3ContextMenu = nullptr;
IPtr<Steinberg::Vst::IHostApplication> vst3HostApplication = nullptr;
std::string wrapper_hostname = "CLAP-As-VST3-Wrapper";
std::string underlying_hostname;
std::vector<wrapper_context_menu_item> contextmenuitems;
uint32_t vst3ContextMenuParamID = 0;

Expand Down Expand Up @@ -348,6 +349,14 @@ class ClapAsVst3 : public Steinberg::Vst::SingleComponentEffect,
bool unregister_timer(clap_id timer_id) override;

const char *host_get_name() override;
const char *wrapper_flavor() const override
{
return CLAP_WRAPPER_HOST_FLAVOR_VST3;
}
const char *underlying_host_name() const override
{
return underlying_hostname.empty() ? nullptr : underlying_hostname.c_str();
}

bool supportsContextMenu() const override;
// context_menu
Expand Down
27 changes: 27 additions & 0 deletions tests/clap-first-example/distortion_clap.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
#include <math.h>
#include <assert.h>
#include "clapwrapper/vst3.h"
#include "clapwrapper/wrapper_host.h"
#include "distortion_clap_entry.h"

static const char *features[] = {CLAP_PLUGIN_FEATURE_AUDIO_EFFECT, CLAP_PLUGIN_FEATURE_STEREO,
Expand Down Expand Up @@ -371,6 +372,32 @@ static bool clap1stDist_init(const struct clap_plugin *plugin)
if (plug->hostLog && plug->host)
{
plug->hostLog->log(plug->host, CLAP_LOG_INFO, "Created clap1st Distortion compiled with C++");

// null means a real clap host rather than clap-wrapper
auto *cwh = (const clap_wrapper_host_information_t *)plug->host->get_extension(
plug->host, CLAP_WRAPPER_HOST_INFORMATION);
const char *how = "Running as a CLAP";
if (cwh)
{
const char *flavor = cwh->get_wrapper_flavor(plug->host);
if (strcmp(flavor, CLAP_WRAPPER_HOST_FLAVOR_VST3) == 0)
how = "Wrapped as a VST3";
else if (strcmp(flavor, CLAP_WRAPPER_HOST_FLAVOR_AUV2) == 0)
how = "Wrapped as an AUv2";
else if (strcmp(flavor, CLAP_WRAPPER_HOST_FLAVOR_STANDALONE) == 0)
how = "Wrapped as a standalone";
else
how = "Wrapped in some other format";
}
plug->hostLog->log(plug->host, CLAP_LOG_INFO, how);

if (cwh)
{
const char *underlying = cwh->get_underlying_host_name(plug->host);
char msg[256];
snprintf(msg, sizeof(msg), "Underlying host is '%s'", underlying ? underlying : "unknown");
plug->hostLog->log(plug->host, CLAP_LOG_INFO, msg);
}
}

return true;
Expand Down
Loading