summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gtk2_ardour/ardour_ui.cc2
-rw-r--r--gtk2_ardour/editor_routes.cc2
-rw-r--r--gtk2_ardour/gain_meter.cc3
-rw-r--r--gtk2_ardour/mixer_ui.cc6
-rw-r--r--gtk2_ardour/utils.h16
-rw-r--r--libs/ardour/ardour/amp.h5
-rw-r--r--libs/ardour/ardour/route.h2
-rw-r--r--libs/ardour/ardour/utils.h16
-rw-r--r--libs/ardour/automation_control.cc2
-rw-r--r--libs/ardour/enums.cc6
-rw-r--r--libs/ardour/route.cc6
-rw-r--r--libs/ardour/session.cc25
-rw-r--r--libs/ardour/track.cc2
-rw-r--r--libs/pbd/controllable.cc70
-rw-r--r--libs/pbd/enums.cc47
-rw-r--r--libs/pbd/enumwriter.cc13
-rw-r--r--libs/pbd/pbd/controllable.h34
-rw-r--r--libs/pbd/pbd/enumwriter.h8
-rw-r--r--libs/pbd/wscript1
-rw-r--r--libs/surfaces/generic_midi/generic_midi_control_protocol.cc27
-rw-r--r--libs/surfaces/generic_midi/midicontrollable.cc14
-rw-r--r--libs/surfaces/generic_midi/midicontrollable.h1
22 files changed, 179 insertions, 129 deletions
diff --git a/gtk2_ardour/ardour_ui.cc b/gtk2_ardour/ardour_ui.cc
index e58e1a2f50..9b70f266e4 100644
--- a/gtk2_ardour/ardour_ui.cc
+++ b/gtk2_ardour/ardour_ui.cc
@@ -3400,7 +3400,7 @@ ARDOUR_UI::store_clock_modes ()
ARDOUR_UI::TransportControllable::TransportControllable (std::string name, ARDOUR_UI& u, ToggleType tp)
- : Controllable (name, string() /* missing URI */), ui (u), type(tp)
+ : Controllable (name), ui (u), type(tp)
{
}
diff --git a/gtk2_ardour/editor_routes.cc b/gtk2_ardour/editor_routes.cc
index 1a55d91573..87d010487f 100644
--- a/gtk2_ardour/editor_routes.cc
+++ b/gtk2_ardour/editor_routes.cc
@@ -892,6 +892,8 @@ EditorRoutes::move_selected_tracks (bool up)
}
_model->reorder (neworder);
+
+ _session->sync_order_keys (N_ ("editor"));
}
void
diff --git a/gtk2_ardour/gain_meter.cc b/gtk2_ardour/gain_meter.cc
index 961ceb6a4a..6c80ae2725 100644
--- a/gtk2_ardour/gain_meter.cc
+++ b/gtk2_ardour/gain_meter.cc
@@ -26,6 +26,7 @@
#include "ardour/session.h"
#include "ardour/session_route.h"
#include "ardour/dB.h"
+#include "ardour/utils.h"
#include <gtkmm/style.h>
#include <gdkmm/color.h>
@@ -40,11 +41,11 @@
#include "ardour_ui.h"
#include "gain_meter.h"
-#include "utils.h"
#include "logmeter.h"
#include "gui_thread.h"
#include "keyboard.h"
#include "public_editor.h"
+#include "utils.h"
#include "ardour/session.h"
#include "ardour/route.h"
diff --git a/gtk2_ardour/mixer_ui.cc b/gtk2_ardour/mixer_ui.cc
index 87c48a4348..b750f8a470 100644
--- a/gtk2_ardour/mixer_ui.cc
+++ b/gtk2_ardour/mixer_ui.cc
@@ -689,9 +689,7 @@ void
Mixer_UI::track_list_reorder (const TreeModel::Path&, const TreeModel::iterator&, int* /*new_order*/)
{
strip_redisplay_does_not_sync_order_keys = true;
- if (!strip_redisplay_does_not_reset_order_keys) {
- _session->set_remote_control_ids();
- }
+ _session->set_remote_control_ids();
redisplay_track_list ();
strip_redisplay_does_not_sync_order_keys = false;
}
@@ -701,6 +699,7 @@ Mixer_UI::track_list_change (const Gtk::TreeModel::Path&, const Gtk::TreeModel::
{
// never reset order keys because of a property change
strip_redisplay_does_not_reset_order_keys = true;
+ _session->set_remote_control_ids();
redisplay_track_list ();
strip_redisplay_does_not_reset_order_keys = false;
}
@@ -710,6 +709,7 @@ Mixer_UI::track_list_delete (const Gtk::TreeModel::Path&)
{
/* this could require an order sync */
if (_session && !_session->deletion_in_progress()) {
+ _session->set_remote_control_ids();
redisplay_track_list ();
}
}
diff --git a/gtk2_ardour/utils.h b/gtk2_ardour/utils.h
index 90a6de9ec4..e742e89cd5 100644
--- a/gtk2_ardour/utils.h
+++ b/gtk2_ardour/utils.h
@@ -37,22 +37,6 @@ namespace Gtk {
class Paned;
}
-static inline double
-gain_to_slider_position (ARDOUR::gain_t g)
-{
- if (g == 0) return 0;
- return pow((6.0*log(g)/log(2.0)+192.0)/198.0, 8.0);
-
-}
-
-static inline ARDOUR::gain_t
-slider_position_to_gain (double pos)
-{
- /* XXX Marcus writes: this doesn't seem right to me. but i don't have a better answer ... */
- if (pos == 0.0) return 0;
- return pow (2.0,(sqrt(sqrt(sqrt(pos)))*198.0-192.0)/6.0);
-}
-
Glib::ustring fit_to_pixels (const Glib::ustring&, int pixel_width, Pango::FontDescription& font, int& actual_width, bool with_ellipses = false);
std::pair<std::string, double> fit_to_pixels (cairo_t *, std::string, double);
diff --git a/libs/ardour/ardour/amp.h b/libs/ardour/ardour/amp.h
index c237479abd..54bd9defe2 100644
--- a/libs/ardour/ardour/amp.h
+++ b/libs/ardour/ardour/amp.h
@@ -73,8 +73,9 @@ public:
GainControl (std::string name, Session& session, Amp* a, const Evoral::Parameter &param,
boost::shared_ptr<AutomationList> al = boost::shared_ptr<AutomationList>() )
: AutomationControl (session, param, al, name)
- , _amp (a)
- {}
+ , _amp (a) {
+ set_flags (Controllable::Flag (flags() | Controllable::GainLike));
+ }
void set_value (float val);
float get_value (void) const;
diff --git a/libs/ardour/ardour/route.h b/libs/ardour/ardour/route.h
index bb02396773..ac945703fd 100644
--- a/libs/ardour/ardour/route.h
+++ b/libs/ardour/ardour/route.h
@@ -304,7 +304,7 @@ class Route : public SessionObject, public AutomatableControls, public RouteGrou
void automation_snapshot (nframes_t now, bool force=false);
void protect_automation ();
- void set_remote_control_id (uint32_t id);
+ void set_remote_control_id (uint32_t id, bool notify_class_listeners = true);
uint32_t remote_control_id () const;
/* for things concerned about *this* route's RID */
diff --git a/libs/ardour/ardour/utils.h b/libs/ardour/ardour/utils.h
index 6c6f754cf9..e68f7a01df 100644
--- a/libs/ardour/ardour/utils.h
+++ b/libs/ardour/ardour/utils.h
@@ -69,6 +69,22 @@ const char* edit_mode_to_string (ARDOUR::EditMode);
ARDOUR::EditMode string_to_edit_mode (std::string);
+static inline double
+gain_to_slider_position (ARDOUR::gain_t g)
+{
+ if (g == 0) return 0;
+ return pow((6.0*log(g)/log(2.0)+192.0)/198.0, 8.0);
+
+}
+
+static inline ARDOUR::gain_t
+slider_position_to_gain (double pos)
+{
+ /* XXX Marcus writes: this doesn't seem right to me. but i don't have a better answer ... */
+ if (pos == 0.0) return 0;
+ return pow (2.0,(sqrt(sqrt(sqrt(pos)))*198.0-192.0)/6.0);
+}
+
/* I don't really like hard-coding these falloff rates here
* Probably should use a map of some kind that could be configured
* These rates are db/sec.
diff --git a/libs/ardour/automation_control.cc b/libs/ardour/automation_control.cc
index cad3ef57e8..1460c42c7b 100644
--- a/libs/ardour/automation_control.cc
+++ b/libs/ardour/automation_control.cc
@@ -34,7 +34,7 @@ AutomationControl::AutomationControl(
const Evoral::Parameter& parameter,
boost::shared_ptr<ARDOUR::AutomationList> list,
const string& name)
- : Controllable((name != "") ? name : EventTypeMap::instance().to_symbol(parameter), string("") /* XXX missing URI */)
+ : Controllable((name != "") ? name : EventTypeMap::instance().to_symbol(parameter))
, Evoral::Control(parameter, list)
, _session(session)
{
diff --git a/libs/ardour/enums.cc b/libs/ardour/enums.cc
index be61b2acb2..7d07a5a95f 100644
--- a/libs/ardour/enums.cc
+++ b/libs/ardour/enums.cc
@@ -48,7 +48,7 @@ namespace ARDOUR {
void
setup_enum_writer ()
{
- EnumWriter* enum_writer = new EnumWriter();
+ EnumWriter& enum_writer (EnumWriter::instance());
vector<int> i;
vector<string> s;
@@ -122,8 +122,8 @@ setup_enum_writer ()
Session::SlaveState _Session_SlaveState;
MTC_Status _MIDI_MTC_Status;
-#define REGISTER(e) enum_writer->register_distinct (typeid(e).name(), i, s); i.clear(); s.clear()
-#define REGISTER_BITS(e) enum_writer->register_bits (typeid(e).name(), i, s); i.clear(); s.clear()
+#define REGISTER(e) enum_writer.register_distinct (typeid(e).name(), i, s); i.clear(); s.clear()
+#define REGISTER_BITS(e) enum_writer.register_bits (typeid(e).name(), i, s); i.clear(); s.clear()
#define REGISTER_ENUM(e) i.push_back (e); s.push_back (#e)
#define REGISTER_CLASS_ENUM(t,e) i.push_back (t::e); s.push_back (#e)
diff --git a/libs/ardour/route.cc b/libs/ardour/route.cc
index 9c08080d2d..c5d26f7b7c 100644
--- a/libs/ardour/route.cc
+++ b/libs/ardour/route.cc
@@ -174,12 +174,14 @@ Route::~Route ()
}
void
-Route::set_remote_control_id (uint32_t id)
+Route::set_remote_control_id (uint32_t id, bool notify_class_listeners)
{
if (id != _remote_control_id) {
_remote_control_id = id;
RemoteControlIDChanged ();
- RemoteControlIDChange ();
+ if (notify_class_listeners) {
+ RemoteControlIDChange ();
+ }
}
}
diff --git a/libs/ardour/session.cc b/libs/ardour/session.cc
index 1f61322b4b..31693daff3 100644
--- a/libs/ardour/session.cc
+++ b/libs/ardour/session.cc
@@ -1863,20 +1863,27 @@ void
Session::set_remote_control_ids ()
{
RemoteModel m = Config->get_remote_model();
+ bool emit_signal = false;
shared_ptr<RouteList> r = routes.reader ();
for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
- if ( MixerOrdered == m) {
+ if (MixerOrdered == m) {
long order = (*i)->order_key(N_("signal"));
- (*i)->set_remote_control_id( order+1 );
- } else if ( EditorOrdered == m) {
+ (*i)->set_remote_control_id (order+1, false);
+ emit_signal = true;
+ } else if (EditorOrdered == m) {
long order = (*i)->order_key(N_("editor"));
- (*i)->set_remote_control_id( order+1 );
- } else if ( UserOrdered == m) {
+ (*i)->set_remote_control_id (order+1, false);
+ emit_signal = true;
+ } else if (UserOrdered == m) {
//do nothing ... only changes to remote id's are initiated by user
}
}
+
+ if (emit_signal) {
+ Route::RemoteControlIDChange();
+ }
}
@@ -2373,6 +2380,8 @@ Session::remove_route (shared_ptr<Route> route)
sync_order_keys (N_("session"));
+ Route::RemoteControlIDChange(); /* EMIT SIGNAL */
+
/* save the new state of the world */
if (save_state (_current_snapshot_name)) {
@@ -4184,9 +4193,11 @@ Session::sync_order_keys (std::string const & base)
}
Route::SyncOrderKeys (base); // EMIT SIGNAL
- Route::RemoteControlIDChange (); // EMIT SIGNAL
-}
+ /* this might not do anything */
+
+ set_remote_control_ids ();
+}
/** @return true if there is at least one record-enabled diskstream, otherwise false */
bool
diff --git a/libs/ardour/track.cc b/libs/ardour/track.cc
index 7d19d23007..f286e07c25 100644
--- a/libs/ardour/track.cc
+++ b/libs/ardour/track.cc
@@ -124,7 +124,7 @@ Track::freeze_state() const
}
Track::RecEnableControllable::RecEnableControllable (Track& s)
- : Controllable (X_("recenable"), string() /* XXX missing URI */), track (s)
+ : Controllable (X_("recenable")), track (s)
{
}
diff --git a/libs/pbd/controllable.cc b/libs/pbd/controllable.cc
index be487a0a87..d5b81a73ed 100644
--- a/libs/pbd/controllable.cc
+++ b/libs/pbd/controllable.cc
@@ -18,6 +18,7 @@
*/
#include "pbd/controllable.h"
+#include "pbd/enumwriter.h"
#include "pbd/xml++.h"
#include "pbd/error.h"
@@ -34,13 +35,11 @@ PBD::Signal1<void,Controllable*> Controllable::DeleteBinding;
Glib::StaticRWLock Controllable::registry_lock = GLIBMM_STATIC_RW_LOCK_INIT;
Controllable::Controllables Controllable::registry;
-Controllable::ControllablesByURI Controllable::registry_by_uri;
PBD::ScopedConnectionList registry_connections;
-Controllable::Controllable (const string& name, const string& uri)
+Controllable::Controllable (const string& name, Flag f)
: _name (name)
- , _uri (uri)
- , _touching (false)
+ , _flags (f)
{
add (*this);
}
@@ -53,13 +52,6 @@ Controllable::add (Controllable& ctl)
Glib::RWLock::WriterLock lm (registry_lock);
registry.insert (&ctl);
- if (!ctl.uri().empty()) {
- pair<string,Controllable*> newpair;
- newpair.first = ctl.uri();
- newpair.second = &ctl;
- registry_by_uri.insert (newpair);
- }
-
/* Controllable::remove() is static - no need to manage this connection */
ctl.DropReferences.connect_same_thread (registry_connections, boost::bind (&Controllable::remove, &ctl));
@@ -76,35 +68,6 @@ Controllable::remove (Controllable* ctl)
break;
}
}
-
- if (!ctl->uri().empty()) {
- ControllablesByURI::iterator i = registry_by_uri.find (ctl->uri());
- if (i != registry_by_uri.end()) {
- registry_by_uri.erase (i);
- }
- }
-}
-
-void
-Controllable::set_uri (const string& new_uri)
-{
- Glib::RWLock::WriterLock lm (registry_lock);
-
- if (!_uri.empty()) {
- ControllablesByURI::iterator i = registry_by_uri.find (_uri);
- if (i != registry_by_uri.end()) {
- registry_by_uri.erase (i);
- }
- }
-
- _uri = new_uri;
-
- if (!_uri.empty()) {
- pair<string,Controllable*> newpair;
- newpair.first = _uri;
- newpair.second = this;
- registry_by_uri.insert (newpair);
- }
}
Controllable*
@@ -121,18 +84,6 @@ Controllable::by_id (const ID& id)
}
Controllable*
-Controllable::by_uri (const string& uri)
-{
- Glib::RWLock::ReaderLock lm (registry_lock);
- ControllablesByURI::iterator i;
-
- if ((i = registry_by_uri.find (uri)) != registry_by_uri.end()) {
- return i->second;
- }
- return 0;
-}
-
-Controllable*
Controllable::by_name (const string& str)
{
Glib::RWLock::ReaderLock lm (registry_lock);
@@ -154,11 +105,8 @@ Controllable::get_state ()
node->add_property (X_("name"), _name); // not reloaded from XML state, just there to look at
_id.print (buf, sizeof (buf));
node->add_property (X_("id"), buf);
+ node->add_property (X_("flags"), enum_2_string (_flags));
- if (!_uri.empty()) {
- node->add_property (X_("uri"), _uri);
- }
-
return *node;
}
@@ -175,7 +123,13 @@ Controllable::set_state (const XMLNode& node, int /*version*/)
return -1;
}
- if ((prop = node.property (X_("uri"))) != 0) {
- set_uri (prop->value());
+ if ((prop = node.property (X_("flags"))) != 0) {
+ _flags = (Flag) string_2_enum (prop->value(), _flags);
}
}
+
+void
+Controllable::set_flags (Flag f)
+{
+ _flags = f;
+}
diff --git a/libs/pbd/enums.cc b/libs/pbd/enums.cc
new file mode 100644
index 0000000000..559af3a307
--- /dev/null
+++ b/libs/pbd/enums.cc
@@ -0,0 +1,47 @@
+/*
+ Copyright (C) 2009 Paul Davis
+
+ 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+*/
+
+#include "pbd/controllable.h"
+#include "pbd/enumwriter.h"
+
+void setup_libpbd_enums () __attribute__ ((constructor));
+
+using namespace PBD;
+using namespace std;
+
+void
+setup_libpbd_enums ()
+{
+ EnumWriter& enum_writer (EnumWriter::instance());
+ vector<int> i;
+ vector<string> s;
+
+ Controllable::Flag controllable_flags;
+
+#define REGISTER(e) enum_writer.register_distinct (typeid(e).name(), i, s); i.clear(); s.clear()
+#define REGISTER_BITS(e) enum_writer.register_bits (typeid(e).name(), i, s); i.clear(); s.clear()
+#define REGISTER_ENUM(e) i.push_back (e); s.push_back (#e)
+#define REGISTER_CLASS_ENUM(t,e) i.push_back (t::e); s.push_back (#e)
+
+ REGISTER_CLASS_ENUM (Controllable, Toggle);
+ REGISTER_CLASS_ENUM (Controllable, Discrete);
+ REGISTER_CLASS_ENUM (Controllable, GainLike);
+ REGISTER_CLASS_ENUM (Controllable, IntegerOnly);
+ REGISTER (controllable_flags);
+}
diff --git a/libs/pbd/enumwriter.cc b/libs/pbd/enumwriter.cc
index 134a00a207..2c6e5c73c8 100644
--- a/libs/pbd/enumwriter.cc
+++ b/libs/pbd/enumwriter.cc
@@ -63,11 +63,18 @@ nocase_cmp(const string & s1, const string& s2)
return (size1 < size2) ? -1 : 1;
}
-EnumWriter::EnumWriter ()
+EnumWriter&
+EnumWriter::instance()
{
if (_instance == 0) {
- _instance = this;
- }
+ _instance = new EnumWriter;
+ }
+
+ return *_instance;
+}
+
+EnumWriter::EnumWriter ()
+{
}
EnumWriter::~EnumWriter ()
diff --git a/libs/pbd/pbd/controllable.h b/libs/pbd/pbd/controllable.h
index 28dd4b7a31..f8d8f82855 100644
--- a/libs/pbd/pbd/controllable.h
+++ b/libs/pbd/pbd/controllable.h
@@ -35,12 +35,16 @@ namespace PBD {
class Controllable : public PBD::StatefulDestructible {
public:
- Controllable (const std::string& name, const std::string& uri);
+ enum Flag {
+ Toggle = 0x1,
+ Discrete = 0x2,
+ GainLike = 0x4,
+ IntegerOnly = 0x8
+ };
+
+ Controllable (const std::string& name, Flag f = Flag (0));
virtual ~Controllable() { Destroyed (this); }
- void set_uri (const std::string&);
- const std::string& uri() const { return _uri; }
-
virtual void set_value (float) = 0;
virtual float get_value (void) const = 0;
@@ -59,27 +63,35 @@ class Controllable : public PBD::StatefulDestructible {
XMLNode& get_state ();
std::string name() const { return _name; }
- bool touching () const { return _touching; }
-
+
+ bool touching () const { return _touching; }
void set_touching (bool yn) { _touching = yn; }
+ bool is_toggle() const { return _flags & Toggle; }
+ bool is_discrete() const { return _flags & Discrete; }
+ bool is_gain_like() const { return _flags & GainLike; }
+ bool is_integral_only() const { return _flags & IntegerOnly; }
+
+ Flag flags() const { return _flags; }
+ void set_flags (Flag f);
+
+ virtual uint32_t get_discrete_values (std::list<float>&) { return 0; /* no values returned */ }
+
static Controllable* by_id (const PBD::ID&);
static Controllable* by_name (const std::string&);
- static Controllable* by_uri (const std::string&);
private:
std::string _name;
- std::string _uri;
+
+ Flag _flags;
bool _touching;
static void add (Controllable&);
static void remove (Controllable*);
typedef std::set<PBD::Controllable*> Controllables;
- typedef std::map<std::string,PBD::Controllable*> ControllablesByURI;
static Glib::StaticRWLock registry_lock;
static Controllables registry;
- static ControllablesByURI registry_by_uri;
};
/* a utility class for the occasions when you need but do not have
@@ -89,7 +101,7 @@ class Controllable : public PBD::StatefulDestructible {
class IgnorableControllable : public Controllable
{
public:
- IgnorableControllable () : PBD::Controllable ("ignoreMe", std::string()) {}
+ IgnorableControllable () : PBD::Controllable ("ignoreMe") {}
~IgnorableControllable () {}
void set_value (float /*v*/) {}
diff --git a/libs/pbd/pbd/enumwriter.h b/libs/pbd/pbd/enumwriter.h
index 63a8ef6f6e..461665d739 100644
--- a/libs/pbd/pbd/enumwriter.h
+++ b/libs/pbd/pbd/enumwriter.h
@@ -36,10 +36,7 @@ class unknown_enumeration : public std::exception {
class EnumWriter {
public:
- EnumWriter ();
- ~EnumWriter ();
-
- static EnumWriter& instance() { return *_instance; }
+ static EnumWriter& instance();
void register_distinct (std::string type, std::vector<int>, std::vector<std::string>);
void register_bits (std::string type, std::vector<int>, std::vector<std::string>);
@@ -50,6 +47,9 @@ class EnumWriter {
void add_to_hack_table (std::string str, std::string hacked_str);
private:
+ EnumWriter ();
+ ~EnumWriter ();
+
struct EnumRegistration {
std::vector<int> values;
std::vector<std::string> names;
diff --git a/libs/pbd/wscript b/libs/pbd/wscript
index b25d8059ce..3794a37e81 100644
--- a/libs/pbd/wscript
+++ b/libs/pbd/wscript
@@ -61,6 +61,7 @@ def build(bld):
enumwriter.cc
event_loop.cc
dmalloc.cc
+ enums.cc
error.cc
filesystem.cc
filesystem_paths.cc
diff --git a/libs/surfaces/generic_midi/generic_midi_control_protocol.cc b/libs/surfaces/generic_midi/generic_midi_control_protocol.cc
index 6a29c27684..42c5358816 100644
--- a/libs/surfaces/generic_midi/generic_midi_control_protocol.cc
+++ b/libs/surfaces/generic_midi/generic_midi_control_protocol.cc
@@ -274,7 +274,6 @@ GenericMidiControlProtocol::start_learning (Controllable* c)
return false;
}
- Glib::Mutex::Lock lm (pending_lock);
Glib::Mutex::Lock lm2 (controllables_lock);
MIDIControllables::iterator tmp;
@@ -288,20 +287,23 @@ GenericMidiControlProtocol::start_learning (Controllable* c)
i = tmp;
}
- MIDIPendingControllables::iterator ptmp;
- for (MIDIPendingControllables::iterator i = pending_controllables.begin(); i != pending_controllables.end(); ) {
- ptmp = i;
- ++ptmp;
- if (((*i)->first)->get_controllable() == c) {
- (*i)->second.disconnect();
- delete (*i)->first;
- delete *i;
- pending_controllables.erase (i);
+ {
+ Glib::Mutex::Lock lm (pending_lock);
+
+ MIDIPendingControllables::iterator ptmp;
+ for (MIDIPendingControllables::iterator i = pending_controllables.begin(); i != pending_controllables.end(); ) {
+ ptmp = i;
+ ++ptmp;
+ if (((*i)->first)->get_controllable() == c) {
+ (*i)->second.disconnect();
+ delete (*i)->first;
+ delete *i;
+ pending_controllables.erase (i);
+ }
+ i = ptmp;
}
- i = ptmp;
}
-
MIDIControllable* mc = 0;
for (MIDIControllables::iterator i = controllables.begin(); i != controllables.end(); ++i) {
@@ -702,6 +704,7 @@ GenericMidiControlProtocol::create_binding (const XMLNode& node)
void
GenericMidiControlProtocol::reset_controllables ()
{
+ cerr << "GM::RC\n";
Glib::Mutex::Lock lm2 (controllables_lock);
for (MIDIControllables::iterator iter = controllables.begin(); iter != controllables.end(); ++iter) {
diff --git a/libs/surfaces/generic_midi/midicontrollable.cc b/libs/surfaces/generic_midi/midicontrollable.cc
index 0cebabd80b..5c23628a64 100644
--- a/libs/surfaces/generic_midi/midicontrollable.cc
+++ b/libs/surfaces/generic_midi/midicontrollable.cc
@@ -30,6 +30,7 @@
#include "midi++/channel.h"
#include "ardour/automation_control.h"
+#include "ardour/utils.h"
#include "midicontrollable.h"
@@ -196,10 +197,14 @@ MIDIControllable::midi_to_control(float val)
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;
+ if (ac->is_gain_like()) {
+ return slider_position_to_gain (val/midi_range);
+ }
+
+ const float control_range = control_max - control_min;
+ return val / midi_range * control_range + control_min;
}
void
@@ -459,8 +464,11 @@ MIDIControllable::get_state ()
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);
diff --git a/libs/surfaces/generic_midi/midicontrollable.h b/libs/surfaces/generic_midi/midicontrollable.h
index b5aa115fee..a635eaea10 100644
--- a/libs/surfaces/generic_midi/midicontrollable.h
+++ b/libs/surfaces/generic_midi/midicontrollable.h
@@ -91,6 +91,7 @@ class MIDIControllable : public PBD::Stateful
bool setting;
MIDI::byte last_value;
bool bistate;
+ bool _is_gain_controller;
bool _learned;
int midi_msg_id; /* controller ID or note number */
PBD::ScopedConnection midi_sense_connection[2];