*/
+#define __STDC_FORMAT_MACROS 1
+#include <stdint.h>
+
#include <cstdio> /* for sprintf, sigh */
#include <climits>
#include "pbd/error.h"
+#include "pbd/controllable_descriptor.h"
#include "pbd/xml++.h"
#include "midi++/port.h"
#include "midi++/channel.h"
#include "ardour/automation_control.h"
+#include "ardour/utils.h"
#include "midicontrollable.h"
using namespace PBD;
using namespace ARDOUR;
-MIDIControllable::MIDIControllable (Port& p, const string& c, bool is_bistate)
- : controllable (0), _current_uri (c), _port (p), bistate (is_bistate)
+MIDIControllable::MIDIControllable (Port& p, bool is_bistate)
+ : controllable (0)
+ , _descriptor (0)
+ , _port (p)
+ , bistate (is_bistate)
{
- init ();
+ _learned = false; /* from URI */
+ setting = false;
+ last_value = 0; // got a better idea ?
+ control_type = none;
+ _control_description = "MIDI Control: none";
+ control_additional = (byte) -1;
+ feedback = true; // for now
}
MIDIControllable::MIDIControllable (Port& p, Controllable& c, bool is_bistate)
- : controllable (&c), _current_uri (c.uri()), _port (p), bistate (is_bistate)
-{
- init ();
-}
+ : controllable (&c)
+ , _descriptor (0)
+ , _port (p)
+ , bistate (is_bistate)
-MIDIControllable::~MIDIControllable ()
-{
- drop_external_control ();
-}
-
-void
-MIDIControllable::init ()
{
+ _learned = true; /* from controllable */
setting = false;
last_value = 0; // got a better idea ?
control_type = none;
_control_description = "MIDI Control: none";
control_additional = (byte) -1;
feedback = true; // for now
+}
- /* use channel 0 ("1") as the initial channel */
+MIDIControllable::~MIDIControllable ()
+{
+ drop_external_control ();
+}
- midi_rebind (0);
+int
+MIDIControllable::init (const std::string& s)
+{
+ _current_uri = s;
+ delete _descriptor;
+ _descriptor = new ControllableDescriptor;
+ return _descriptor->set (s);
}
void
void
MIDIControllable::drop_external_control ()
{
- midi_sense_connection[0].disconnect ();
- midi_sense_connection[1].disconnect ();
- midi_learn_connection.disconnect ();
-
+ midi_forget ();
control_type = none;
control_additional = (byte) -1;
}
void
-MIDIControllable::reacquire_controllable ()
+MIDIControllable::set_controllable (Controllable* c)
{
- if (!_current_uri.empty()) {
- controllable = Controllable::by_uri (_current_uri);
- } else {
- controllable = 0;
- }
+ controllable = c;
}
void
float control_min = 0.0f;
float control_max = 1.0f;
ARDOUR::AutomationControl* ac = dynamic_cast<ARDOUR::AutomationControl*>(controllable);
+
+ const float midi_range = 127.0f; // TODO: NRPN etc.
+
if (ac) {
+
+ if (ac->is_gain_like()) {
+ return slider_position_to_gain (val/midi_range);
+ }
+
control_min = ac->parameter().min();
control_max = ac->parameter().max();
}
const float control_range = control_max - control_min;
- const float midi_range = 127.0f; // TODO: NRPN etc.
-
- return val / midi_range * control_range + control_min;
+ return val / midi_range * control_range + control_min;
}
void
XMLNode* node = new XMLNode ("MIDIControllable");
+ if (!_current_uri.empty()) {
+ node->add_property ("uri", _current_uri);
+ }
+
if (controllable) {
- node->add_property ("uri", controllable->uri());
snprintf (buf, sizeof(buf), "0x%x", (int) control_type);
node->add_property ("event", buf);
snprintf (buf, sizeof(buf), "%d", (int) control_channel);