summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid Robillard <d@drobilla.net>2009-02-18 22:30:06 +0000
committerDavid Robillard <d@drobilla.net>2009-02-18 22:30:06 +0000
commit9cfa3e2bf6eeaa07a3a0b87e711921f7d07ae97a (patch)
tree258a1281f7038eb694d6b83ec78b31b28f5fa998
parent3ccd34ec7e6c5bd68a0d68db57fc8047b6c9ee7e (diff)
Fix MIDI control parameter mapping to work with controls that aren't [0..1] like gain (fix ticket #0002553).
git-svn-id: svn://localhost/ardour2/branches/3.0@4627 d708f5d6-7413-0410-9779-e7cbd77b26cf
-rw-r--r--libs/ardour/ardour/automation_control.h4
-rw-r--r--libs/surfaces/generic_midi/midicontrollable.cc45
-rw-r--r--libs/surfaces/generic_midi/midicontrollable.h3
3 files changed, 46 insertions, 6 deletions
diff --git a/libs/ardour/ardour/automation_control.h b/libs/ardour/ardour/automation_control.h
index 3f22e6d57f..d3a220efbc 100644
--- a/libs/ardour/ardour/automation_control.h
+++ b/libs/ardour/ardour/automation_control.h
@@ -42,7 +42,9 @@ public:
boost::shared_ptr<ARDOUR::AutomationList> l=boost::shared_ptr<ARDOUR::AutomationList>(),
const string& name="");
- boost::shared_ptr<AutomationList> alist() const { return boost::dynamic_pointer_cast<AutomationList>(_list); }
+ boost::shared_ptr<AutomationList> alist() const {
+ return boost::dynamic_pointer_cast<AutomationList>(_list);
+ }
void set_list(boost::shared_ptr<Evoral::ControlList>);
diff --git a/libs/surfaces/generic_midi/midicontrollable.cc b/libs/surfaces/generic_midi/midicontrollable.cc
index 1a044d8ef3..08f90165bc 100644
--- a/libs/surfaces/generic_midi/midicontrollable.cc
+++ b/libs/surfaces/generic_midi/midicontrollable.cc
@@ -23,6 +23,7 @@
#include <pbd/xml++.h>
#include <midi++/port.h>
#include <midi++/channel.h>
+#include <ardour/automation_control.h>
#include "midicontrollable.h"
@@ -112,6 +113,40 @@ MIDIControllable::drop_external_control ()
control_additional = (byte) -1;
}
+float
+MIDIControllable::control_to_midi(float val)
+{
+ float control_min = 0.0f;
+ float control_max = 1.0f;
+ ARDOUR::AutomationControl* ac = dynamic_cast<ARDOUR::AutomationControl*>(&controllable);
+ if (ac) {
+ 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 - control_min) / control_range * midi_range;
+}
+
+float
+MIDIControllable::midi_to_control(float val)
+{
+ float control_min = 0.0f;
+ float control_max = 1.0f;
+ ARDOUR::AutomationControl* ac = dynamic_cast<ARDOUR::AutomationControl*>(&controllable);
+ if (ac) {
+ 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;
+}
+
void
MIDIControllable::midi_sense_note_on (Parser &p, EventTwoBytes *tb)
{
@@ -149,7 +184,7 @@ MIDIControllable::midi_sense_controller (Parser &, EventTwoBytes *msg)
{
if (control_additional == msg->controller_number) {
if (!bistate) {
- controllable.set_value (msg->value/127.0);
+ controllable.set_value (midi_to_control(msg->value));
} else {
if (msg->value > 64.0) {
controllable.set_value (1);
@@ -158,7 +193,7 @@ MIDIControllable::midi_sense_controller (Parser &, EventTwoBytes *msg)
}
}
- last_value = (MIDI::byte) (controllable.get_value() * 127.0); // to prevent feedback fights
+ last_value = (MIDI::byte) (control_to_midi(controllable.get_value())); // to prevent feedback fights
}
}
@@ -297,7 +332,7 @@ MIDIControllable::send_feedback ()
msg[0] = (control_type & 0xF0) | (control_channel & 0xF);
msg[1] = control_additional;
- msg[2] = (byte) (controllable.get_value() * 127.0f);
+ msg[2] = (byte) (control_to_midi(controllable.get_value()));
_port.write (msg, 3, 0);
}
@@ -306,8 +341,8 @@ MIDI::byte*
MIDIControllable::write_feedback (MIDI::byte* buf, int32_t& bufsize, bool force)
{
if (control_type != none && feedback && bufsize > 2) {
-
- MIDI::byte gm = (MIDI::byte) (controllable.get_value() * 127.0);
+
+ MIDI::byte gm = (MIDI::byte) (control_to_midi(controllable.get_value()));
if (gm != last_value) {
*buf++ = (0xF0 & control_type) | (0xF & control_channel);
diff --git a/libs/surfaces/generic_midi/midicontrollable.h b/libs/surfaces/generic_midi/midicontrollable.h
index 976c2d00fb..9fe9dcd2ac 100644
--- a/libs/surfaces/generic_midi/midicontrollable.h
+++ b/libs/surfaces/generic_midi/midicontrollable.h
@@ -55,6 +55,9 @@ class MIDIControllable : public PBD::Stateful
bool get_midi_feedback () { return feedback; }
void set_midi_feedback (bool val) { feedback = val; }
+ float control_to_midi(float val);
+ float midi_to_control(float val);
+
MIDI::Port& get_port() const { return _port; }
PBD::Controllable& get_controllable() const { return controllable; }