This commit is contained in:
Holger Dehnhardt 2025-12-04 08:31:40 -05:00 committed by GitHub
commit 040dd85d52
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
10 changed files with 1226 additions and 606 deletions

View file

@ -4,66 +4,146 @@
#include "ardour/debug.h" #include "ardour/debug.h"
#include "console1.h" #include "console1.h"
namespace ArdourSurface { namespace Console1
{
using ControllerID = Console1::ControllerID; using ControllerID = Console1::ControllerID;
class Controller class Controller
{ {
public: public:
enum ControllerType
{
CONTROLLER,
CONTROLLER_BUTTON,
MULTISTATE_BUTTON,
ENCODER,
METER
};
Controller (Console1* console1, ControllerID id) Controller (Console1* console1, ControllerID id)
: console1 (console1) : console1 (console1)
, _id (id) , _id (id)
{ {
} }
virtual ~Controller () {} Controller (Console1* console1,
ControllerID id,
std::function<void (uint32_t)> action,
std::function<void (uint32_t)> shift_action = 0,
std::function<void (uint32_t)> plugin_action = 0,
std::function<void (uint32_t)> plugin_shift_action = 0)
: console1 (console1)
, _id (id)
, action (action)
, shift_action (shift_action)
, plugin_action (plugin_action)
, plugin_shift_action (plugin_shift_action)
{
}
Console1* console1; virtual ~Controller ()
ControllerID id () const { return _id; } {
}
virtual ControllerType get_type () { return CONTROLLER; } Console1* console1;
ControllerID id () const
{
return _id;
}
protected: virtual void clear_value() {}
ControllerID _id;
virtual ControllerType get_type ()
{
return CONTROLLER;
}
void set_action (std::function<void (uint32_t)> new_action)
{
action = new_action;
}
void set_plugin_action (std::function<void (uint32_t)> new_action)
{
plugin_action = new_action;
}
void set_plugin_shift_action (std::function<void (uint32_t)> new_action)
{
plugin_shift_action = new_action;
}
std::function<void (uint32_t)> get_action (){
return action;
}
std::function<void (uint32_t)> get_shift_action ()
{
return shift_action;
}
std::function<void (uint32_t)> get_plugin_action ()
{
return plugin_action;
}
std::function<void (uint32_t)> get_plugin_shift_action ()
{
return plugin_shift_action;
}
protected:
ControllerID _id;
std::function<void (uint32_t)> action;
std::function<void (uint32_t)> shift_action;
std::function<void (uint32_t)> plugin_action;
std::function<void (uint32_t)> plugin_shift_action;
};
class Encoder : public Controller
{
public:
Encoder (Console1* console1,
ControllerID id,
std::function<void (uint32_t)> action,
std::function<void (uint32_t)> shift_action = 0,
std::function<void (uint32_t)> plugin_action = 0,
std::function<void (uint32_t)> plugin_shift_action = 0)
: Controller (console1, id, action, shift_action, plugin_action, plugin_shift_action)
{
console1->controllerMap.insert (std::make_pair (id, this));
}
ControllerType get_type ()
{
return ENCODER;
}
virtual void set_value (uint32_t value)
{
MIDI::byte buf[3];
buf[0] = 0xB0;
buf[1] = _id;
buf[2] = value;
console1->write (buf, 3);
}
PBD::Signal<void (uint32_t)>* plugin_signal;
}; };
class ControllerButton : public Controller class ControllerButton : public Controller
{ {
public: public:
ControllerButton (Console1* console1, ControllerButton (Console1* console1,
ControllerID id, ControllerID id,
std::function<void (uint32_t)> action, std::function<void (uint32_t)> action,
std::function<void (uint32_t)> shift_action = 0, std::function<void (uint32_t)> shift_action = 0,
std::function<void (uint32_t)> plugin_action = 0, std::function<void (uint32_t)> plugin_action = 0,
std::function<void (uint32_t)> plugin_shift_action = 0 ) std::function<void (uint32_t)> plugin_shift_action = 0)
: Controller (console1, id) : Controller (console1, id, action, shift_action, plugin_action, plugin_shift_action)
, action (action)
, shift_action (shift_action)
, plugin_action (plugin_action)
, plugin_shift_action (plugin_shift_action)
{ {
console1->buttons.insert (std::make_pair (id, this)); console1->controllerMap.insert (std::make_pair (id, this));
} }
ControllerType get_type () { return CONTROLLER_BUTTON; } ControllerType get_type ()
{
void set_action (std::function<void (uint32_t)> new_action) { action = new_action; } return CONTROLLER_BUTTON;
void set_plugin_action (std::function<void (uint32_t)> new_action) { plugin_action = new_action; } }
void set_plugin_shift_action (std::function<void (uint32_t)> new_action) { plugin_shift_action = new_action; }
virtual void set_led_state (bool onoff) virtual void set_led_state (bool onoff)
{ {
// DEBUG_TRACE(DEBUG::Console1, "ControllerButton::set_led_state ...\n");
MIDI::byte buf[3]; MIDI::byte buf[3];
buf[0] = 0xB0; buf[0] = 0xB0;
buf[1] = _id; buf[1] = _id;
@ -74,7 +154,6 @@ class ControllerButton : public Controller
virtual void set_led_value (uint32_t val) virtual void set_led_value (uint32_t val)
{ {
// DEBUG_TRACE(DEBUG::Console1, "ControllerButton::set_led_state ...\n");
MIDI::byte buf[3]; MIDI::byte buf[3];
buf[0] = 0xB0; buf[0] = 0xB0;
buf[1] = _id; buf[1] = _id;
@ -82,34 +161,28 @@ class ControllerButton : public Controller
console1->write (buf, 3); console1->write (buf, 3);
} }
std::function<void (uint32_t)> action;
std::function<void (uint32_t)> shift_action;
std::function<void (uint32_t)> plugin_action;
std::function<void (uint32_t)> plugin_shift_action;
}; };
class MultiStateButton : public Controller class MultiStateButton : public Controller
{ {
public: public:
MultiStateButton (Console1* console1, MultiStateButton (Console1* console1,
ControllerID id, ControllerID id,
std::vector<uint32_t> state_values, std::vector<uint32_t> state_values,
std::function<void (uint32_t)> action, std::function<void (uint32_t)> action,
std::function<void (uint32_t)> shift_action = 0, std::function<void (uint32_t)> shift_action = 0,
std::function<void (uint32_t)> plugin_action = 0, std::function<void (uint32_t)> plugin_action = 0,
std::function<void (uint32_t)> plugin_shift_action = 0 std::function<void (uint32_t)> plugin_shift_action = 0)
) : Controller (console1, id, action, shift_action, plugin_action, plugin_shift_action)
: Controller (console1, id) , state_values (state_values)
, action (action)
, shift_action (shift_action)
, plugin_action (action)
, plugin_shift_action (shift_action)
, state_values (state_values)
{ {
console1->multi_buttons.insert (std::make_pair (id, this)); console1->controllerMap.insert (std::make_pair (id, this));
} }
ControllerType get_type () { return MULTISTATE_BUTTON; } ControllerType get_type ()
{
return MULTISTATE_BUTTON;
}
virtual void set_led_state (uint32_t state) virtual void set_led_state (uint32_t state)
{ {
@ -123,36 +196,33 @@ class MultiStateButton : public Controller
console1->write (buf, 3); console1->write (buf, 3);
} }
void set_action (std::function<void (uint32_t)> new_action) { action = new_action; } uint32_t state_count ()
void set_plugin_action (std::function<void (uint32_t)> new_action) { plugin_action = new_action; } {
void set_plugin_shift_action (std::function<void (uint32_t)> new_action) { plugin_shift_action = new_action; } return state_values.size ();
}
uint32_t state_count () { return state_values.size (); } private:
std::function<void (uint32_t)> action;
std::function<void (uint32_t)> shift_action;
std::function<void (uint32_t)> plugin_action;
std::function<void (uint32_t)> plugin_shift_action;
private:
std::vector<uint32_t> state_values; std::vector<uint32_t> state_values;
}; };
class Meter : public Controller class Meter : public Controller
{ {
public: public:
Meter (Console1* console1, Meter (Console1* console1,
ControllerID id, ControllerID id,
std::function<void ()> action, std::function<void ()> action,
std::function<void ()> shift_action = 0) std::function<void ()> shift_action = 0)
: Controller (console1, id) : Controller (console1, id)
, action (action) , action (action)
, shift_action (shift_action) , shift_action (shift_action)
{ {
console1->meters.insert (std::make_pair (id, this)); console1->meters.insert (std::make_pair (id, this));
} }
ControllerType get_type () { return METER; } ControllerType get_type ()
{
return METER;
}
virtual void set_value (uint32_t value) virtual void set_value (uint32_t value)
{ {
@ -167,46 +237,6 @@ class Meter : public Controller
std::function<void ()> shift_action; std::function<void ()> shift_action;
}; };
class Encoder : public Controller } // namespace Console1
{
public:
Encoder (Console1* console1,
ControllerID id,
std::function<void (uint32_t)> action,
std::function<void (uint32_t)> shift_action = 0,
std::function<void (uint32_t)> plugin_action = 0,
std::function<void (uint32_t)> plugin_shift_action = 0)
: Controller (console1, id)
, action (action)
, shift_action (shift_action)
, plugin_action (plugin_action)
, plugin_shift_action (plugin_action)
{
console1->encoders.insert (std::make_pair (id, this));
}
ControllerType get_type () { return ENCODER; }
void set_action (std::function<void (uint32_t)> new_action) { action = new_action; }
void set_plugin_action (std::function<void (uint32_t)> new_action) { plugin_action = new_action; }
void set_plugin_shift_action (std::function<void (uint32_t)> new_action) { plugin_shift_action = new_action; }
virtual void set_value (uint32_t value)
{
MIDI::byte buf[3];
buf[0] = 0xB0;
buf[1] = _id;
buf[2] = value;
console1->write (buf, 3);
}
std::function<void (uint32_t)> action;
std::function<void (uint32_t val)> shift_action;
std::function<void (uint32_t val)> plugin_action;
std::function<void (uint32_t val)> plugin_shift_action;
PBD::Signal<void(uint32_t)>* plugin_signal;
};
}
#endif // ardour_surface_console1_button_h #endif // ardour_surface_console1_button_h

View file

@ -19,6 +19,7 @@
#include "c1_gui.h" #include "c1_gui.h"
#include <ytkmm/alignment.h> #include <ytkmm/alignment.h>
#include <ytkmm/combobox.h>
#include <ytkmm/label.h> #include <ytkmm/label.h>
#include <ytkmm/liststore.h> #include <ytkmm/liststore.h>
@ -32,24 +33,27 @@
#include "ardour/filesystem_paths.h" #include "ardour/filesystem_paths.h"
#include "ardour/parameter_descriptor.h" #include "ardour/parameter_descriptor.h"
#include "console1.h" #include "console1.h"
#include "gtkmm2ext/action_model.h"
#include "gtkmm2ext/bindings.h" #include "gtkmm2ext/bindings.h"
#include "gtkmm2ext/gui_thread.h" #include "gtkmm2ext/gui_thread.h"
#include "gtkmm2ext/utils.h" #include "gtkmm2ext/utils.h"
using namespace PBD; using namespace PBD;
using namespace ARDOUR; using namespace ARDOUR;
using namespace ArdourSurface;
using namespace std; using namespace std;
using namespace Gtk; using namespace Gtk;
using namespace Gtkmm2ext; using namespace Gtkmm2ext;
namespace Console1
{
void* void*
Console1::get_gui () const Console1::get_gui () const
{ {
if (!gui) { if (!gui) {
const_cast<Console1*> (this)->build_gui (); const_cast<Console1*> (this)->build_gui ();
} }
static_cast<Gtk::VBox*> (gui)->show_all (); static_cast<Gtk::Notebook*> (gui)->show_all ();
return gui; return gui;
} }
@ -57,7 +61,7 @@ void
Console1::tear_down_gui () Console1::tear_down_gui ()
{ {
if (gui) { if (gui) {
Gtk::Widget* w = static_cast<Gtk::VBox*> (gui)->get_parent (); Gtk::Widget* w = static_cast<Gtk::Widget*> (gui)->get_parent ();
if (w) { if (w) {
w->hide (); w->hide ();
delete w; delete w;
@ -113,19 +117,18 @@ C1GUI::C1GUI (Console1& p)
// swap_solo_mute (_ ("Swap Solo and Mute")); // swap_solo_mute (_ ("Swap Solo and Mute"));
swap_solo_mute_cb.set_tooltip_text ( swap_solo_mute_cb.set_tooltip_text (
_ ("If checked Ardour the mute and solo buttons are swept so they have the same order as in the GUI.")); _("If checked Ardour the mute and solo buttons are swept so they have the same order as in the GUI."));
swap_solo_mute_cb.set_active (p.swap_solo_mute); swap_solo_mute_cb.set_active (p.swap_solo_mute);
swap_solo_mute_cb.signal_toggled ().connect (sigc::mem_fun (*this, &C1GUI::set_swap_solo_mute)); swap_solo_mute_cb.signal_toggled ().connect (sigc::mem_fun (*this, &C1GUI::set_swap_solo_mute));
#ifdef MIXBUS #ifdef MIXBUS
// before the ssl strips, the q knobs for low- and high mids where alwas used as sends, now this can be toggled // before the ssl strips, the q knobs for low- and high mids where always used as sends, now this can be toggled
band_q_as_send_cb.set_tooltip_text ( band_q_as_send_cb.set_tooltip_text (
_ ("If checked Ardour the Q-Factor knobs for Low and High are used as sends for Send 11 and send 12.")); _("If checked Ardour the Q-Factor knobs for Low and High are used as sends for Send 11 and send 12."));
band_q_as_send_cb.set_active (p.band_q_as_send); band_q_as_send_cb.set_active (p.band_q_as_send);
band_q_as_send_cb.signal_toggled ().connect (sigc::mem_fun (*this, &C1GUI::set_band_q_as_send)); band_q_as_send_cb.signal_toggled ().connect (sigc::mem_fun (*this, &C1GUI::set_band_q_as_send));
#endif #endif
// create_plugin_stubs (_ ("Create Plugin Mapping Stubs")); create_plugin_stubs_btn.set_tooltip_text (_("If checked a mapping stub is created for every unknown plugin."));
create_plugin_stubs_btn.set_tooltip_text (_ ("If checked a mapping stub is created for every unknown plugin."));
create_plugin_stubs_btn.set_active (p.create_mapping_stubs); create_plugin_stubs_btn.set_active (p.create_mapping_stubs);
create_plugin_stubs_btn.signal_toggled ().connect (sigc::mem_fun (*this, &C1GUI::set_create_mapping_stubs)); create_plugin_stubs_btn.signal_toggled ().connect (sigc::mem_fun (*this, &C1GUI::set_create_mapping_stubs));
@ -137,14 +140,14 @@ C1GUI::C1GUI (Console1& p)
row++; row++;
l = manage (new Gtk::Label); l = manage (new Gtk::Label);
l->set_markup (string_compose ("<span weight=\"bold\">%1</span>", _ ("Outgoing MIDI on:"))); l->set_markup (string_compose ("<span weight=\"bold\">%1</span>", _("Outgoing MIDI on:")));
l->set_alignment (1.0, 0.5); l->set_alignment (1.0, 0.5);
table.attach (*l, 0, 1, row, row + 1, AttachOptions (FILL | EXPAND), AttachOptions (0)); table.attach (*l, 0, 1, row, row + 1, AttachOptions (FILL | EXPAND), AttachOptions (0));
table.attach (output_combo, 1, 2, row, row + 1, AttachOptions (FILL | EXPAND), AttachOptions (0), 0, 0); table.attach (output_combo, 1, 2, row, row + 1, AttachOptions (FILL | EXPAND), AttachOptions (0), 0, 0);
row++; row++;
l = manage (new Gtk::Label); l = manage (new Gtk::Label);
l->set_markup (string_compose ("<span weight=\"bold\">%1</span>", _ ("Swap Solo and Mute:"))); l->set_markup (string_compose ("<span weight=\"bold\">%1</span>", _("Swap Solo and Mute:")));
l->set_alignment (1.0, 0.5); l->set_alignment (1.0, 0.5);
table.attach (*l, 0, 1, row, row + 1, AttachOptions (FILL | EXPAND), AttachOptions (0)); table.attach (*l, 0, 1, row, row + 1, AttachOptions (FILL | EXPAND), AttachOptions (0));
table.attach (swap_solo_mute_cb, 1, 2, row, row + 1); table.attach (swap_solo_mute_cb, 1, 2, row, row + 1);
@ -152,7 +155,7 @@ C1GUI::C1GUI (Console1& p)
#ifdef MIXBUS #ifdef MIXBUS
l = manage (new Gtk::Label); l = manage (new Gtk::Label);
l->set_markup (string_compose ("<span weight=\"bold\">%1</span>", _ ("Use Mid-Q Buttons as send 11/12:"))); l->set_markup (string_compose ("<span weight=\"bold\">%1</span>", _("Use Mid-Q Buttons as send 11/12:")));
l->set_alignment (1.0, 0.5); l->set_alignment (1.0, 0.5);
table.attach (*l, 0, 1, row, row + 1, AttachOptions (FILL | EXPAND), AttachOptions (0)); table.attach (*l, 0, 1, row, row + 1, AttachOptions (FILL | EXPAND), AttachOptions (0));
table.attach (band_q_as_send_cb, 1, 2, row, row + 1); table.attach (band_q_as_send_cb, 1, 2, row, row + 1);
@ -160,33 +163,45 @@ C1GUI::C1GUI (Console1& p)
#endif #endif
l = manage (new Gtk::Label); l = manage (new Gtk::Label);
l->set_markup (string_compose ("<span weight=\"bold\">%1</span>", _ ("Create Plugin Mapping Stubs:"))); l->set_markup (string_compose ("<span weight=\"bold\">%1</span>", _("Create Plugin Mapping Stubs:")));
l->set_alignment (1.0, 0.5); l->set_alignment (1.0, 0.5);
table.attach (*l, 0, 1, row, row + 1, AttachOptions (FILL | EXPAND), AttachOptions (0)); table.attach (*l, 0, 1, row, row + 1, AttachOptions (FILL | EXPAND), AttachOptions (0));
table.attach (create_plugin_stubs_btn, 1, 2, row, row + 1); table.attach (create_plugin_stubs_btn, 1, 2, row, row + 1);
row++; row++;
hpacker.pack_start (table, true, true); hpacker.pack_start (table, true, true);
append_page (hpacker, _("Device Setup"));
hpacker.show_all();
set_spacing (12); // Create the page for plugin mappings
p.load_mappings ();
pack_start (hpacker, false, false); VBox* plugconfig_packer = build_plugin_assignment_page();
/* update the port connection combos */ append_page (*plugconfig_packer, _("Plugin Mappings"));
plugconfig_packer->show_all ();
update_port_combos (); /* update the port connection combos */
/* catch future changes to connection state */ update_port_combos ();
ARDOUR::AudioEngine::instance ()->PortRegisteredOrUnregistered.connect ( /* catch future changes to connection state */
_port_connections, invalidator (*this), std::bind (&C1GUI::connection_handler, this), gui_context ());
ARDOUR::AudioEngine::instance ()->PortPrettyNameChanged.connect ( ARDOUR::AudioEngine::instance ()->PortRegisteredOrUnregistered.connect (
_port_connections, invalidator (*this), std::bind (&C1GUI::connection_handler, this), gui_context ()); port_connections, invalidator (*this), std::bind (&C1GUI::connection_handler, this), gui_context ());
c1.ConnectionChange.connect ( ARDOUR::AudioEngine::instance ()->PortPrettyNameChanged.connect (
_port_connections, invalidator (*this), std::bind (&C1GUI::connection_handler, this), gui_context ()); port_connections, invalidator (*this), std::bind (&C1GUI::connection_handler, this), gui_context ());
c1.ConnectionChange.connect (
port_connections, invalidator (*this), std::bind (&C1GUI::connection_handler, this), gui_context ());
c1.PluginStubAdded.connect (
plugin_connections, invalidator (*this), std::bind (&C1GUI::load_plugin_combo_rows, this), gui_context ());
} }
C1GUI::~C1GUI () {} C1GUI::~C1GUI () {
DEBUG_TRACE (DEBUG::Console1, "1GUI::~C1GUI ()\n");
c1.midi_assign_mode = false;
}
void void
C1GUI::set_swap_solo_mute () C1GUI::set_swap_solo_mute ()
@ -287,7 +302,7 @@ C1GUI::build_midi_port_list (vector<string> const& ports, bool for_input)
row = *store->append (); row = *store->append ();
row[midi_port_columns.full_name] = string (); row[midi_port_columns.full_name] = string ();
row[midi_port_columns.short_name] = _ ("Disconnected"); row[midi_port_columns.short_name] = _("Disconnected");
for (vector<string>::const_iterator p = ports.begin (); p != ports.end (); ++p) { for (vector<string>::const_iterator p = ports.begin (); p != ports.end (); ++p) {
row = *store->append (); row = *store->append ();
@ -334,3 +349,6 @@ C1GUI::active_port_changed (Gtk::ComboBox* combo, bool for_input)
} }
} }
} }
} // namespace Console1

View file

@ -23,47 +23,62 @@
#include <string> #include <string>
#include <ytkmm/box.h> #include <ytkmm/box.h>
#include <ytkmm/combobox.h>
#include <ytkmm/checkbutton.h> #include <ytkmm/checkbutton.h>
#include <ytkmm/combobox.h>
#include <ytkmm/cellrenderercombo.h>
#include <ytkmm/image.h> #include <ytkmm/image.h>
#include <ytkmm/table.h> #include <ytkmm/table.h>
#include <ytkmm/treestore.h> #include <ytkmm/treestore.h>
#include <ytkmm/scrolledwindow.h>
#include <ytkmm/spinbutton.h> #include <ytkmm/spinbutton.h>
#include <ytkmm/notebook.h> #include <ytkmm/notebook.h>
namespace Gtk { namespace Gtk {
class CellRendererCombo; class ListStore;
class ListStore; }
namespace ActionManager {
class ActionModel;
} }
#include "ardour/mode.h" #include "ardour/mode.h"
#include "console1.h" #include "console1.h"
namespace ArdourSurface { namespace Console1 {
class C1GUI : public Gtk::VBox class C1GUI : public Gtk::Notebook
{ {
public: public:
C1GUI (Console1&); C1GUI (Console1&);
~C1GUI (); ~C1GUI ();
private: private:
Console1& c1; Console1& c1;
PBD::ScopedConnectionList lcxl_connections; PBD::ScopedConnectionList lcxl_connections;
Gtk::VBox hpacker; Gtk::VBox hpacker;
Gtk::Table table; Gtk::Table table;
Gtk::ComboBox input_combo; Gtk::ComboBox input_combo;
Gtk::ComboBox output_combo; Gtk::ComboBox output_combo;
Gtk::Image image;
Gtk::Image image;
Gtk::CheckButton swap_solo_mute_cb; Gtk::CheckButton swap_solo_mute_cb;
Gtk::CheckButton band_q_as_send_cb; Gtk::CheckButton band_q_as_send_cb;
Gtk::CheckButton create_plugin_stubs_btn; Gtk::CheckButton create_plugin_stubs_btn;
Gtk::ScrolledWindow plugin_mapping_scroller;
Gtk::ComboBox plugins_combo;
Gtk::TreeView plugin_assignment_editor;
Gtk::ToggleButton* midi_assign_button;
Gtk::VBox plugin_packer;
sigc::signal<void> plugin_assignment_changed;
void update_port_combos (); void update_port_combos ();
PBD::ScopedConnection connection_change_connection; PBD::ScopedConnection connection_change_connection;
void connection_handler (); void connection_handler ();
PBD::ScopedConnectionList _port_connections; PBD::ScopedConnectionList port_connections;
PBD::ScopedConnectionList plugin_connections;
struct MidiPortColumns : public Gtk::TreeModel::ColumnRecord { struct MidiPortColumns : public Gtk::TreeModel::ColumnRecord {
MidiPortColumns() { MidiPortColumns() {
@ -74,17 +89,58 @@ private:
Gtk::TreeModelColumn<std::string> full_name; Gtk::TreeModelColumn<std::string> full_name;
}; };
struct PluginColumns : public Gtk::TreeModel::ColumnRecord {
PluginColumns() {
add (plugin_name);
add (plugin_id);
}
Gtk::TreeModelColumn<std::string> plugin_name;
Gtk::TreeModelColumn<std::string> plugin_id;
};
struct PluginAssignamentEditorColumns : public Gtk::TreeModel::ColumnRecord {
PluginAssignamentEditorColumns() {
add (index);
add (name);
add (is_switch);
add (controllerName);
add (shift);
};
Gtk::TreeModelColumn<int> index; // parameter index
Gtk::TreeModelColumn<std::string> name; // readable name of the parameter
Gtk::TreeModelColumn<bool> is_switch;
Gtk::TreeModelColumn<std::string> controllerName; // enum Button::ID
Gtk::TreeModelColumn<bool> shift;
};
MidiPortColumns midi_port_columns; MidiPortColumns midi_port_columns;
PluginColumns plugin_columns;
PluginAssignamentEditorColumns plugin_assignment_editor_columns;
Glib::RefPtr<Gtk::ListStore> plugin_assignment_store;
bool ignore_active_change; bool ignore_active_change;
Glib::RefPtr<Gtk::ListStore> build_midi_port_list (std::vector<std::string> const & ports, bool for_input); Glib::RefPtr<Gtk::ListStore> build_midi_port_list (std::vector<std::string> const & ports, bool for_input);
void active_port_changed (Gtk::ComboBox*,bool for_input);
Console1::PluginMapping plugin_mapping;
Gtk::VBox* build_plugin_assignment_page ();
Gtk::CellRendererCombo* make_action_renderer (Glib::RefPtr<Gtk::ListStore> model, Gtk::TreeModelColumnBase column);
void load_plugin_combo_rows ();
void build_plugin_assignment_editor ();
void plugin_assignment_editor_selection_changed ();
void change_controller_number (int controllerNumber, bool shiftState);
void midi_assign_button_toggled (Gtk::ToggleButton* b);
void change_controller (const Glib::ustring&, const Gtk::TreeIter&);
void toggle_shift (const Glib::ustring&);
void active_port_changed (Gtk::ComboBox*, bool for_input);
void set_swap_solo_mute (); void set_swap_solo_mute ();
void set_band_q_as_send(); void set_band_q_as_send ();
void set_create_mapping_stubs(); void set_create_mapping_stubs ();
void active_plugin_changed (Gtk::ComboBox* combo);
void write_plugin_assignment ();
}; };
} // namespace Console1
}
#endif /* __ardour_console1_gui_h__ */ #endif /* __ardour_console1_gui_h__ */

View file

@ -27,13 +27,15 @@
#include "console1.h" #include "console1.h"
using namespace ARDOUR; using namespace ARDOUR;
using namespace ArdourSurface;
using namespace PBD; using namespace PBD;
using namespace Glib; using namespace Glib;
using namespace std; using namespace std;
/* Operations */ /* Operations */
namespace Console1
{
void void
Console1::bank (bool up) Console1::bank (bool up)
{ {
@ -145,7 +147,7 @@ Console1::select (const uint32_t i)
void void
Console1::shift (const uint32_t val) Console1::shift (const uint32_t val)
{ {
DEBUG_TRACE (DEBUG::Console1, "shift()\n"); DEBUG_TRACE (DEBUG::Console1, string_compose( "shift (%1)\n", val ));
shift_state = !shift_state; shift_state = !shift_state;
ShiftChange (val); ShiftChange (val);
} }
@ -674,11 +676,14 @@ Console1::map_select ()
void void
Console1::map_shift (bool shift) Console1::map_shift (bool shift)
{ {
DEBUG_TRACE (DEBUG::Console1, "map_shift()\n"); DEBUG_TRACE (DEBUG::Console1, string_compose ("map_shift(%1)\n", shift));
try { try {
ControllerButton* controllerButton = get_button (PRESET); ControllerButton* controllerButton = get_button (PRESET);
controllerButton->set_led_state (shift); controllerButton->set_led_state (shift);
map_stripable_state (); if( in_plugin_state )
remap_plugin_parameter (current_plugin_index);
else
map_stripable_state ();
} catch (ControlNotFoundException const&) { } catch (ControlNotFoundException const&) {
DEBUG_TRACE (DEBUG::Console1, "Button not found\n"); DEBUG_TRACE (DEBUG::Console1, "Button not found\n");
} }
@ -687,7 +692,7 @@ Console1::map_shift (bool shift)
void void
Console1::map_plugin_state (bool plugin_state) Console1::map_plugin_state (bool plugin_state)
{ {
DEBUG_TRACE (DEBUG::Console1, "map_plugin_state()\n"); DEBUG_TRACE (DEBUG::Console1, string_compose ("map_plugin_state(%1)\n", plugin_state) );
try { try {
ControllerButton* controllerButton = get_button (TRACK_GROUP); ControllerButton* controllerButton = get_button (TRACK_GROUP);
controllerButton->set_led_state (in_plugin_state); controllerButton->set_led_state (in_plugin_state);
@ -699,10 +704,6 @@ Console1::map_plugin_state (bool plugin_state)
stop_blinking (ControllerID (FOCUS1 + i)); stop_blinking (ControllerID (FOCUS1 + i));
} }
map_stripable_state (); map_stripable_state ();
} else {
// I don't plan shift functionality with plugins...
shift (0);
// map all plugin related operations
} }
} }
@ -1034,6 +1035,7 @@ Console1::map_drive ()
} }
} }
// Sends
// Sends // Sends
void void
Console1::map_mb_send_level (const uint32_t n) Console1::map_mb_send_level (const uint32_t n)
@ -1045,15 +1047,22 @@ Console1::map_mb_send_level (const uint32_t n)
} }
#endif #endif
// Theese two sends are available in non-shift state // Theese two sends are available in non-shift state
if (n_offset > 9 && shift_state) { if (n_offset > 9 && shift_state)
{
return; return;
} else if (n_offset < 10 && !shift_state) // while the rest needs the shift state
{
return;
}
else if( !shift_state && !switch_eq_q_dials )
{
} }
else if (n_offset < 10 && !shift_state) { // while the rest needs the shift state else if (n_offset < 10 && !shift_state) { // while the rest needs the shift state
return; return;
} }
else if(!shift_state && !switch_eq_q_dials) { else if(!shift_state && !switch_eq_q_dials) {
return; return;
} }
ControllerID controllerID = get_send_controllerid (n_offset); ControllerID controllerID = get_send_controllerid (n_offset);
if (map_encoder (controllerID)) { if (map_encoder (controllerID)) {
std::shared_ptr<AutomationControl> control = _current_stripable->send_level_controllable (n); std::shared_ptr<AutomationControl> control = _current_stripable->send_level_controllable (n);
@ -1153,6 +1162,7 @@ Console1::map_comp_emph ()
} }
} }
void Console1::eqBandQChangeMapping (bool mapValues) void Console1::eqBandQChangeMapping (bool mapValues)
{ {
DEBUG_TRACE(DEBUG::Console1, string_compose("eqBandQChangeMapping(): band_q_as_send = %1, strip_eq_mode = %2, mapValues = %3 \n", band_q_as_send, strip_eq_mode, mapValues)); DEBUG_TRACE(DEBUG::Console1, string_compose("eqBandQChangeMapping(): band_q_as_send = %1, strip_eq_mode = %2, mapValues = %3 \n", band_q_as_send, strip_eq_mode, mapValues));
@ -1228,3 +1238,5 @@ Console1::map_encoder (ControllerID controllerID, std::shared_ptr<ARDOUR::Automa
DEBUG_TRACE (DEBUG::Console1, "Encoder not found\n"); DEBUG_TRACE (DEBUG::Console1, "Encoder not found\n");
} }
} }
} // namespace Console1

View file

@ -0,0 +1,238 @@
/*
* Copyright (C) 2023 Holger Dehnhardt <holger@dehnhardt.org>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#include "c1_gui.h"
#include "ardour/debug.h"
#include "console1.h"
#include "pbd/i18n.h"
using namespace PBD;
using namespace Gtk;
using namespace std;
namespace Console1
{
VBox*
C1GUI::build_plugin_assignment_page ()
{
VBox* plugconfig_packer = manage (new VBox);
HBox* plugselect_packer = manage (new HBox);
Gtk::Label* l;
l = manage (new Gtk::Label (_ ("Select Plugin")));
plugselect_packer->pack_start (*l, false, false);
plugconfig_packer->pack_start (*plugselect_packer, false, false);
load_plugin_combo_rows ();
plugselect_packer->pack_start (plugins_combo, true, true);
plugin_mapping_scroller.property_shadow_type () = Gtk::SHADOW_NONE;
plugin_mapping_scroller.set_policy (Gtk::PolicyType::POLICY_AUTOMATIC, Gtk::PolicyType::POLICY_AUTOMATIC);
plugin_mapping_scroller.add (plugin_assignment_editor);
plugconfig_packer->pack_start (plugin_mapping_scroller, true, true, 20);
build_plugin_assignment_editor ();
midi_assign_button = manage (new ToggleButton (_ ("assign Control per MIDI")));
midi_assign_button->set_sensitive (false);
midi_assign_button->set_active (false);
midi_assign_button->signal_toggled ().connect (sigc::bind (sigc::mem_fun (*this, &C1GUI::midi_assign_button_toggled), midi_assign_button));
plugconfig_packer->pack_start (*midi_assign_button, false, false);
plugin_assignment_changed.connect (sigc::mem_fun (*this, &C1GUI::write_plugin_assignment));
return plugconfig_packer;
}
void C1GUI::load_plugin_combo_rows()
{
Glib::RefPtr<Gtk::ListStore> plugin_store_model = ListStore::create (plugin_columns);
TreeModel::Row plugin_combo_row;
for (const auto& pm : c1.plugin_mapping_map) {
plugin_combo_row = *(plugin_store_model->append ());
plugin_combo_row[plugin_columns.plugin_name] = pm.second.name;
plugin_combo_row[plugin_columns.plugin_id] = pm.first;
DEBUG_TRACE (DEBUG::Console1, string_compose ("Add Plugin: name %1 / %2\n", pm.second.name, pm.first));
}
plugins_combo.pack_start (plugin_columns.plugin_name);
plugins_combo.signal_changed ().connect (
sigc::bind (sigc::mem_fun (*this, &C1GUI::active_plugin_changed), &plugins_combo));
plugins_combo.set_model (plugin_store_model);
}
void
C1GUI::build_plugin_assignment_editor ()
{
plugin_assignment_editor.append_column (_ ("Key"), plugin_assignment_editor_columns.index);
plugin_assignment_editor.append_column (_ ("Name"), plugin_assignment_editor_columns.name);
plugin_assignment_editor.append_column (_ ("Switch"), plugin_assignment_editor_columns.is_switch);
TreeViewColumn* col;
CellRendererCombo* controlRenderer;
CellRendererToggle* boolRendererShift = manage (new CellRendererToggle);
boolRendererShift->set_active ();
boolRendererShift->property_activatable () = true;
col = manage (new TreeViewColumn (_ ("Shift"), *boolRendererShift));
col->add_attribute (boolRendererShift->property_active (), plugin_assignment_editor_columns.shift);
boolRendererShift->signal_toggled ().connect (sigc::mem_fun (*this, &C1GUI::toggle_shift));
plugin_assignment_editor.append_column (*col);
controlRenderer = make_action_renderer (c1.getPluginControllerModel (), plugin_assignment_editor_columns.controllerName);
col = manage (new TreeViewColumn (_ ("Control"), *controlRenderer));
col->add_attribute (controlRenderer->property_text (), plugin_assignment_editor_columns.controllerName);
plugin_assignment_editor.append_column (*col);
plugin_assignment_store = ListStore::create (plugin_assignment_editor_columns);
plugin_assignment_editor.set_model (plugin_assignment_store);
}
void
C1GUI::active_plugin_changed (Gtk::ComboBox* combo)
{
DEBUG_TRACE (DEBUG::Console1, "C1GUI active_plugin_changed\n");
write_plugin_assignment ();
plugin_assignment_editor.set_model (Glib::RefPtr<TreeModel> ());
plugin_assignment_store->clear ();
TreeModel::iterator active = combo->get_active ();
TreeModel::Row plugin_assignment_row;
string new_plugin_name = (*active)[plugin_columns.plugin_name];
string new_plugin_id = (*active)[plugin_columns.plugin_id];
DEBUG_TRACE (DEBUG::Console1, string_compose ("Plugin: selected %1 / %2\n", new_plugin_name, new_plugin_id));
plugin_mapping = c1.plugin_mapping_map[new_plugin_id];
for (auto& parm : plugin_mapping.parameters) {
plugin_assignment_row = *(plugin_assignment_store->append ());
plugin_assignment_row[plugin_assignment_editor_columns.index] = parm.first;
plugin_assignment_row[plugin_assignment_editor_columns.name] = parm.second.name;
plugin_assignment_row[plugin_assignment_editor_columns.controllerName] = c1.findControllerNameById (parm.second.controllerId);
plugin_assignment_row[plugin_assignment_editor_columns.is_switch] = parm.second.is_switch;
plugin_assignment_row[plugin_assignment_editor_columns.shift] = parm.second.shift;
DEBUG_TRACE (DEBUG::Console1, string_compose ("Parameter Name %1 \n", parm.second.name));
DEBUG_TRACE (DEBUG::Console1, string_compose ("Parameter Index: %1 - index %2 \n", parm.first, parm.second.paramIndex));
DEBUG_TRACE (DEBUG::Console1, string_compose ("ControllerId: %1 \n", parm.second.controllerId));
DEBUG_TRACE (DEBUG::Console1, string_compose ("is switch? %1 \n", parm.second.is_switch));
DEBUG_TRACE (DEBUG::Console1, string_compose ("is shift? %1 \n", parm.second.shift));
}
plugin_assignment_editor.set_model (plugin_assignment_store);
plugin_assignment_editor.get_selection ()->set_mode (SELECTION_SINGLE);
plugin_assignment_editor.get_selection ()->signal_changed ().connect (sigc::mem_fun (*this, &C1GUI::plugin_assignment_editor_selection_changed));
midi_assign_button->set_sensitive (false);
midi_assign_button->set_active (false);
}
CellRendererCombo*
C1GUI::make_action_renderer (Glib::RefPtr<ListStore> model, Gtk::TreeModelColumnBase column)
{
CellRendererCombo* renderer = manage (new CellRendererCombo);
renderer->property_model () = model;
renderer->property_editable () = true;
renderer->property_text_column () = 0;
renderer->property_has_entry () = false;
renderer->signal_changed ().connect (sigc::mem_fun (*this, &C1GUI::change_controller));
return renderer;
}
void
C1GUI::change_controller (const Glib::ustring& sPath, const TreeModel::iterator& iter)
{
Gtk::TreePath path (sPath);
Gtk::TreeModel::iterator row = plugin_assignment_store->get_iter (path);
int index = *path.begin ();
if (row) {
string controllerName = (*iter)[c1.plugin_controller_columns.controllerName];
int controllerId = (*iter)[c1.plugin_controller_columns.controllerId];
plugin_mapping.parameters[index].controllerId = Console1::ControllerID (controllerId);
(*row).set_value (plugin_assignment_editor_columns.controllerName, controllerName);
DEBUG_TRACE (DEBUG::Console1,
string_compose ("Column Name: Controller, index %1, name %2 \n", index, controllerName));
plugin_assignment_changed ();
}
}
void
C1GUI::plugin_assignment_editor_selection_changed ()
{
if (plugin_assignment_editor.get_selection ()->count_selected_rows () != 1) {
midi_assign_button->set_sensitive (false);
}
midi_assign_button->set_sensitive (true);
}
void
C1GUI::write_plugin_assignment ()
{
DEBUG_TRACE (DEBUG::Console1, "write_plugin_assignment\n");
c1.plugin_mapping_map[plugin_mapping.id] = plugin_mapping;
c1.write_plugin_mapping (plugin_mapping);
}
void
C1GUI::change_controller_number( int controllerNumber, bool shiftState ){
DEBUG_TRACE (DEBUG::Console1, string_compose ("C1GUI::change_controller_number: received %1\n", controllerNumber));
Gtk::TreeModel::iterator row = plugin_assignment_editor.get_selection ()->get_selected ();
if (row) {
string name = c1.findControllerNameById (Console1::ControllerID(controllerNumber));
(*row).set_value (plugin_assignment_editor_columns.controllerName, name);
(*row).set_value (plugin_assignment_editor_columns.shift, shiftState);
int index = (*row).get_value (plugin_assignment_editor_columns.index);
plugin_mapping.parameters[index].controllerId = Console1::ControllerID (controllerNumber);
plugin_mapping.parameters[index].shift = shiftState ? 1 : 0;
plugin_assignment_changed ();
}
midi_assign_button->set_active (false);
}
void
C1GUI::midi_assign_button_toggled (Gtk::ToggleButton* b)
{
DEBUG_TRACE (DEBUG::Console1, "C1GUI::midi_assign_button_changed() \n");
bool en = b->get_active ();
c1.midi_assign_mode = en;
if( en )
{
c1.SendControllerNumber.connect (std::bind ( &C1GUI::change_controller_number, this, _1, _2));
}
}
void
C1GUI::toggle_shift (const Glib::ustring& s)
{
int index = atoi (s.c_str ());
Gtk::TreeModel::iterator row = plugin_assignment_store->get_iter (s);
if (row) {
bool value = !plugin_mapping.parameters[index].shift;
plugin_mapping.parameters[index].shift = value;
(*row).set_value (plugin_assignment_editor_columns.shift, value);
DEBUG_TRACE (DEBUG::Console1, string_compose ("Column Name: Shift, value %1\n", value));
plugin_assignment_changed ();
}
}
}

View file

@ -35,12 +35,12 @@
#include "console1.h" #include "console1.h"
using namespace ARDOUR; using namespace ARDOUR;
using namespace ArdourSurface;
using namespace PBD; using namespace PBD;
using namespace Glib; using namespace Glib;
using namespace std; using namespace std;
namespace ArdourSurface { namespace Console1
{
bool bool
Console1::ensure_config_dir () Console1::ensure_config_dir ()
@ -57,6 +57,9 @@ Console1::ensure_config_dir ()
uint32_t uint32_t
Console1::load_mappings () Console1::load_mappings ()
{ {
if( mappings_loaded )
return plugin_mapping_map.size ();
uint32_t i = 0; uint32_t i = 0;
if (!ensure_config_dir ()) if (!ensure_config_dir ())
return 1; return 1;
@ -89,7 +92,9 @@ Console1::load_mappings ()
++i; ++i;
} }
DEBUG_TRACE (DEBUG::Console1, string_compose ("Console1::load_mappings - found %1 mapping files\n", i)); DEBUG_TRACE (DEBUG::Console1, string_compose ("Console1::load_mappings - found %1 mapping files\n", i));
DEBUG_TRACE (DEBUG::Console1, string_compose ("Console1::load_mappings - loaded %1 mapping files\n", plugin_mapping_map.size()));
g_dir_close (gdir); g_dir_close (gdir);
mappings_loaded = true;
return i; return i;
} }
@ -118,56 +123,68 @@ Console1::load_mapping (XMLNode* mapping_xml)
const XMLNodeList& plist = (*i)->children (); const XMLNodeList& plist = (*i)->children ();
XMLNodeConstIterator j; XMLNodeConstIterator j;
PluginParameterMapping parmap;
for (j = plist.begin (); j != plist.end (); ++j) { for (j = plist.begin (); j != plist.end (); ++j) {
if ((*j)->name () == "name") { if ((*j)->name () == "name") {
param_name = (*j)->child_content (); param_name = (*j)->child_content ();
} else if ((*j)->name () == "mapping") { } else if ((*j)->name () == "mapping") {
param_mapping = (*j)->child_content (); param_mapping = (*j)->child_content ();
(*j)->get_property ("shift", parmap.shift);
(*j)->get_property ("is_switch", parmap.is_switch);
} }
} }
parmap.paramIndex = index;
parmap.name = param_name;
if (!param_mapping.empty ()) { if (!param_mapping.empty ()) {
PluginParameterMapping parmap; ControllerNameIdMap::const_iterator m = controllerNameIdMap.find (param_mapping);
parmap.paramIndex = index; if (m != controllerNameIdMap.end ())
parmap.name = param_name; {
ControllerMap::const_iterator m = controllerMap.find (param_mapping); parmap.controllerId = m->second;
if (m == controllerMap.end ()) }
continue;
parmap.controllerId = m->second;
parmap.is_switch = (param_type == "switch");
pm.parameters[index] = std::move (parmap);
pluginMappingMap[pm.id] = pm;
} }
else{
pm.configured = false;
parmap.controllerId = CONTROLLER_NONE;
}
pm.parameters[index] = std::move (parmap);
} }
plugin_mapping_map[pm.id] = pm;
return true; return true;
} }
void void
Console1::create_mapping (const std::shared_ptr<Processor> proc, const std::shared_ptr<Plugin> plugin) Console1::create_plugin_mapping_stubs (const std::shared_ptr<Processor> proc, const std::shared_ptr<Plugin> plugin)
{ {
DEBUG_TRACE (DEBUG::Console1, "create_plugin_mapping_stubs \n");
XMLTree* tree = new XMLTree (); XMLTree* tree = new XMLTree ();
XMLNode node = XMLNode ("c1plugin-mapping"); XMLNode node = XMLNode ("c1plugin-mapping");
node.set_property ("ID", plugin->unique_id ()); if( plugin->unique_id() == "" )
node.set_property ("NAME", plugin->name ()); return;
int32_t n_controls = -1; node.set_property ("ID", plugin->unique_id ());
node.set_property ("NAME", plugin->name ());
int32_t n_controls = -1;
set<Evoral::Parameter> p = proc->what_can_be_automated (); set<Evoral::Parameter> p = proc->what_can_be_automated ();
for (set<Evoral::Parameter>::iterator j = p.begin (); j != p.end (); ++j) { for (set<Evoral::Parameter>::iterator j = p.begin (); j != p.end (); ++j) {
++n_controls; ++n_controls;
std::string n = proc->describe_parameter (*j); std::string n = proc->describe_parameter (*j);
DEBUG_TRACE (DEBUG::Console1, string_compose ("Plugin parameter %1: %2\n", n_controls, n)); DEBUG_TRACE (DEBUG::Console1, string_compose ("create_plugin_mapping_stubs: Plugin parameter %1: %2\n", n_controls, n));
if (n == "hidden") { if (n == "hidden") {
continue; continue;
} }
XMLNode param = XMLNode ("param-mapping"); ParameterDescriptor parameterDescriptor;
param.set_property ("id", n_controls); plugin->get_parameter_descriptor (n_controls, parameterDescriptor);
XMLNode name = XMLNode ("name"); XMLNode param = XMLNode ("param-mapping");
XMLNode c = XMLNode ("c", plugin->parameter_label (n_controls).c_str ()); param.set_property ("id", n_controls);
name.add_child_copy (c); XMLNode name = XMLNode ("name");
XMLNode mapping = XMLNode ("mapping"); XMLNode c = XMLNode ("c", plugin->parameter_label (n_controls).c_str ());
mapping.set_property ("shift", "false"); name.add_child_copy (c);
param.add_child_copy (name); XMLNode mapping = XMLNode ("mapping");
param.add_child_copy (mapping); mapping.set_property ("shift", "false");
node.add_child_copy (param); mapping.set_property ("is_switch", parameterDescriptor.toggled ? 1 : 0);
param.add_child_copy (name);
param.add_child_copy (mapping);
node.add_child_copy (param);
} }
tree->set_root (&node); tree->set_root (&node);
@ -180,12 +197,54 @@ Console1::create_mapping (const std::shared_ptr<Processor> proc, const std::shar
tree->set_filename (filename); tree->set_filename (filename);
tree->write (); tree->write ();
load_mapping (&node);
PluginStubAdded ();
}
void
Console1::write_plugin_mapping (PluginMapping &mapping)
{
DEBUG_TRACE (DEBUG::Console1, "write_plugin_mapping \n");
XMLTree* tree = new XMLTree ();
XMLNode node = XMLNode ("c1plugin-mapping");
node.set_property ("ID", mapping.id);
node.set_property ("NAME", mapping.name);
for (const auto& plugin_param : mapping.parameters ) {
DEBUG_TRACE (DEBUG::Console1, string_compose ("write_plugin_mapping: Plugin parameter %1: %2 - shift: %3\n", plugin_param.first, plugin_param.second.name, plugin_param.second.shift));
XMLNode param = XMLNode ("param-mapping");
param.set_property ("id", plugin_param.second.paramIndex);
XMLNode name = XMLNode ("name");
XMLNode c = XMLNode ("c", plugin_param.second.name );
name.add_child_copy (c);
XMLNode mapping = XMLNode ("mapping");
mapping.set_property ("shift", plugin_param.second.shift);
mapping.set_property ("is_switch", plugin_param.second.is_switch);
XMLNode controller = XMLNode ("c", findControllerNameById (plugin_param.second.controllerId));
mapping.add_child_copy (controller);
param.add_child_copy (name);
param.add_child_copy (mapping);
node.add_child_copy (param);
}
tree->set_root (&node);
if (!ensure_config_dir ())
return;
std::string filename = Glib::build_filename (
user_config_directory (), config_dir_name, string_compose ("%1.%2", mapping.id, "xml"));
tree->set_filename (filename);
tree->write ();
load_mapping (&node);
} }
bool bool
Console1::select_plugin (const int32_t plugin_index) Console1::select_plugin (const int32_t plugin_index)
{ {
DEBUG_TRACE (DEBUG::Console1, "Console1::select_plugin\n"); DEBUG_TRACE (DEBUG::Console1, "Console1::select_plugin\n");
midi_assign_mode = false;
if (current_plugin_index == plugin_index) { if (current_plugin_index == plugin_index) {
std::shared_ptr<Route> r = std::dynamic_pointer_cast<Route> (_current_stripable); std::shared_ptr<Route> r = std::dynamic_pointer_cast<Route> (_current_stripable);
if (!r) { if (!r) {
@ -239,24 +298,23 @@ Console1::remove_plugin_operations ()
{ {
plugin_connections.drop_connections (); plugin_connections.drop_connections ();
for (auto& e : encoders) { for (auto& c : controllerMap) {
e.second->set_plugin_action (0); if (c.first == ControllerID::TRACK_GROUP)
e.second->set_plugin_shift_action (0);
e.second->set_value (0);
}
for (auto& b : buttons) {
if (b.first == ControllerID::TRACK_GROUP)
continue; continue;
if (b.first >= ControllerID::FOCUS1 && b.first <= ControllerID::FOCUS20) if (c.first >= ControllerID::FOCUS1 && c.first <= ControllerID::FOCUS20)
continue; continue;
b.second->set_plugin_action (0); c.second->set_plugin_action (0);
b.second->set_plugin_shift_action (0); c.second->set_plugin_shift_action (0);
b.second->set_led_state (false); c.second->clear_value ();
} if( c.second->get_type() == ControllerType::CONTROLLER_BUTTON && c.first != ControllerID::PRESET )
for (auto& m : multi_buttons) { {
m.second->set_plugin_action (0); ControllerButton* b = dynamic_cast<ControllerButton *> (c.second);
m.second->set_plugin_shift_action (0); b->set_led_state (false);
m.second->set_led_state (false); } else if (c.second->get_type () == ControllerType::MULTISTATE_BUTTON )
{
MultiStateButton* b = dynamic_cast<MultiStateButton *> (c.second);
b->set_led_state (false);
}
} }
} }
@ -271,17 +329,19 @@ Console1::find_plugin (const int32_t plugin_index)
if (!r) { if (!r) {
return proc; return proc;
} }
remove_plugin_operations ();
while ((ext_plugin_index < plugin_index) && (int_plugin_index < (int)bank_size)) { while ((ext_plugin_index < plugin_index) && (int_plugin_index < (int)bank_size)) {
++int_plugin_index; ++int_plugin_index;
DEBUG_TRACE (DEBUG::Console1, string_compose ("find_plugin: int index %1, ext index %2\n", int_plugin_index, ext_plugin_index));
proc = r->nth_plugin (int_plugin_index); proc = r->nth_plugin (int_plugin_index);
if (!proc) { if (!proc) {
DEBUG_TRACE (DEBUG::Console1, "find_plugin: plugin not found\n");
continue; continue;
;
} }
DEBUG_TRACE (DEBUG::Console1, "find_plugin: plugin found\n");
if (!proc->display_to_user ()) { if (!proc->display_to_user ()) {
DEBUG_TRACE (DEBUG::Console1, "find_plugin: display to user failed\n");
continue; continue;
} }
@ -301,19 +361,161 @@ Console1::find_plugin (const int32_t plugin_index)
} }
bool bool
Console1::spill_plugins (const int32_t plugin_index) Console1::setup_plugin_mute_button(const std::shared_ptr<PluginInsert>& plugin_insert)
{ {
bool mapping_found = false; int32_t n_controls = -1;
try {
ControllerButton* cb = get_button (ControllerID::MUTE);
std::function<void ()> plugin_mapping = [=] () -> void { cb->set_led_state (!plugin_insert->enabled ()); };
cb->set_plugin_action ([=] (uint32_t val) {
plugin_insert->enable (val == 0);
DEBUG_TRACE (DEBUG::Console1,
string_compose ("ControllerButton Plugin parameter %1: %2 \n", n_controls, val));
});
remove_plugin_operations (); plugin_insert->ActiveChanged.connect (
plugin_connections, MISSING_INVALIDATOR, std::bind (plugin_mapping), this);
plugin_insert->ActiveChanged ();
return true;
} catch (ControlNotFoundException const&) {
DEBUG_TRACE (DEBUG::Console1, string_compose ("No ControllerButton found %1\n", n_controls));
return false;
}
}
std::shared_ptr<Processor> proc = find_plugin (plugin_index); bool
if (!proc) Console1::setup_plugin_controller (const PluginParameterMapping& ppm, int32_t n_controls,
const ParameterDescriptor& parameterDescriptor,
const std::shared_ptr<AutomationControl>& ac)
{
DEBUG_TRACE (DEBUG::Console1, "Console1::setup_plugin_controller");
try {
Controller* controller = get_controller (ppm.controllerId);
if (!ppm.shift)
controller->set_plugin_action ([=] (uint32_t val) {
double v = val / 127.f;
double translated = parameterDescriptor.from_interface (v, true);
ac->set_value (translated,
PBD::Controllable::GroupControlDisposition::UseGroup);
DEBUG_TRACE (
DEBUG::Console1,
string_compose ("from: ->Encoder Plugin parameter %1: origin %2 calculated %3 translated %4\n", n_controls, val, v, translated));
});
else
controller->set_plugin_shift_action ([=] (uint32_t val) {
double v = val / 127.f;
double translated = parameterDescriptor.from_interface (v, true);
ac->set_value (translated,
PBD::Controllable::GroupControlDisposition::UseGroup);
DEBUG_TRACE (
DEBUG::Console1,
string_compose ("from: ->Encoder Plugin shift-parameter %1: origin %2 calculated %3 translated %4\n", n_controls, val, v, translated));
});
return set_plugin_receive_connection (controller, ac, parameterDescriptor, ppm);
} catch (ControlNotFoundException const&) {
DEBUG_TRACE (DEBUG::Console1, string_compose ("No Encoder found %1\n", n_controls));
return false;
}
}
bool
Console1::set_plugin_receive_connection (Controller* controller, const std::shared_ptr<AutomationControl>& ac, const ParameterDescriptor& parameterDescriptor, const PluginParameterMapping& ppm)
{
DEBUG_TRACE (DEBUG::Console1, "Console1::set_plugin_receive_connection \n");
if (ppm.shift != shift_state)
return false; return false;
int32_t n_controls = -1; std::function<void (bool b, PBD::Controllable::GroupControlDisposition d)> plugin_mapping;
DEBUG_TRACE (DEBUG::Console1, string_compose ("Found plugin %1\n", proc->name ()));
std::shared_ptr<PluginInsert> plugin_insert = std::dynamic_pointer_cast<PluginInsert> (proc); switch (controller->get_type ()) {
case ControllerType::ENCODER: {
Encoder* e = dynamic_cast<Encoder*> (controller);
if (e) {
DEBUG_TRACE (DEBUG::Console1, "Console1::set_plugin_receive_connection ENCODER\n");
plugin_mapping =
[=] (bool b, PBD::Controllable::GroupControlDisposition d) -> void {
double origin = ac->get_value ();
double v = parameterDescriptor.to_interface (origin, true);
e->set_value (v * 127);
DEBUG_TRACE (
DEBUG::Console1,
string_compose ("to: <-Encoder Plugin parameter %1: origin %2 translated %3 - %4\n", ppm.paramIndex, origin, v, v * 127));
};
DEBUG_TRACE (DEBUG::Console1, string_compose ("ENCODER has plugin_action %1, has shitft_plugin_action %2\n", e->get_plugin_action () ? "Yes" : "No", e->get_plugin_shift_action () ? "Yes" : "No"));
}
};
break;
case ControllerType::CONTROLLER_BUTTON: {
ControllerButton* button = dynamic_cast<ControllerButton*> (controller);
if (button) {
DEBUG_TRACE (DEBUG::Console1, "Console1::set_plugin_receive_connection CONTROLLER_BUTTON \n");
plugin_mapping = [=] (bool b, PBD::Controllable::GroupControlDisposition d) -> void {
button->set_led_state (ac->get_value ());
DEBUG_TRACE (DEBUG::Console1,
string_compose ("<-ControllerButton Plugin parameter %1: %2 \n",
ppm.paramIndex,
ac->get_value ()));
};
}
};
break;
default:
return false;
break;
}
ac->Changed.connect (
plugin_connections, MISSING_INVALIDATOR, std::bind (plugin_mapping, _1, _2), this);
ac->Changed (true, PBD::Controllable::GroupControlDisposition::UseGroup);
return true;
}
bool
Console1::handle_plugin_parameter(const PluginParameterMapping& ppm, int32_t n_controls,
const ParameterDescriptor& parameterDescriptor,
const std::shared_ptr<AutomationControl>& ac)
{
bool swtch = false;
DEBUG_TRACE (DEBUG::Console1, string_compose ("\nName: %1 \n", parameterDescriptor.label));
DEBUG_TRACE (DEBUG::Console1, string_compose ("Normal: %1 \n", parameterDescriptor.normal));
DEBUG_TRACE (DEBUG::Console1, string_compose ("Lower: %1 \n", parameterDescriptor.lower));
DEBUG_TRACE (DEBUG::Console1, string_compose ("Upper: %1 \n", parameterDescriptor.upper));
DEBUG_TRACE (DEBUG::Console1, string_compose ("Toggled: %1 \n", parameterDescriptor.toggled));
DEBUG_TRACE (DEBUG::Console1, string_compose ("Logarithmic: %1 \n", parameterDescriptor.logarithmic));
DEBUG_TRACE (DEBUG::Console1, string_compose ("Rangesteps: %1 \n", parameterDescriptor.rangesteps));
DEBUG_TRACE (DEBUG::Console1, string_compose ("Unit: %1 \n", parameterDescriptor.unit));
DEBUG_TRACE (DEBUG::Console1, string_compose ("Step: %1 \n", parameterDescriptor.step));
DEBUG_TRACE (DEBUG::Console1, string_compose ("Smallstep: %1 \n", parameterDescriptor.smallstep));
DEBUG_TRACE (DEBUG::Console1, string_compose ("Largestep: %1 \n", parameterDescriptor.largestep));
DEBUG_TRACE (DEBUG::Console1, string_compose ("Int-step: %1 \n", parameterDescriptor.integer_step));
DEBUG_TRACE (DEBUG::Console1, string_compose ("Sr_dependent: %1 \n", parameterDescriptor.sr_dependent));
DEBUG_TRACE (DEBUG::Console1, string_compose ("Enumeration: %1 \n", parameterDescriptor.enumeration));
DEBUG_TRACE (DEBUG::Console1, string_compose ("Inlinectrl: %1 \n", parameterDescriptor.inline_ctrl));
if (parameterDescriptor.toggled)
swtch = true;
else if (parameterDescriptor.integer_step && parameterDescriptor.upper == 1)
swtch = true;
else if (ppm.is_switch)
swtch = true;
return setup_plugin_controller(ppm, n_controls, parameterDescriptor, ac);
}
bool
Console1::remap_plugin_parameter (int plugin_index)
{
DEBUG_TRACE (DEBUG::Console1, string_compose ("Console1::remap_plugin_parameter index = %1 \n", plugin_index));
//plugin_connections.drop_connections ();
int32_t n_controls = -1;
std::shared_ptr<Processor> proc = find_plugin (plugin_index);
set<Evoral::Parameter> p = proc->what_can_be_automated ();
std::shared_ptr<PluginInsert> plugin_insert = std::dynamic_pointer_cast<PluginInsert> (proc);
if (!plugin_insert) if (!plugin_insert)
return false; return false;
@ -321,127 +523,117 @@ Console1::spill_plugins (const int32_t plugin_index)
if (!plugin) if (!plugin)
return false; return false;
DEBUG_TRACE (DEBUG::Console1, string_compose ("Found plugin id %1\n", plugin->unique_id ())); setup_plugin_mute_button (plugin_insert);
try {
ControllerButton* cb = get_button (ControllerID::MUTE);
std::function<void ()> plugin_mapping = [=] () -> void { cb->set_led_state (!plugin_insert->enabled ()); };
cb->set_plugin_action ([=] (uint32_t val) {
plugin_insert->enable (val == 0);
DEBUG_TRACE (DEBUG::Console1,
string_compose ("ControllerButton Plugin parameter %1: %2 \n", n_controls, val));
});
plugin_insert->ActiveChanged.connect (
plugin_connections, MISSING_INVALIDATOR, std::bind (plugin_mapping), this);
plugin_insert->ActiveChanged ();
} catch (ControlNotFoundException const&) {
DEBUG_TRACE (DEBUG::Console1, string_compose ("No ControllerButton found %1\n", n_controls));
}
PluginMappingMap::iterator pmmit = pluginMappingMap.find (plugin->unique_id ());
mapping_found = (pmmit != pluginMappingMap.end ());
if (!mapping_found) {
if (create_mapping_stubs) {
create_mapping (proc, plugin);
}
return true;
}
PluginMappingMap::iterator pmmit = plugin_mapping_map.find (plugin->unique_id ());
if (pmmit == plugin_mapping_map.end ())
return false;
PluginMapping pluginMapping = pmmit->second; PluginMapping pluginMapping = pmmit->second;
DEBUG_TRACE (DEBUG::Console1,
string_compose ("Plugin mapping found for id %1, name %2\n", pluginMapping.id, pluginMapping.name));
set<Evoral::Parameter> p = proc->what_can_be_automated ();
for (set<Evoral::Parameter>::iterator j = p.begin (); j != p.end (); ++j) { for (set<Evoral::Parameter>::iterator j = p.begin (); j != p.end (); ++j) {
++n_controls; ++n_controls;
std::string n = proc->describe_parameter (*j); std::string n = proc->describe_parameter (*j);
DEBUG_TRACE (DEBUG::Console1, string_compose ("Plugin parameter %1: %2\n", n_controls, n)); DEBUG_TRACE (DEBUG::Console1, string_compose ("Console1::remap_plugin_parameter: Plugin parameter %1: %2\n", n_controls, n));
if (n == "hidden") { if (n == "hidden") {
continue; continue;
} }
ParameterDescriptor parameterDescriptor; ParameterDescriptor parameterDescriptor;
plugin->get_parameter_descriptor (n_controls, parameterDescriptor); plugin->get_parameter_descriptor (n_controls, parameterDescriptor);
if (plugin->parameter_is_control (n_controls)) { PluginParameterMapping ppm = pluginMapping.parameters[n_controls];
DEBUG_TRACE (DEBUG::Console1, "parameter is control\n"); Controller *controller = get_controller (ppm.controllerId);
} std::shared_ptr<AutomationControl> ac = plugin_insert->automation_control (Evoral::Parameter (PluginAutomation, 0, n_controls));
if (plugin->parameter_is_output (n_controls)) { if (controller && ac) {
DEBUG_TRACE (DEBUG::Console1, "parameter is output\n"); DEBUG_TRACE (DEBUG::Console1, string_compose ("CONTROLLER has plugin_action %1, has shitft_plugin_action %2\n", controller->get_plugin_action () ? "Yes" : "No", controller->get_plugin_shift_action () ? "Yes" : "No"));
} set_plugin_receive_connection (controller, ac, parameterDescriptor, ppm);
if (plugin->parameter_is_audio (n_controls)) { }
DEBUG_TRACE (DEBUG::Console1, "parameter is audio\n"); }
}
if (plugin->parameter_is_input (n_controls)) {
std::shared_ptr<AutomationControl> c =
plugin_insert->automation_control (Evoral::Parameter (PluginAutomation, 0, n_controls));
if (c) {
PluginParameterMapping ppm = pluginMapping.parameters[n_controls];
bool swtch = false;
if (parameterDescriptor.integer_step && parameterDescriptor.upper == 1) {
swtch = true;
} else if (ppm.is_switch) {
swtch = true;
}
if (!swtch) {
try {
Encoder* e = get_encoder (ppm.controllerId);
std::function<void (bool b, PBD::Controllable::GroupControlDisposition d)> plugin_mapping =
[=] (bool b, PBD::Controllable::GroupControlDisposition d) -> void {
double v = parameterDescriptor.to_interface (c->get_value (), true);
e->set_value (v * 127);
DEBUG_TRACE (
DEBUG::Console1,
string_compose ("<-Encoder Plugin parameter %1: %2 - %3\n", n_controls, v * 127, v));
};
e->set_plugin_action ([=] (uint32_t val) {
double v = val / 127.f;
c->set_value (parameterDescriptor.from_interface (v, true),
PBD::Controllable::GroupControlDisposition::UseGroup);
DEBUG_TRACE (
DEBUG::Console1,
string_compose ("->Encoder Plugin parameter %1: %2 - %3\n", n_controls, val, v));
});
c->Changed.connect (
plugin_connections, MISSING_INVALIDATOR, std::bind (plugin_mapping, _1, _2), this);
c->Changed (true, PBD::Controllable::GroupControlDisposition::UseGroup);
continue;
} catch (ControlNotFoundException const&) {
DEBUG_TRACE (DEBUG::Console1, string_compose ("No Encoder found %1\n", n_controls));
}
} else {
try {
ControllerButton* cb = get_button (ppm.controllerId);
std::function<void (bool b, PBD::Controllable::GroupControlDisposition d)> plugin_mapping =
[=] (bool b, PBD::Controllable::GroupControlDisposition d) -> void {
cb->set_led_state (c->get_value ());
DEBUG_TRACE (DEBUG::Console1,
string_compose ("<-ControllerButton Plugin parameter %1: %2 \n",
n_controls,
c->get_value ()));
};
cb->set_plugin_action ([=] (uint32_t val) {
double v = val / 127.f;
c->set_value (parameterDescriptor.from_interface (v, true),
PBD::Controllable::GroupControlDisposition::UseGroup);
DEBUG_TRACE (
DEBUG::Console1,
string_compose ("->ControllerButton Plugin parameter %1: %2 - %3\n", n_controls, val, v));
});
c->Changed.connect (
plugin_connections, MISSING_INVALIDATOR, std::bind (plugin_mapping, _1, _2), this);
c->Changed (true, PBD::Controllable::GroupControlDisposition::UseGroup);
continue;
} catch (ControlNotFoundException const&) {
DEBUG_TRACE (DEBUG::Console1, string_compose ("No ControllerButton found %1\n", n_controls));
}
}
}
}
}
return true; return true;
} }
bool
Console1::spill_plugins (const int32_t plugin_index)
{
bool mapping_found = false;
remove_plugin_operations ();
std::shared_ptr<Processor> proc = find_plugin (plugin_index);
if (!proc)
return false;
int32_t n_controls = -1;
DEBUG_TRACE (DEBUG::Console1, string_compose ("spill_plugins: Found plugin %1\n", proc->name ()));
std::shared_ptr<PluginInsert> plugin_insert = std::dynamic_pointer_cast<PluginInsert> (proc);
if (!plugin_insert)
return false;
std::shared_ptr<Plugin> plugin = plugin_insert->plugin ();
if (!plugin)
return false;
DEBUG_TRACE (DEBUG::Console1, string_compose ("spill_plugins: Found plugin id %1\n", plugin->unique_id ()));
// Setup mute button
setup_plugin_mute_button(plugin_insert);
PluginMappingMap::iterator pmmit = plugin_mapping_map.find (plugin->unique_id ());
mapping_found = (pmmit != plugin_mapping_map.end ());
if (!mapping_found) {
if (create_mapping_stubs) {
create_plugin_mapping_stubs (proc, plugin);
}
return true;
}
PluginMapping pluginMapping = pmmit->second;
DEBUG_TRACE (DEBUG::Console1,
string_compose ("spill_plugins: Plugin mapping found for id %1, name %2\n", pluginMapping.id, pluginMapping.name));
set<Evoral::Parameter> p = proc->what_can_be_automated ();
for (set<Evoral::Parameter>::iterator j = p.begin (); j != p.end (); ++j) {
++n_controls;
std::string n = proc->describe_parameter (*j);
DEBUG_TRACE (DEBUG::Console1, string_compose ("spill_plugins: Plugin parameter %1: %2\n", n_controls, n));
if (n == "hidden") {
continue;
}
ParameterDescriptor parameterDescriptor;
plugin->get_parameter_descriptor (n_controls, parameterDescriptor);
if (plugin->parameter_is_control (n_controls)) {
DEBUG_TRACE (DEBUG::Console1, "parameter is control\n");
}
if (plugin->parameter_is_output (n_controls)) {
DEBUG_TRACE (DEBUG::Console1, "parameter is output\n");
}
if (plugin->parameter_is_audio (n_controls)) {
DEBUG_TRACE (DEBUG::Console1, "parameter is audio\n");
}
if (plugin->parameter_is_input (n_controls)) {
std::shared_ptr<AutomationControl> c =
plugin_insert->automation_control (Evoral::Parameter (PluginAutomation, 0, n_controls));
if (c) {
PluginParameterMapping ppm = pluginMapping.parameters[n_controls];
handle_plugin_parameter(ppm, n_controls, parameterDescriptor, c);
}
}
}
return true;
} }
Glib::RefPtr<Gtk::ListStore> Console1::getPluginControllerModel()
{
plugin_controller_model = Gtk::ListStore::create (plugin_controller_columns);
Gtk::TreeModel::Row plugin_controller_combo_row;
for( const auto &controller : controllerNameIdMap )
{
plugin_controller_combo_row = *(plugin_controller_model->append ());
plugin_controller_combo_row[plugin_controller_columns.controllerId] = controller.second;
plugin_controller_combo_row[plugin_controller_columns.controllerName] = X_ (controller.first);
}
return plugin_controller_model;
}
} // namespace Console1

View file

@ -41,12 +41,16 @@
#include "c1_control.h" #include "c1_control.h"
#include "c1_gui.h" #include "c1_gui.h"
using namespace ARDOUR; using namespace ARDOUR;
using namespace ArdourSurface;
using namespace PBD; using namespace PBD;
using namespace Glib; using namespace Glib;
using namespace std; using namespace std;
namespace Console1
{
Console1::Console1 (Session& s) Console1::Console1 (Session& s)
: MIDISurface (s, X_ ("Softube Console1"), X_ ("Console1"), false) : MIDISurface (s, X_ ("Softube Console1"), X_ ("Console1"), false)
, gui (0) , gui (0)
@ -66,25 +70,17 @@ Console1::~Console1 ()
stop_event_loop (); stop_event_loop ();
MIDISurface::drop (); MIDISurface::drop ();
for (const auto& b : buttons) { for (const auto& c : controllerMap) {
delete b.second; delete c.second;
}
for (const auto& e : encoders) {
delete e.second;
}
for (const auto& m : meters) {
delete m.second;
}
for (const auto& mb : multi_buttons) {
delete mb.second;
} }
} }
void void
Console1::all_lights_out () Console1::all_lights_out ()
{ {
for (ButtonMap::iterator b = buttons.begin (); b != buttons.end (); ++b) { for (ControllerMap::iterator b = controllerMap.begin (); b != controllerMap.end (); ++b) {
b->second->set_led_state (false); if( b->second->get_type() == ControllerType::CONTROLLER_BUTTON )
(dynamic_cast<ControllerButton*>(b->second))->set_led_state (false);
} }
} }
@ -181,7 +177,7 @@ Console1::begin_using_device ()
f0 7d 20 00 00 00 01 00 7f 49 6f 6c 73 00 f7 f0 7d 20 00 00 00 01 00 7f 49 6f 6c 73 00 f7
*/ */
load_mappings (); load_mappings ();
setup_controls (); setup_controls ();
/* Connection to the blink-timer */ /* Connection to the blink-timer */
@ -277,18 +273,22 @@ Console1::setup_controls ()
for (uint32_t i = 0; i < 20; ++i) { for (uint32_t i = 0; i < 20; ++i) {
new ControllerButton (this, new ControllerButton (this,
ControllerID (FOCUS1 + i), ControllerID (FOCUS1 + i),
std::function<void (uint32_t)> (std::bind (&Console1::select, this, i)), std::function<void (uint32_t)> (std::bind (&Console1::select, this, i)),
0, std::function<void (uint32_t)> (std::bind (&Console1::select, this, i)),
std::function<void (uint32_t)> (std::bind (&Console1::select_plugin, this, i))); std::function<void (uint32_t)> (std::bind (&Console1::select_plugin, this, i)),
std::function<void (uint32_t)> (std::bind (&Console1::select_plugin, this, i)));
} }
new ControllerButton ( new ControllerButton (
this, ControllerID::PRESET, std::function<void (uint32_t)> (std::bind (&Console1::shift, this, _1))); this, ControllerID::PRESET, std::function<void (uint32_t)> (std::bind (&Console1::shift, this, _1)));
new ControllerButton (this, new ControllerButton (this,
ControllerID::TRACK_GROUP, ControllerID::TRACK_GROUP,
std::function<void (uint32_t)> (std::bind (&Console1::plugin_state, this, _1))); std::function<void (uint32_t)> (std::bind (&Console1::plugin_state, this, _1)),
std::function<void (uint32_t)> (std::bind (&Console1::plugin_state, this, _1)),
std::function<void (uint32_t)> (std::bind (&Console1::plugin_state, this, _1)),
std::function<void (uint32_t)> (std::bind (&Console1::plugin_state, this, _1)));
new ControllerButton ( new ControllerButton (
this, ControllerID::DISPLAY_ON, std::function<void (uint32_t)> (std::bind (&Console1::rude_solo, this, _1))); this, ControllerID::DISPLAY_ON, std::function<void (uint32_t)> (std::bind (&Console1::rude_solo, this, _1)));
@ -438,64 +438,48 @@ void
Console1::handle_midi_controller_message (MIDI::Parser&, MIDI::EventTwoBytes* tb) Console1::handle_midi_controller_message (MIDI::Parser&, MIDI::EventTwoBytes* tb)
{ {
uint32_t controller_number = static_cast<uint32_t> (tb->controller_number); uint32_t controller_number = static_cast<uint32_t> (tb->controller_number);
uint32_t value = static_cast<uint32_t> (tb->value); uint32_t value = static_cast<uint32_t> (tb->value);
DEBUG_TRACE (DEBUG::Console1,
DEBUG_TRACE (DEBUG::Console1,
string_compose ("handle_midi_controller_message cn: '%1' val: '%2'\n", controller_number, value)); string_compose ("handle_midi_controller_message cn: '%1' val: '%2'\n", controller_number, value));
try { DEBUG_TRACE (DEBUG::Console1,
Encoder* e = get_encoder (ControllerID (controller_number)); string_compose ("handle_midi_controller_message shift state: '%1' plugin state: '%2'\n", shift_state, in_plugin_state));
if (in_plugin_state && e->plugin_action) {
e->plugin_action (value); if (midi_assign_mode && (controller_number != ControllerID::PRESET)) {
} else if (shift_state && e->shift_action) { SendControllerNumber (controller_number, shift_state);
e->shift_action (value);
} else {
e->action (value);
}
return; return;
} catch (ControlNotFoundException const&) { }
try {
Controller* controller = controllerMap[ControllerID (controller_number)];
if (controller ) {
DEBUG_TRACE (DEBUG::Console1, "handle_midi_controller_message; Controller Found'\n");
if (shift_state && in_plugin_state && controller->get_plugin_shift_action ()) {
controller->get_plugin_shift_action () (value);
DEBUG_TRACE (DEBUG::Console1, "handle_midi_controller_message: plugin_shift_action'\n" );
} else if (in_plugin_state && controller->get_plugin_action ()) {
controller->get_plugin_action () (value);
DEBUG_TRACE (DEBUG::Console1, "handle_midi_controller_message: plugin_action'\n");
} else if (shift_state && controller->get_shift_action ()) {
controller->get_shift_action () (value);
DEBUG_TRACE (DEBUG::Console1, "handle_midi_controller_message: shift_action'\n");
} else {
controller->get_action () (value);
DEBUG_TRACE (DEBUG::Console1, "handle_midi_controller_message: action'\n");
}
return;
}
else {
DEBUG_TRACE (DEBUG::Console1, "handle_midi_controller_message: Controller not found'\n");
}
}
catch (ControlNotFoundException const&) {
DEBUG_TRACE (DEBUG::Console1, DEBUG_TRACE (DEBUG::Console1,
string_compose ("handle_midi_controller_message: encoder not found cn: " string_compose ("handle_midi_controller_message: encoder not found cn: "
"'%1' val: '%2'\n", "'%1' val: '%2'\n",
controller_number, controller_number,
value)); value));
} }
try {
ControllerButton* b = get_button (ControllerID (controller_number));
if (in_plugin_state && b->plugin_action) {
DEBUG_TRACE (DEBUG::Console1, "Executing plugin_action\n");
b->plugin_action (value);
} else if (shift_state && b->shift_action) {
DEBUG_TRACE (DEBUG::Console1, "Executing shift_action\n");
b->shift_action (value);
} else {
DEBUG_TRACE (DEBUG::Console1, "Executing action\n");
b->action (value);
}
return;
} catch (ControlNotFoundException const&) {
DEBUG_TRACE (DEBUG::Console1,
string_compose ("handle_midi_controller_message: button not found cn: "
"'%1' val: '%2'\n",
controller_number,
value));
}
try {
MultiStateButton* mb = get_mbutton (ControllerID (controller_number));
if (shift_state && mb->shift_action) {
mb->shift_action (value);
} else {
mb->action (value);
}
return;
} catch (ControlNotFoundException const&) {
DEBUG_TRACE (DEBUG::Console1,
string_compose ("handle_midi_controller_message: mbutton not found cn: "
"'%1' val: '%2'\n",
controller_number,
value));
}
} }
void void
@ -532,7 +516,7 @@ Console1::notify_transport_state_changed ()
void void
Console1::stripable_selection_changed () Console1::stripable_selection_changed ()
{ {
DEBUG_TRACE (DEBUG::Console1, "stripable_selection_changed \n"); DEBUG_TRACE (DEBUG::Console1, "stripable_selection_changed \n");
if (!_in_use) if (!_in_use)
return; return;
@ -953,15 +937,6 @@ Console1::blinker ()
return true; return true;
} }
ControllerButton*
Console1::get_button (ControllerID id) const
{
ButtonMap::const_iterator b = buttons.find (id);
if (b == buttons.end ())
throw (ControlNotFoundException ());
return const_cast<ControllerButton*> (b->second);
}
Meter* Meter*
Console1::get_meter (ControllerID id) const Console1::get_meter (ControllerID id) const
{ {
@ -971,22 +946,42 @@ Console1::get_meter (ControllerID id) const
return const_cast<Meter*> (m->second); return const_cast<Meter*> (m->second);
} }
Controller*
Console1::get_controller (ControllerID id) const
{
ControllerMap::const_iterator c = controllerMap.find (id);
if (c == controllerMap.end ())
throw (ControlNotFoundException ());
return (c->second);
}
Controller*
Console1::get_controller (ControllerID id, ControllerType controllerType) const
{
ControllerMap::const_iterator c = controllerMap.find (id);
if ((c == controllerMap.end ()) || (c->second->get_type () != controllerType))
throw (ControlNotFoundException ());
return (c->second);
}
Encoder* Encoder*
Console1::get_encoder (ControllerID id) const Console1::get_encoder (ControllerID id) const
{ {
EncoderMap::const_iterator m = encoders.find (id); return dynamic_cast<Encoder*> (get_controller (id, ControllerType::ENCODER));
if (m == encoders.end ())
throw (ControlNotFoundException ());
return const_cast<Encoder*> (m->second);
} }
ControllerButton*
Console1::get_button (ControllerID id) const
{
return dynamic_cast<ControllerButton*> (get_controller (id, ControllerType::CONTROLLER_BUTTON));
}
MultiStateButton* MultiStateButton*
Console1::get_mbutton (ControllerID id) const Console1::get_mbutton (ControllerID id) const
{ {
MultiStateButtonMap::const_iterator m = multi_buttons.find (id); return dynamic_cast<MultiStateButton*> (get_controller (id, ControllerType::MULTISTATE_BUTTON));
if (m == multi_buttons.end ())
throw (ControlNotFoundException ());
return const_cast<MultiStateButton*> (m->second);
} }
ControllerID ControllerID
@ -1259,3 +1254,21 @@ Console1::master_monitor_has_changed ()
DEBUG_TRACE (DEBUG::Console1, string_compose ("master_monitor_has_changed - monitor active %1\n", monitor_active)); DEBUG_TRACE (DEBUG::Console1, string_compose ("master_monitor_has_changed - monitor active %1\n", monitor_active));
create_strip_inventory (); create_strip_inventory ();
} }
const std::string Console1::findControllerNameById (const ControllerID id){
for( const auto &controller : controllerNameIdMap ){
if( controller.second == id ){
return controller.first;
}
}
return std::string();
}
void
Console1::reset_midi_assign_mode ()
{
DEBUG_TRACE (DEBUG::Console1, "console1::reset_midi_assign_mode()\n");
midi_assign_mode = false;
}
} // namespace Console1

View file

@ -23,9 +23,17 @@
#include <map> #include <map>
#include <set> #include <set>
#include <sigc++/trackable.h>
#include <ytkmm/treemodel.h>
#include <ytkmm/liststore.h>
#include <glibmm/threads.h>
#define ABSTRACT_UI_EXPORTS #define ABSTRACT_UI_EXPORTS
#include "pbd/abstract_ui.h" #include "pbd/abstract_ui.h"
#include "ardour/parameter_descriptor.h"
#include "ardour/presentation_info.h" #include "ardour/presentation_info.h"
#include "control_protocol/control_protocol.h" #include "control_protocol/control_protocol.h"
@ -55,20 +63,15 @@ namespace PBD {
class Controllable; class Controllable;
} }
namespace Console1
{
class MIDIControllable; class MIDIControllable;
class MIDIFunction; class MIDIFunction;
class MIDIAction; class MIDIAction;
namespace ArdourSurface {
class C1GUI; class C1GUI;
// XXX TODO: these classes should not be in the ArdourSurface namespace
// which is shared with all other ctrl surfaces.
//
// ArdourSurface::Meter etc may cause conflicts.
// best add a C1 prefix, or additional namespace
class Controller; class Controller;
class ControllerButton; class ControllerButton;
class MultiStateButton; class MultiStateButton;
@ -86,6 +89,14 @@ public:
ControlNotFoundException () {} ControlNotFoundException () {}
}; };
enum ControllerType {
CONTROLLER,
CONTROLLER_BUTTON,
MULTISTATE_BUTTON,
ENCODER,
METER
};
class Console1 : public MIDISurface class Console1 : public MIDISurface
{ {
@ -109,6 +120,7 @@ public:
std::string input_port_name () const override; std::string input_port_name () const override;
std::string output_port_name () const override; std::string output_port_name () const override;
uint32_t load_mappings ();
XMLNode& get_state () const override; XMLNode& get_state () const override;
int set_state (const XMLNode&, int version) override; int set_state (const XMLNode&, int version) override;
@ -118,109 +130,113 @@ public:
bool create_mapping_stubs; bool create_mapping_stubs;
bool switch_eq_q_dials = true; bool switch_eq_q_dials = true;
bool midi_assign_mode = false;
void reset_midi_assign_mode ();
bool in_use(){ bool in_use(){
return _in_use; return _in_use;
} }
PBD::Signal<void()> ConnectionChange; PBD::Signal<void()> ConnectionChange;
/* Timer Events */ /* Timer Events */
PBD::Signal<void(bool)> BlinkIt; PBD::Signal<void (bool)> BlinkIt;
PBD::Signal<void()> Periodic; PBD::Signal<void ()> Periodic;
/* Local Signals */ /* Local Signals */
PBD::Signal<void()> BankChange; PBD::Signal<void ()> PluginStubAdded;
PBD::Signal<void(bool)> ShiftChange; PBD::Signal<void ()> BankChange;
PBD::Signal<void(bool)> PluginStateChange; PBD::Signal<void (bool)> ShiftChange;
PBD::Signal<void(bool)> EQBandQBindingChange; PBD::Signal<void (bool)> PluginStateChange;
PBD::Signal<void (bool)> EQBandQBindingChange;
sigc::signal2<void, int, bool> SendControllerNumber;
enum ControllerID enum ControllerID {
{ CONTROLLER_NONE = 0,
CONTROLLER_NONE = 0, VOLUME = 7,
VOLUME = 7, PAN = 10,
PAN = 10, MUTE = 12,
MUTE = 12, SOLO = 13,
SOLO = 13, ORDER = 14,
ORDER = 14, DRIVE = 15,
DRIVE = 15, EXTERNAL_SIDECHAIN = 17,
EXTERNAL_SIDECHAIN = 17, CHARACTER = 18,
CHARACTER = 18, FOCUS1 = 21,
FOCUS1 = 21, FOCUS2,
FOCUS2, FOCUS3,
FOCUS3, FOCUS4,
FOCUS4, FOCUS5,
FOCUS5, FOCUS6,
FOCUS6, FOCUS7,
FOCUS7, FOCUS8,
FOCUS8, FOCUS9,
FOCUS9, FOCUS10,
FOCUS10, FOCUS11,
FOCUS11, FOCUS12,
FOCUS12, FOCUS13,
FOCUS13, FOCUS14,
FOCUS14, FOCUS15,
FOCUS15, FOCUS16,
FOCUS16, FOCUS17,
FOCUS17, FOCUS18,
FOCUS18, FOCUS19,
FOCUS19, FOCUS20 = 40,
FOCUS20 = 40, COMP = 46,
COMP = 46, COMP_THRESH = 47,
COMP_THRESH = 47, COMP_RELEASE = 48,
COMP_RELEASE = 48, COMP_RATIO = 49,
COMP_RATIO = 49, COMP_PAR = 50,
COMP_PAR = 50, COMP_ATTACK = 51,
COMP_ATTACK = 51, SHAPE = 53,
SHAPE = 53, SHAPE_GATE = 54,
SHAPE_GATE = 54, SHAPE_SUSTAIN = 55,
SHAPE_SUSTAIN = 55, SHAPE_RELEASE = 56,
SHAPE_RELEASE = 56, SHAPE_PUNCH = 57,
SHAPE_PUNCH = 57, PRESET = 58,
PRESET = 58, HARD_GATE = 59,
HARD_GATE = 59, FILTER_TO_COMPRESSORS = 61,
FILTER_TO_COMPRESSORS = 61, HIGH_SHAPE = 65,
HIGH_SHAPE = 65, EQ = 80,
EQ = 80, HIGH_GAIN = 82,
HIGH_GAIN = 82, HIGH_FREQ = 83,
HIGH_FREQ = 83, HIGH_MID_GAIN = 85,
HIGH_MID_GAIN = 85, HIGH_MID_FREQ = 86,
HIGH_MID_FREQ = 86, HIGH_MID_SHAPE = 87,
HIGH_MID_SHAPE = 87, LOW_MID_GAIN = 88,
LOW_MID_GAIN = 88, LOW_MID_FREQ = 89,
LOW_MID_FREQ = 89, LOW_MID_SHAPE = 90,
LOW_MID_SHAPE = 90, LOW_GAIN = 91,
LOW_GAIN = 91, LOW_FREQ = 92,
LOW_FREQ = 92, LOW_SHAPE = 93,
LOW_SHAPE = 93, PAGE_UP = 96,
PAGE_UP = 96, PAGE_DOWN = 97,
PAGE_DOWN = 97, DISPLAY_ON = 102,
DISPLAY_ON = 102, LOW_CUT = 103,
LOW_CUT = 103, MODE = 104,
MODE = 104, HIGH_CUT = 105,
HIGH_CUT = 105, GAIN = 107,
GAIN = 107, PHASE_INV = 108,
PHASE_INV = 108, INPUT_METER_L = 110,
INPUT_METER_L = 110, INPUT_METER_R = 111,
INPUT_METER_R = 111, OUTPUT_METER_L = 112,
OUTPUT_METER_L = 112, OUTPUT_METER_R = 113,
OUTPUT_METER_R = 113, SHAPE_METER = 114,
SHAPE_METER = 114, COMP_METER = 115,
COMP_METER = 115, TRACK_COPY = 120,
TRACK_COPY = 120, TRACK_GROUP = 123,
TRACK_GROUP = 123,
}; };
enum EQ_MODE enum EQ_MODE {
{ EQM_UNDEFINED = -1,
EQM_UNDEFINED = -1, EQM_HARRISON = 0,
EQM_HARRISON = 0, EQM_SSL = 1
EQM_SSL = 1 };
};
using ControllerMap = std::map<std::string, ControllerID>; using ControllerNameIdMap = std::map<std::string, ControllerID>;
ControllerMap controllerMap{ { "CONTROLLER_NONE", ControllerID::CONTROLLER_NONE }, ControllerNameIdMap controllerNameIdMap{ { "CONTROLLER_NONE", ControllerID::CONTROLLER_NONE },
{ "VOLUME", ControllerID::VOLUME }, { "VOLUME", ControllerID::VOLUME },
{ "PAN", ControllerID::PAN }, { "PAN", ControllerID::PAN },
{ "MUTE", ControllerID::MUTE }, { "MUTE", ControllerID::MUTE },
@ -293,12 +309,27 @@ public:
{ "TRACK_COPY", ControllerID::TRACK_COPY }, { "TRACK_COPY", ControllerID::TRACK_COPY },
{ "TRACK_GROUP", ControllerID::TRACK_GROUP } }; { "TRACK_GROUP", ControllerID::TRACK_GROUP } };
private: struct PluginControllerColumns : public Gtk::TreeModel::ColumnRecord {
PluginControllerColumns () {
add (controllerName);
add (controllerId);
}
Gtk::TreeModelColumn<std::string> controllerName;
Gtk::TreeModelColumn<int> controllerId;
};
PluginControllerColumns plugin_controller_columns;
Glib::RefPtr<Gtk::ListStore> plugin_controller_model;
const std::string findControllerNameById (const ControllerID id);
private:
std::string config_dir_name = "c1mappings"; std::string config_dir_name = "c1mappings";
/* GUI */ /* GUI */
mutable C1GUI* gui; mutable C1GUI* gui;
void build_gui (); void build_gui ();
bool mappings_loaded = false;
bool controls_model_loaded = false;
/* Configuration */ /* Configuration */
const uint32_t bank_size = 20; const uint32_t bank_size = 20;
@ -311,7 +342,7 @@ private:
// Selected EQ // Selected EQ
EQ_MODE strip_eq_mode = EQM_UNDEFINED; EQ_MODE strip_eq_mode = EQM_UNDEFINED;
bool rolling = false; bool rolling = false;
uint32_t current_bank = 0; uint32_t current_bank = 0;
uint32_t current_strippable_index = 0; uint32_t current_strippable_index = 0;
@ -372,76 +403,74 @@ private:
void select_rid_by_index (const uint32_t index); void select_rid_by_index (const uint32_t index);
/* Controller Maps*/ /* Controller Maps*/
typedef std::map<ControllerID, ArdourSurface::ControllerButton*> ButtonMap; typedef std::map<ControllerID, Meter*> MeterMap;
typedef std::map<ControllerID, ArdourSurface::MultiStateButton*> MultiStateButtonMap;
typedef std::map<ControllerID, ArdourSurface::Meter*> MeterMap;
typedef std::map<ControllerID, ArdourSurface::Encoder*> EncoderMap;
ButtonMap buttons; typedef std::map<ControllerID, Controller*> ControllerMap;
ControllerButton* get_button (ControllerID) const;
MultiStateButtonMap multi_buttons; MeterMap meters;
MultiStateButton* get_mbutton (ControllerID id) const; Meter* get_meter (ControllerID) const;
ControllerButton* get_button (ControllerID) const;
MeterMap meters; MultiStateButton* get_mbutton (ControllerID id) const;
Meter* get_meter (ControllerID) const;
EncoderMap encoders; Encoder* get_encoder (ControllerID) const;
Encoder* get_encoder (ControllerID) const;
typedef std::map<uint32_t, ControllerID> SendControllerMap; ControllerMap controllerMap;
SendControllerMap send_controllers{ { 0, LOW_FREQ }, { 1, LOW_MID_FREQ }, { 2, HIGH_MID_FREQ }, Controller* get_controller (ControllerID id) const;
{ 3, HIGH_FREQ }, { 4, LOW_GAIN }, { 5, LOW_MID_GAIN }, Controller* get_controller (ControllerID id, ControllerType controllerType) const;
{ 6, HIGH_MID_GAIN }, { 7, HIGH_GAIN }, { 8, LOW_MID_SHAPE },
{ 9, HIGH_MID_SHAPE }, { 10, LOW_MID_SHAPE }, { 11, HIGH_MID_SHAPE } };
ControllerID get_send_controllerid (uint32_t); typedef std::map<uint32_t, ControllerID> SendControllerMap;
SendControllerMap send_controllers{ { 0, LOW_FREQ }, { 1, LOW_MID_FREQ }, { 2, HIGH_MID_FREQ }, { 3, HIGH_FREQ },
{ 4, LOW_GAIN }, { 5, LOW_MID_GAIN }, { 6, HIGH_MID_GAIN }, { 7, HIGH_GAIN },
{ 8, LOW_MID_SHAPE }, { 9, HIGH_MID_SHAPE }, { 10, LOW_MID_SHAPE }, { 11, HIGH_MID_SHAPE } };
/* */ ControllerID get_send_controllerid (uint32_t);
void all_lights_out ();
void notify_transport_state_changed () override; /* */
void notify_solo_active_changed (bool) override; void all_lights_out ();
sigc::connection periodic_connection; void notify_transport_state_changed () override;
void notify_solo_active_changed (bool) override;
bool periodic (); sigc::connection periodic_connection;
void periodic_update_meter ();
// Meter Handlig bool periodic ();
uint32_t last_output_meter_l = 0; void periodic_update_meter ();
uint32_t last_output_meter_r = 0;
std::shared_ptr<ARDOUR::ReadOnlyControl> gate_redux_meter = 0; // Meter Handlig
uint32_t last_gate_meter = 0; uint32_t last_output_meter_l = 0;
uint32_t last_output_meter_r = 0;
std::shared_ptr<ARDOUR::ReadOnlyControl> comp_redux_meter = 0; std::shared_ptr<ARDOUR::ReadOnlyControl> gate_redux_meter = 0;
uint32_t last_comp_redux = 0; uint32_t last_gate_meter = 0;
sigc::connection blink_connection; std::shared_ptr<ARDOUR::ReadOnlyControl> comp_redux_meter = 0;
typedef std::list<ControllerID> Blinkers; uint32_t last_comp_redux = 0;
Blinkers blinkers;
bool blink_state;
bool blinker ();
void start_blinking (ControllerID);
void stop_blinking (ControllerID);
void set_current_stripable (std::shared_ptr<ARDOUR::Stripable>); sigc::connection blink_connection;
void drop_current_stripable (); typedef std::list<ControllerID> Blinkers;
/*void use_master (); Blinkers blinkers;
void use_monitor ();*/ bool blink_state;
void stripable_selection_changed () override; bool blinker ();
/*PBD::ScopedConnection selection_connection;*/ void start_blinking (ControllerID);
PBD::ScopedConnectionList stripable_connections; void stop_blinking (ControllerID);
PBD::ScopedConnectionList console1_connections;
PBD::ScopedConnectionList plugin_connections;
void map_stripable_state (); void set_current_stripable (std::shared_ptr<ARDOUR::Stripable>);
void drop_current_stripable ();
/*void use_master ();
void use_monitor ();*/
void stripable_selection_changed () override;
/*PBD::ScopedConnection selection_connection;*/
PBD::ScopedConnectionList stripable_connections;
PBD::ScopedConnectionList console1_connections;
PBD::ScopedConnectionList plugin_connections;
void notify_parameter_changed (std::string) override; void map_stripable_state ();
void band_q_usage_changed ();
/* operations (defined in c1_operations.cc) */ void notify_parameter_changed (std::string) override;
void band_q_usage_changed ();
/* operations (defined in c1_operations.cc) */
void bank (bool up); void bank (bool up);
void drive (uint32_t value); void drive (uint32_t value);
@ -630,32 +659,59 @@ private:
using ParameterMap = std::map<uint32_t, PluginParameterMapping>; using ParameterMap = std::map<uint32_t, PluginParameterMapping>;
/* plugin handling */
bool ensure_config_dir ();
bool load_mapping (XMLNode* fin);
/**
* @brief Creates mapping stubs for a given plugin processor.
*
* This function sets up the necessary mapping stubs to associate the specified
* plugin with its processor, enabling control surface integration or automation.
*
* @param proc Shared pointer to the ARDOUR::Processor instance to be mapped.
* @param plugin Shared pointer to the ARDOUR::Plugin instance for which mapping stubs are created.
*/
void create_plugin_mapping_stubs (const std::shared_ptr<ARDOUR::Processor> proc, const std::shared_ptr<ARDOUR::Plugin> plugin);
bool spill_plugins (const int32_t plugin_index);
bool setup_plugin_mute_button (const std::shared_ptr<ARDOUR::PluginInsert>& plugin_insert);
bool setup_plugin_controller (const PluginParameterMapping& ppm, int32_t n_controls,
const ARDOUR::ParameterDescriptor& parameterDescriptor,
const std::shared_ptr<ARDOUR::AutomationControl>& ac);
bool handle_plugin_parameter (const PluginParameterMapping& ppm, int32_t n_controls,
const ARDOUR::ParameterDescriptor& parameterDescriptor,
const std::shared_ptr<ARDOUR::AutomationControl>& c);
bool set_plugin_receive_connection (Controller* controller, const std::shared_ptr<ARDOUR::AutomationControl>& ac, const ARDOUR::ParameterDescriptor& parameterDescriptor, const PluginParameterMapping& ppm);
bool remap_plugin_parameter (int plugin_index);
/* plugin operations */
void remove_plugin_operations ();
std::shared_ptr<ARDOUR::Processor> find_plugin (const int32_t plugin_index);
bool select_plugin (const int32_t plugin_index);
bool map_select_plugin (const int32_t plugin_index);
void eqBandQChangeMapping (bool mapValues);
public:
struct PluginMapping struct PluginMapping
{ {
std::string id; std::string id;
std::string name; std::string name;
bool configured;
ParameterMap parameters; ParameterMap parameters;
}; };
using PluginMappingMap = std::map<std::string, PluginMapping>;
PluginMappingMap plugin_mapping_map;
/* plugin handling */ Glib::RefPtr<Gtk::ListStore> getPluginControllerModel();
bool ensure_config_dir (); void write_plugin_mapping (PluginMapping &mapping);
uint32_t load_mappings ();
bool load_mapping (XMLNode* fin);
void create_mapping (const std::shared_ptr<ARDOUR::Processor> proc, const std::shared_ptr<ARDOUR::Plugin> plugin);
bool spill_plugins (const int32_t plugin_index);
/* plugin operations */
void remove_plugin_operations ();
std::shared_ptr<ARDOUR::Processor> find_plugin (const int32_t plugin_index);
bool select_plugin (const int32_t plugin_index);
bool map_select_plugin (const int32_t plugin_index);
void eqBandQChangeMapping (bool mapValues);
using PluginMappingMap = std::map<std::string, PluginMapping>;
PluginMappingMap pluginMappingMap;
}; };
} } // namespace Console1
#endif /* ardour_surface_console1_h */ #endif /* ardour_surface_console1_h */

View file

@ -22,15 +22,14 @@
#include "console1.h" #include "console1.h"
using namespace ARDOUR; using namespace ARDOUR;
using namespace ArdourSurface;
static ControlProtocol* static ControlProtocol*
new_console1 (Session* s) new_console1 (Session* s)
{ {
Console1* console1 = 0; Console1::Console1* console1 = 0;
try { try {
console1 = new Console1 (*s); console1 = new Console1::Console1 (*s);
} catch (failed_constructor& err) { } catch (failed_constructor& err) {
delete console1; delete console1;
console1 = 0; console1 = 0;

View file

@ -15,6 +15,7 @@ def build(bld):
console1.cc console1.cc
c1_operations.cc c1_operations.cc
c1_plugin_operations.cc c1_plugin_operations.cc
c1_plugin_control_assignment.cc
c1_gui.cc c1_gui.cc
''' '''
obj.defines = [ 'PACKAGE="ardour_console1"' ] obj.defines = [ 'PACKAGE="ardour_console1"' ]
@ -22,6 +23,11 @@ def build(bld):
obj.includes = [ '.', './console1'] obj.includes = [ '.', './console1']
obj.name = 'libardour_console1' obj.name = 'libardour_console1'
obj.target = 'ardour_console1' obj.target = 'ardour_console1'
obj.uselib = 'SIGCPP XML OSX GLIBMM GIOMM PANGOMM' obj.uselib = 'SIGCPP XML OSX'
obj.use = 'libardour libardour_cp libardour_midisurface libgtkmm2ext libpbd libevoral libtemporal libytkmm' obj.use = 'libardour libardour_cp libardour_midisurface libgtkmm2ext libpbd libevoral libtemporal'
obj.install_path = os.path.join(bld.env['LIBDIR'], 'surfaces') obj.install_path = os.path.join(bld.env['LIBDIR'], 'surfaces')
if bld.is_defined('YTK'):
obj.use += ' libytkmm'
obj.uselib += ' GLIBMM GIOMM PANGOMM'
else:
obj.uselib += ' GTKMM'