Add OSX configuration script.
[ardour.git] / libs / surfaces / faderport / faderport.cc
index bfeb20b76b3ca600e72fbbbeb77675704fb7ec2b..72190c1e8a0370970723688de1d5f832d41ae39c 100644 (file)
@@ -47,6 +47,7 @@
 #include "ardour/monitor_processor.h"
 #include "ardour/profile.h"
 #include "ardour/rc_configuration.h"
+#include "ardour/record_enable_control.h"
 #include "ardour/stripable.h"
 #include "ardour/session.h"
 #include "ardour/session_configuration.h"
@@ -60,7 +61,7 @@ using namespace PBD;
 using namespace Glib;
 using namespace std;
 
-#include "i18n.h"
+#include "pbd/i18n.h"
 
 #include "pbd/abstract_ui.cc" // instantiate template
 
@@ -107,9 +108,6 @@ FaderPort::FaderPort (Session& s)
                session->engine().make_port_name_non_relative (outp->name())
                );
 
-
-       StripableSelectionChanged.connect (selection_connection, MISSING_INVALIDATOR, boost::bind (&FaderPort::gui_track_selection_changed, this, _1), this);
-
        /* Catch port connections and disconnections */
        ARDOUR::AudioEngine::instance()->PortConnectedOrDisconnected.connect (port_connection, MISSING_INVALIDATOR, boost::bind (&FaderPort::connection_handler, this, _1, _2, _3, _4, _5), this);
 
@@ -173,7 +171,7 @@ FaderPort::FaderPort (Session& s)
        /* See comments about Stop above .. */
        get_button (Rewind).set_action (boost::bind (&BasicUI::rewind, this), true, RewindDown);
        get_button (Rewind).set_action (boost::bind (&BasicUI::goto_zero, this), true, ButtonState (RewindDown|StopDown));
-       get_button (Rewind).set_action (boost::bind (&BasicUI::goto_start, this), true, ButtonState (RewindDown|ShiftDown));
+       get_button (Rewind).set_action (boost::bind (&BasicUI::goto_start, this, false), true, ButtonState (RewindDown|ShiftDown));
 
        get_button (Ffwd).set_action (boost::bind (&BasicUI::ffwd, this), true);
        get_button (Ffwd).set_action (boost::bind (&BasicUI::goto_end, this), true, ShiftDown);
@@ -196,10 +194,13 @@ FaderPort::FaderPort (Session& s)
 
 FaderPort::~FaderPort ()
 {
+       cerr << "~FP\n";
+
        all_lights_out ();
 
        if (_input_port) {
                DEBUG_TRACE (DEBUG::FaderPort, string_compose ("unregistering input port %1\n", boost::shared_ptr<ARDOUR::Port>(_input_port)->name()));
+               Glib::Threads::Mutex::Lock em (AudioEngine::instance()->process_lock());
                AudioEngine::instance()->unregister_port (_input_port);
                _input_port.reset ();
        }
@@ -207,6 +208,7 @@ FaderPort::~FaderPort ()
        if (_output_port) {
                _output_port->drain (10000,  250000); /* check every 10 msecs, wait up to 1/4 second for the port to drain */
                DEBUG_TRACE (DEBUG::FaderPort, string_compose ("unregistering output port %1\n", boost::shared_ptr<ARDOUR::Port>(_output_port)->name()));
+               Glib::Threads::Mutex::Lock em (AudioEngine::instance()->process_lock());
                AudioEngine::instance()->unregister_port (_output_port);
                _output_port.reset ();
        }
@@ -246,7 +248,7 @@ FaderPort::start_midi_handling ()
         * method, which will read the data, and invoke the parser.
         */
 
-       _input_port->xthread().set_receive_handler (sigc::bind (sigc::mem_fun (this, &FaderPort::midi_input_handler), _input_port));
+       _input_port->xthread().set_receive_handler (sigc::bind (sigc::mem_fun (this, &FaderPort::midi_input_handler), boost::weak_ptr<AsyncMIDIPort> (_input_port)));
        _input_port->xthread().attach (main_loop()->get_context());
 }
 
@@ -284,19 +286,12 @@ FaderPort::stop ()
 void
 FaderPort::thread_init ()
 {
-       struct sched_param rtparam;
-
        pthread_set_name (event_loop_name().c_str());
 
        PBD::notify_event_loops_about_thread_creation (pthread_self(), event_loop_name(), 2048);
        ARDOUR::SessionEvent::create_per_thread_pool (event_loop_name(), 128);
 
-       memset (&rtparam, 0, sizeof (rtparam));
-       rtparam.sched_priority = 9; /* XXX should be relative to audio (JACK) thread */
-
-       if (pthread_setschedparam (pthread_self(), SCHED_FIFO, &rtparam) != 0) {
-               // do we care? not particularly.
-       }
+       set_thread_priority ();
 }
 
 void
@@ -379,7 +374,7 @@ FaderPort::button_handler (MIDI::Parser &, MIDI::EventTwoBytes* tb)
                                if (tb->value) {
                                        gain->start_touch (now);
                                } else {
-                                       gain->stop_touch (true, now);
+                                       gain->stop_touch (now);
                                }
                        }
                }
@@ -459,9 +454,9 @@ FaderPort::encoder_handler (MIDI::Parser &, MIDI::pitchbend_t pb)
                if ((button_state & trim_modifier) == trim_modifier ) {    // mod+encoder = input trim
                        boost::shared_ptr<AutomationControl> trim = _current_stripable->trim_control ();
                        if (trim) {
-                               float val = trim->get_user();  //for gain elements, the "user" value is in dB
-                               val += delta;
-                               trim->set_user(val);
+                               float val = accurate_coefficient_to_dB (trim->get_value());
+                               val += delta * .5f; // use 1/2 dB Steps -20..+20
+                               trim->set_value (dB_to_coefficient (val), Controllable::UseGroup);
                        }
                } else if (width_modifier && ((button_state & width_modifier) == width_modifier)) {
                        ardour_pan_width (delta);
@@ -748,8 +743,14 @@ FaderPort::connect_session_signals()
 }
 
 bool
-FaderPort::midi_input_handler (Glib::IOCondition ioc, boost::shared_ptr<ARDOUR::AsyncMIDIPort> port)
+FaderPort::midi_input_handler (Glib::IOCondition ioc, boost::weak_ptr<ARDOUR::AsyncMIDIPort> wport)
 {
+       boost::shared_ptr<AsyncMIDIPort> port (wport.lock());
+
+       if (!port) {
+               return false;
+       }
+
        DEBUG_TRACE (DEBUG::FaderPort, string_compose ("something happend on  %1\n", boost::shared_ptr<MIDI::Port>(port)->name()));
 
        if (ioc & ~IO_IN) {
@@ -826,11 +827,10 @@ FaderPort::set_state (const XMLNode& node, int version)
 
        for (XMLNodeList::const_iterator n = node.children().begin(); n != node.children().end(); ++n) {
                if ((*n)->name() == X_("Button")) {
-                       XMLProperty const * prop = (*n)->property (X_("id"));
-                       if (!prop) {
+                       int32_t xid;
+                       if (!(*n)->get_property (X_("id"), xid)) {
                                continue;
                        }
-                       int xid = atoi (prop->value());
                        ButtonMap::iterator b = buttons.find (ButtonID (xid));
                        if (b == buttons.end()) {
                                continue;
@@ -1032,13 +1032,8 @@ FaderPort::Button::set_led_state (boost::shared_ptr<MIDI::Port> port, bool onoff
 int
 FaderPort::Button::set_state (XMLNode const& node)
 {
-       const XMLProperty* prop = node.property ("id");
-       if (!prop) {
-               return -1;
-       }
-
-       int xid = atoi (prop->value());
-       if (xid != id) {
+       int32_t xid;
+       if (!node.get_property ("id", xid) || xid != id) {
                return -1;
        }
 
@@ -1050,16 +1045,16 @@ FaderPort::Button::set_state (XMLNode const& node)
        state_pairs.push_back (make_pair (string ("long"), LongPress));
 
        for (vector<state_pair_t>::const_iterator sp = state_pairs.begin(); sp != state_pairs.end(); ++sp) {
-               string propname;
 
-               propname = sp->first + X_("-press");
-               if ((prop = node.property (propname)) != 0) {
-                       set_action (prop->value(), true, sp->second);
+               string propname = sp->first + X_("-press");
+               string value;
+               if (node.get_property (propname.c_str(), value)) {
+                       set_action (value, true, sp->second);
                }
 
                propname = sp->first + X_("-release");
-               if ((prop = node.property (propname)) != 0) {
-                       set_action (prop->value(), false, sp->second);
+               if (node.get_property (propname.c_str(), value)) {
+                       set_action (value, false, sp->second);
                }
        }
 
@@ -1070,10 +1065,8 @@ XMLNode&
 FaderPort::Button::get_state () const
 {
        XMLNode* node = new XMLNode (X_("Button"));
-       char buf[16];
-       snprintf (buf, sizeof (buf), "%d", id);
 
-       node->add_property (X_("id"), buf);
+       node->set_property (X_("id"), to_string<int32_t>(id));
 
        ToDoMap::const_iterator x;
        ToDo null;
@@ -1089,13 +1082,13 @@ FaderPort::Button::get_state () const
        for (vector<state_pair_t>::const_iterator sp = state_pairs.begin(); sp != state_pairs.end(); ++sp) {
                if ((x = on_press.find (sp->second)) != on_press.end()) {
                        if (x->second.type == NamedAction) {
-                               node->add_property (string (sp->first + X_("-press")).c_str(), x->second.action_name);
+                               node->set_property (string (sp->first + X_("-press")).c_str(), x->second.action_name);
                        }
                }
 
                if ((x = on_release.find (sp->second)) != on_release.end()) {
                        if (x->second.type == NamedAction) {
-                               node->add_property (string (sp->first + X_("-release")).c_str(), x->second.action_name);
+                               node->set_property (string (sp->first + X_("-release")).c_str(), x->second.action_name);
                        }
                }
        }
@@ -1104,15 +1097,9 @@ FaderPort::Button::get_state () const
 }
 
 void
-FaderPort::gui_track_selection_changed (StripableNotificationListPtr stripables)
+FaderPort::stripable_selection_changed ()
 {
-       boost::shared_ptr<Stripable> r;
-
-       if (!stripables->empty()) {
-               r = stripables->front().lock();
-       }
-
-       set_current_stripable (r);
+       set_current_stripable (ControlProtocol::first_selected_stripable());
 }
 
 void