Show I/O Plugins on Recorder Page

This commit is contained in:
Robin Gareus 2022-05-17 02:25:58 +02:00
parent 5c85695362
commit c10c3ed64f
No known key found for this signature in database
GPG key ID: A090BCE02CF57F04
2 changed files with 175 additions and 24 deletions

View file

@ -31,6 +31,7 @@
#include "ardour/audioengine.h" #include "ardour/audioengine.h"
#include "ardour/audio_port.h" #include "ardour/audio_port.h"
#include "ardour/audio_track.h" #include "ardour/audio_track.h"
#include "ardour/io_plug.h"
#include "ardour/midi_port.h" #include "ardour/midi_port.h"
#include "ardour/midi_track.h" #include "ardour/midi_track.h"
#include "ardour/monitor_return.h" #include "ardour/monitor_return.h"
@ -430,6 +431,7 @@ RecorderUI::set_session (Session* s)
_session->EndTimeChanged.connect (_session_connections, invalidator (*this), boost::bind (&RecorderUI::gui_extents_changed, this), gui_context()); _session->EndTimeChanged.connect (_session_connections, invalidator (*this), boost::bind (&RecorderUI::gui_extents_changed, this), gui_context());
_session->RecordStateChanged.connect (_session_connections, invalidator (*this), boost::bind (&RecorderUI::update_sensitivity, this), gui_context()); _session->RecordStateChanged.connect (_session_connections, invalidator (*this), boost::bind (&RecorderUI::update_sensitivity, this), gui_context());
_session->UpdateRouteRecordState.connect (_session_connections, invalidator (*this), boost::bind (&RecorderUI::update_recordstate, this), gui_context()); _session->UpdateRouteRecordState.connect (_session_connections, invalidator (*this), boost::bind (&RecorderUI::update_recordstate, this), gui_context());
_session->IOPluginsChanged.connect (_session_connections, invalidator (*this), boost::bind (&RecorderUI::io_plugins_changed, this), gui_context());
/* map_parameters */ /* map_parameters */
parameter_changed ("show-group-tabs"); parameter_changed ("show-group-tabs");
@ -556,13 +558,23 @@ RecorderUI::start_updating ()
PortManager::AudioInputPorts const aip (AudioEngine::instance ()->audio_input_ports ()); PortManager::AudioInputPorts const aip (AudioEngine::instance ()->audio_input_ports ());
PortManager::MIDIInputPorts const mip (AudioEngine::instance ()->midi_input_ports ()); PortManager::MIDIInputPorts const mip (AudioEngine::instance ()->midi_input_ports ());
if (aip.size () + mip.size () == 0) { size_t iop_audio = 0;
size_t iop_midi = 0;
boost::shared_ptr<IOPlugList> iop (_session->io_plugs ());
for (auto& p : *iop) {
PortManager::AudioInputPorts const& aip (p->audio_input_ports ());
PortManager::MIDIInputPorts const& mip (p->midi_input_ports ());
iop_audio += aip.size ();
iop_midi += mip.size ();
}
if (aip.size () + mip.size () + iop_audio + iop_midi == 0) {
return; return;
} }
switch (UIConfiguration::instance ().get_input_meter_layout ()) { switch (UIConfiguration::instance ().get_input_meter_layout ()) {
case LayoutAutomatic: case LayoutAutomatic:
if (aip.size () + mip.size () > 16) { if (aip.size () + mip.size () + iop_audio + iop_midi > 16) {
_vertical = true; _vertical = true;
} else { } else {
_vertical = false; _vertical = false;
@ -592,6 +604,10 @@ RecorderUI::start_updating ()
set_connections (i->first); set_connections (i->first);
} }
for (auto& p : *iop) {
io_plugin_add (p);
}
update_io_widget_labels (); update_io_widget_labels ();
meter_area_layout (); meter_area_layout ();
_meter_area.queue_resize (); _meter_area.queue_resize ();
@ -620,6 +636,8 @@ RecorderUI::stop_updating ()
_monitor_connection.disconnect (); _monitor_connection.disconnect ();
container_clear (_meter_table); container_clear (_meter_table);
_input_ports.clear (); _input_ports.clear ();
_ioplugins.clear ();
_going_away_connections.drop_connections ();
} }
void void
@ -650,6 +668,69 @@ RecorderUI::add_or_remove_io (DataType dt, vector<string> ports, bool add)
} }
} }
post_add_remove (spill_changed);
}
void
RecorderUI::io_plugins_changed ()
{
_fast_screen_update_connection.disconnect ();
boost::shared_ptr<IOPlugList> iop (_session->io_plugs ());
for (auto& p : *iop) {
if (_ioplugins.find (p) != _ioplugins.end ()) {
continue;
}
io_plugin_add (p);
}
post_add_remove (false);
}
void
RecorderUI::io_plugin_add (boost::shared_ptr<IOPlug> p)
{
PortManager::AudioInputPorts const& aip (p->audio_input_ports ());
PortManager::MIDIInputPorts const& mip (p->midi_input_ports ());
_ioplugins.insert (p);
p->DropReferences.connect (_going_away_connections, invalidator (*this), boost::bind (&RecorderUI::io_plugin_going_away, this, boost::weak_ptr<IOPlug>(p)), gui_context ());
for (auto i = aip.begin (); i != aip.end (); ++i) {
_input_ports[i->first] = boost::shared_ptr<RecorderUI::InputPort> (new InputPort (i->first, DataType::AUDIO, this, _vertical, true));
set_connections (i->first);
}
for (auto i = mip.begin (); i != mip.end (); ++i) {
_input_ports[i->first] = boost::shared_ptr<RecorderUI::InputPort> (new InputPort (i->first, DataType::MIDI, this, _vertical, true));
set_connections (i->first);
}
}
void
RecorderUI::io_plugin_going_away (boost::weak_ptr<IOPlug> wp)
{
_fast_screen_update_connection.disconnect ();
bool spill_changed = false;
boost::shared_ptr<IOPlug> p = wp.lock ();
if (!p) {
assert (0);
return;
}
PortManager::AudioInputPorts const& aip (p->audio_input_ports ());
PortManager::MIDIInputPorts const& mip (p->midi_input_ports ());
for (auto i = aip.begin (); i != aip.end (); ++i) {
_input_ports.erase (i->first);
spill_changed |= 0 != _spill_port_names.erase (i->first);
}
for (auto i = mip.begin (); i != mip.end (); ++i) {
_input_ports.erase (i->first);
spill_changed |= 0 != _spill_port_names.erase (i->first);
}
_ioplugins.erase (p);
post_add_remove (spill_changed);
}
void
RecorderUI::post_add_remove (bool spill_changed)
{
update_io_widget_labels (); update_io_widget_labels ();
update_sensitivity (); update_sensitivity ();
meter_area_layout (); meter_area_layout ();
@ -669,6 +750,8 @@ RecorderUI::update_io_widget_labels ()
{ {
uint32_t n_audio = 0; uint32_t n_audio = 0;
uint32_t n_midi = 0; uint32_t n_midi = 0;
uint32_t n_io_audio = 0;
uint32_t n_io_midi = 0;
InputPortSet ips; InputPortSet ips;
for (InputPortMap::const_iterator i = _input_ports.begin (); i != _input_ports.end (); ++i) { for (InputPortMap::const_iterator i = _input_ports.begin (); i != _input_ports.end (); ++i) {
@ -676,6 +759,16 @@ RecorderUI::update_io_widget_labels ()
} }
for (InputPortSet::const_iterator i = ips.begin (); i != ips.end (); ++i) { for (InputPortSet::const_iterator i = ips.begin (); i != ips.end (); ++i) {
boost::shared_ptr<InputPort> const& ip = *i; boost::shared_ptr<InputPort> const& ip = *i;
if (ip->ioplug ()) {
switch (ip->data_type ()) {
case DataType::AUDIO:
ip->set_frame_label (string_compose (_("I/O Plugin Audio %1"), ++n_io_audio));
break;
case DataType::MIDI:
ip->set_frame_label (string_compose (_("I/O Plugin MIDI %1"), ++n_io_midi));
break;
}
} else {
switch (ip->data_type ()) { switch (ip->data_type ()) {
case DataType::AUDIO: case DataType::AUDIO:
ip->set_frame_label (string_compose (_("Audio Input %1"), ++n_audio)); ip->set_frame_label (string_compose (_("Audio Input %1"), ++n_audio));
@ -686,11 +779,13 @@ RecorderUI::update_io_widget_labels ()
} }
} }
} }
}
bool bool
RecorderUI::update_meters () RecorderUI::update_meters ()
{ {
PortManager::AudioInputPorts const aip (AudioEngine::instance ()->audio_input_ports ()); PortManager::AudioInputPorts const aip (AudioEngine::instance ()->audio_input_ports ());
boost::shared_ptr<IOPlugList> iop (_session->io_plugs ());
/* scope data needs to be read continuously */ /* scope data needs to be read continuously */
for (PortManager::AudioInputPorts::const_iterator i = aip.begin (); i != aip.end (); ++i) { for (PortManager::AudioInputPorts::const_iterator i = aip.begin (); i != aip.end (); ++i) {
@ -700,6 +795,16 @@ RecorderUI::update_meters ()
} }
} }
for (auto& p : *iop) {
PortManager::AudioInputPorts const& aip (p->audio_input_ports ());
for (auto i = aip.begin (); i != aip.end (); ++i) {
InputPortMap::iterator im = _input_ports.find (i->first);
if (im != _input_ports.end()) {
im->second->update (*(i->second.scope));
}
}
}
if (!contents ().get_mapped ()) { if (!contents ().get_mapped ()) {
return true; return true;
} }
@ -720,6 +825,24 @@ RecorderUI::update_meters ()
} }
} }
for (auto& p : *iop) {
PortManager::AudioInputPorts const& aip (p->audio_input_ports ());
PortManager::MIDIInputPorts const& mip (p->midi_input_ports ());
for (auto i = aip.begin (); i != aip.end (); ++i) {
InputPortMap::iterator im = _input_ports.find (i->first);
if (im != _input_ports.end()) {
im->second->update (accurate_coefficient_to_dB (i->second.meter->level), accurate_coefficient_to_dB (i->second.meter->peak));
}
}
for (PortManager::MIDIInputPorts::const_iterator i = mip.begin (); i != mip.end (); ++i) {
InputPortMap::iterator im = _input_ports.find (i->first);
if (im != _input_ports.end()) {
im->second->update ((float const*)i->second.meter->chn_active);
im->second->update (*(i->second.monitor));
}
}
}
for (list<TrackRecordAxis*>::const_iterator i = _recorders.begin (); i != _recorders.end (); ++i) { for (list<TrackRecordAxis*>::const_iterator i = _recorders.begin (); i != _recorders.end (); ++i) {
(*i)->fast_update (); (*i)->fast_update ();
} }
@ -1215,6 +1338,9 @@ void
RecorderUI::peak_reset () RecorderUI::peak_reset ()
{ {
AudioEngine::instance ()->reset_input_meters (); AudioEngine::instance ()->reset_input_meters ();
for (auto& p : _ioplugins) {
p->reset_input_meters ();
}
} }
/* ****************************************************************************/ /* ****************************************************************************/
@ -1225,7 +1351,7 @@ Glib::RefPtr<Gtk::SizeGroup> RecorderUI::InputPort::_name_size_group;
Glib::RefPtr<Gtk::SizeGroup> RecorderUI::InputPort::_ctrl_size_group; Glib::RefPtr<Gtk::SizeGroup> RecorderUI::InputPort::_ctrl_size_group;
Glib::RefPtr<Gtk::SizeGroup> RecorderUI::InputPort::_monitor_size_group; Glib::RefPtr<Gtk::SizeGroup> RecorderUI::InputPort::_monitor_size_group;
RecorderUI::InputPort::InputPort (string const& name, DataType dt, RecorderUI* parent, bool vertical) RecorderUI::InputPort::InputPort (string const& name, DataType dt, RecorderUI* parent, bool vertical, bool ioplug)
: _dt (dt) : _dt (dt)
, _monitor (dt, AudioEngine::instance()->sample_rate (), vertical ? InputPortMonitor::Vertical : InputPortMonitor::Horizontal) , _monitor (dt, AudioEngine::instance()->sample_rate (), vertical ? InputPortMonitor::Vertical : InputPortMonitor::Horizontal)
, _alignment (0.5, 0.5, 0, 0) , _alignment (0.5, 0.5, 0, 0)
@ -1236,6 +1362,7 @@ RecorderUI::InputPort::InputPort (string const& name, DataType dt, RecorderUI* p
, _name_label ("", ALIGN_CENTER, ALIGN_CENTER, false) , _name_label ("", ALIGN_CENTER, ALIGN_CENTER, false)
, _add_button ("+") , _add_button ("+")
, _port_name (name) , _port_name (name)
, _ioplug (ioplug)
, _solo_release (0) , _solo_release (0)
{ {
if (!_size_groups_initialized) { if (!_size_groups_initialized) {
@ -1275,7 +1402,10 @@ RecorderUI::InputPort::InputPort (string const& name, DataType dt, RecorderUI* p
_name_button.set_corner_radius (2); _name_button.set_corner_radius (2);
_name_button.set_name ("generic button"); _name_button.set_name ("generic button");
_name_button.set_text_ellipsize (Pango::ELLIPSIZE_MIDDLE); _name_button.set_text_ellipsize (Pango::ELLIPSIZE_MIDDLE);
if (!_ioplug) {
_name_button.signal_clicked.connect (sigc::mem_fun (*this, &RecorderUI::InputPort::rename_port)); _name_button.signal_clicked.connect (sigc::mem_fun (*this, &RecorderUI::InputPort::rename_port));
}
_name_label.set_ellipsize (Pango::ELLIPSIZE_MIDDLE); _name_label.set_ellipsize (Pango::ELLIPSIZE_MIDDLE);
@ -1321,7 +1451,11 @@ RecorderUI::InputPort::InputPort (string const& name, DataType dt, RecorderUI* p
_monitor_size_group->add_widget (_monitor); _monitor_size_group->add_widget (_monitor);
Gdk::Color bg; Gdk::Color bg;
if (_ioplug) {
ARDOUR_UI_UTILS::set_color_from_rgba (bg, UIConfiguration::instance ().color ("neutral:background"));
} else {
ARDOUR_UI_UTILS::set_color_from_rgba (bg, UIConfiguration::instance ().color ("neutral:background2")); ARDOUR_UI_UTILS::set_color_from_rgba (bg, UIConfiguration::instance ().color ("neutral:background2"));
}
_frame.modify_bg (Gtk::STATE_NORMAL, bg); _frame.modify_bg (Gtk::STATE_NORMAL, bg);
/* top level packing with border */ /* top level packing with border */
@ -1432,8 +1566,12 @@ RecorderUI::InputPort::setup_name ()
_name_button.set_text (_port_name); _name_button.set_text (_port_name);
_name_label.set_text (""); _name_label.set_text ("");
} }
if (_ioplug) {
set_tooltip (_name_button, string_compose (_("I/O Plugin input port '%1'"), _port_name));
} else {
set_tooltip (_name_button, string_compose (_("Set or edit the custom name for input port '%1'"), _port_name)); set_tooltip (_name_button, string_compose (_("Set or edit the custom name for input port '%1'"), _port_name));
} }
}
void void
RecorderUI::InputPort::rename_port () RecorderUI::InputPort::rename_port ()
@ -1493,7 +1631,7 @@ RecorderUI::InputPort::spilled () const
void void
RecorderUI::InputPort::allow_monitoring (bool en) RecorderUI::InputPort::allow_monitoring (bool en)
{ {
if (_dt != DataType::AUDIO) { if (_dt != DataType::AUDIO || _ioplug) {
en = false; en = false;
} }
if (!en && _monitor_button.get_active ()) { if (!en && _monitor_button.get_active ()) {

View file

@ -51,6 +51,7 @@
namespace ARDOUR { namespace ARDOUR {
class SoloMuteRelease; class SoloMuteRelease;
class IOPlug;
} }
class TrackRecordAxis; class TrackRecordAxis;
@ -87,6 +88,10 @@ private:
void stop_updating (); void stop_updating ();
bool update_meters (); bool update_meters ();
void add_or_remove_io (ARDOUR::DataType, std::vector<std::string>, bool); void add_or_remove_io (ARDOUR::DataType, std::vector<std::string>, bool);
void io_plugins_changed ();
void io_plugin_add (boost::shared_ptr<ARDOUR::IOPlug>);
void io_plugin_going_away (boost::weak_ptr<ARDOUR::IOPlug>);
void post_add_remove (bool);
void update_io_widget_labels (); void update_io_widget_labels ();
void initial_track_display (); void initial_track_display ();
@ -157,11 +162,6 @@ private:
std::set<std::string> _spill_port_names; std::set<std::string> _spill_port_names;
sigc::connection _fast_screen_update_connection;
sigc::connection _ruler_width_update_connection;
PBD::ScopedConnectionList _engine_connections;
PBD::ScopedConnection _monitor_connection;
class RecRuler : public CairoWidget , public ARDOUR::SessionHandlePtr class RecRuler : public CairoWidget , public ARDOUR::SessionHandlePtr
{ {
public: public:
@ -188,7 +188,7 @@ private:
class InputPort : public Gtk::EventBox class InputPort : public Gtk::EventBox
{ {
public: public:
InputPort (std::string const&, ARDOUR::DataType, RecorderUI*, bool vertical = false); InputPort (std::string const&, ARDOUR::DataType, RecorderUI*, bool vertical = false, bool ioplug = false);
~InputPort (); ~InputPort ();
void set_frame_label (std::string const&); void set_frame_label (std::string const&);
@ -201,6 +201,7 @@ private:
void update_rec_stat (); void update_rec_stat ();
ARDOUR::DataType data_type () const; ARDOUR::DataType data_type () const;
bool ioplug () const { return _ioplug; }
std::string const& name () const; std::string const& name () const;
void update (float, float); // FastMeter void update (float, float); // FastMeter
@ -210,6 +211,9 @@ private:
void clear (); void clear ();
bool operator< (InputPort const& o) const { bool operator< (InputPort const& o) const {
if (_ioplug != o._ioplug) {
return !_ioplug;
}
if (_dt == o._dt) { if (_dt == o._dt) {
return PBD::naturally_less (_port_name.c_str (), o._port_name.c_str ()); return PBD::naturally_less (_port_name.c_str (), o._port_name.c_str ());
} }
@ -231,6 +235,7 @@ private:
Gtk::Label _name_label; Gtk::Label _name_label;
ArdourWidgets::ArdourButton _add_button; ArdourWidgets::ArdourButton _add_button;
std::string _port_name; std::string _port_name;
bool _ioplug;
ARDOUR::WeakRouteList _connected_routes; ARDOUR::WeakRouteList _connected_routes;
ARDOUR::SoloMuteRelease* _solo_release; ARDOUR::SoloMuteRelease* _solo_release;
@ -248,6 +253,7 @@ private:
typedef std::map<std::string, boost::shared_ptr<InputPort> > InputPortMap; typedef std::map<std::string, boost::shared_ptr<InputPort> > InputPortMap;
typedef std::set<boost::shared_ptr<InputPort>, InputPortPtrSort> InputPortSet; typedef std::set<boost::shared_ptr<InputPort>, InputPortPtrSort> InputPortSet;
typedef std::set<boost::shared_ptr<ARDOUR::IOPlug>> IOPlugSet;
RecRuler _ruler; RecRuler _ruler;
Gtk::EventBox _space; Gtk::EventBox _space;
@ -258,6 +264,13 @@ private:
InputPortMap _input_ports; InputPortMap _input_ports;
std::list<TrackRecordAxis*> _recorders; std::list<TrackRecordAxis*> _recorders;
std::list<TrackRecordAxis*> _visible_recorders; std::list<TrackRecordAxis*> _visible_recorders;
IOPlugSet _ioplugins;
sigc::connection _fast_screen_update_connection;
sigc::connection _ruler_width_update_connection;
PBD::ScopedConnectionList _engine_connections;
PBD::ScopedConnection _monitor_connection;
PBD::ScopedConnectionList _going_away_connections;
public: public:
/* only for RecorderGroupTab */ /* only for RecorderGroupTab */