13
0

VST3: Implement PSI extensions

* Register classes
* Implement automation-state notification
* Implenent parameter slave
This commit is contained in:
Robin Gareus 2020-10-05 19:56:13 +02:00
parent 042f0a192f
commit 65c433dce2
Signed by: rgareus
GPG Key ID: A090BCE02CF57F04
3 changed files with 123 additions and 0 deletions

View File

@ -29,6 +29,7 @@
namespace ARDOUR {
class VST3PluginModule;
class AutomationList;
}
#if defined(__clang__)
@ -113,6 +114,9 @@ public:
std::string print_parameter (Vst::ParamID, Vst::ParamValue) const;
bool set_program (int p, int32 sample_off);
bool subscribe_to_automation_changes () const;
void automation_state_changed (uint32_t, ARDOUR::AutoState, boost::weak_ptr<ARDOUR::AutomationList>);
ARDOUR::Plugin::IOPortDescription describe_io_port (ARDOUR::DataType dt, bool input, uint32_t id) const;
uint32_t n_audio_inputs () const;
@ -154,6 +158,11 @@ public:
void process (float** ins, float** outs, uint32_t n_samples);
/* PSL Extension */
Vst::IEditController* conroller () const { return _controller; }
bool add_slave (Vst::IEditController*, bool);
bool remove_slave (Vst::IEditController*);
private:
/* prevent copy construction */
VST3PI (const VST3PI&);
@ -287,6 +296,8 @@ public:
IOPortDescription describe_io_port (DataType dt, bool input, uint32_t id) const;
PluginOutputConfiguration possible_output () const;
void set_automation_control (uint32_t, boost::shared_ptr<ARDOUR::AutomationControl>);
std::string state_node_name () const { return "vst3"; }
void add_state (XMLNode*) const;
@ -303,6 +314,9 @@ public:
void set_owner (ARDOUR::SessionObject* o);
void add_slave (boost::shared_ptr<Plugin>, bool);
void remove_slave (boost::shared_ptr<Plugin>);
int connect_and_run (BufferSet& bufs,
samplepos_t start, samplepos_t end, double speed,
ChanMapping const& in, ChanMapping const& out,

View File

@ -60,6 +60,16 @@ DEF_CLASS_IID (Vst::IUnitData)
DEF_CLASS_IID (Vst::IUnitInfo)
DEF_CLASS_IID (Vst::ChannelContext::IInfoListener)
DEF_CLASS_IID (Presonus::IContextInfoProvider)
DEF_CLASS_IID (Presonus::IContextInfoProvider2)
DEF_CLASS_IID (Presonus::IContextInfoProvider3)
DEF_CLASS_IID (Presonus::IContextInfoHandler)
DEF_CLASS_IID (Presonus::IContextInfoHandler2)
DEF_CLASS_IID (Presonus::IEditControllerExtra)
DEF_CLASS_IID (Presonus::ISlaveControllerHandler)
DEF_CLASS_IID (Presonus::IPlugInViewEmbedding)
DEF_CLASS_IID (Presonus::IPlugInViewScaling)
#if SMTG_OS_LINUX
DEF_CLASS_IID (Linux::IRunLoop);
#endif

View File

@ -183,6 +183,15 @@ VST3Plugin::designated_bypass_port ()
return _plug->designated_bypass_port ();
}
void
VST3Plugin::set_automation_control (uint32_t port, boost::shared_ptr<ARDOUR::AutomationControl> ac)
{
if (!ac->alist () || !_plug->subscribe_to_automation_changes ()) {
return;
}
ac->alist()->automation_state_changed.connect_same_thread (_connections, boost::bind (&VST3PI::automation_state_changed, _plug, port, _1, boost::weak_ptr<AutomationList> (ac->alist ())));
}
std::set<Evoral::Parameter>
VST3Plugin::automatable () const
{
@ -543,6 +552,24 @@ VST3Plugin::configure_io (ChanCount in, ChanCount out)
return Plugin::configure_io (in, out);
}
void
VST3Plugin::add_slave (boost::shared_ptr<Plugin> p, bool rt)
{
boost::shared_ptr<VST3Plugin> vst = boost::dynamic_pointer_cast<VST3Plugin> (p);
if (vst) {
_plug->add_slave (vst->_plug->conroller (), rt);
}
}
void
VST3Plugin::remove_slave (boost::shared_ptr<Plugin> p)
{
boost::shared_ptr<VST3Plugin> vst = boost::dynamic_pointer_cast<VST3Plugin> (p);
if (vst) {
_plug->remove_slave (vst->_plug->conroller ());
}
}
int
VST3Plugin::connect_and_run (BufferSet& bufs,
samplepos_t start, samplepos_t end, double speed,
@ -1564,6 +1591,12 @@ VST3PI::get_parameter_descriptor (uint32_t port, ParameterDescriptor& desc) cons
} else if (p.unit == "Hz") {
desc.unit = ARDOUR::ParameterDescriptor::HZ;
}
FUnknownPtr<Presonus::IEditControllerExtra> extra_ctrl (_controller);
if (extra_ctrl) {
int32 flags = extra_ctrl->getParamExtraFlags (id);
desc.inline_ctrl = (flags & Presonus::kParamFlagMicroEdit) ? true : false;
}
}
std::string
@ -2325,6 +2358,72 @@ VST3PI::setup_info_listener ()
stripable_property_changed (PropertyChange ());
}
/* ****************************************************************************
* PSL Extensions
*/
bool
VST3PI::add_slave (Vst::IEditController* c, bool rt)
{
FUnknownPtr<Presonus::ISlaveControllerHandler> slave_ctrl (_controller);
if (slave_ctrl) {
return slave_ctrl->addSlave (c, rt ? Presonus::kSlaveModeLowLatencyClone : Presonus::kSlaveModeNormal) == kResultOk;
}
return false;
}
bool
VST3PI::remove_slave (Vst::IEditController* c)
{
FUnknownPtr<Presonus::ISlaveControllerHandler> slave_ctrl (_controller);
if (slave_ctrl) {
return slave_ctrl->removeSlave (c) == kResultOk;
}
return false;
}
bool
VST3PI::subscribe_to_automation_changes () const
{
FUnknownPtr<Presonus::IEditControllerExtra> extra_ctrl (_controller);
return 0 != extra_ctrl ? true : false;
}
void
VST3PI::automation_state_changed (uint32_t port, AutoState s, boost::weak_ptr <AutomationList> wal)
{
Vst::ParamID id (index_to_id (port));
boost::shared_ptr<AutomationList> al = wal.lock ();
FUnknownPtr<Presonus::IEditControllerExtra> extra_ctrl (_controller);
assert (extra_ctrl);
Presonus::AutomationMode am;
switch (s) {
case ARDOUR::Off:
if (!al || al->empty ()) {
am = Presonus::kAutomationNone;
} else {
am = Presonus::kAutomationOff;
}
break;
case Write:
am = Presonus::kAutomationWrite;
break;
case Touch:
am = Presonus::kAutomationTouch;
break;
case Play:
am = Presonus::kAutomationRead;
break;
case Latch:
am = Presonus::kAutomationLatch;
break;
default:
assert (0);
}
extra_ctrl->setParamAutomationMode (id, am);
}
/* ****************************************************************************
* GUI
*/