summaryrefslogtreecommitdiff
path: root/libs
diff options
context:
space:
mode:
authorPaul Davis <paul@linuxaudiosystems.com>2008-03-21 20:22:00 +0000
committerPaul Davis <paul@linuxaudiosystems.com>2008-03-21 20:22:00 +0000
commitfec2a96cec0f557cf30dde2f9bf21b76be36551d (patch)
treea1b446d153191d641f36cb30e178e3fc400be495 /libs
parentaa06f1f9f8be010d4abfc5b5c2fd61ab8e39fa58 (diff)
fix dragging that involves locked regions; auto-rebinding patch for people to experiment with (probably needs a little work)
git-svn-id: svn://localhost/ardour2/branches/2.0-ongoing@3164 d708f5d6-7413-0410-9779-e7cbd77b26cf
Diffstat (limited to 'libs')
-rw-r--r--libs/ardour/ardour/region_factory.h7
-rw-r--r--libs/ardour/ardour/session.h3
-rw-r--r--libs/ardour/region_factory.cc14
-rw-r--r--libs/ardour/session.cc4
-rw-r--r--libs/gtkmm2ext/gtkmm2ext/barcontroller.h1
-rw-r--r--libs/gtkmm2ext/gtkmm2ext/bindable_button.h5
-rw-r--r--libs/gtkmm2ext/gtkmm2ext/binding_proxy.h1
-rw-r--r--libs/pbd/controllable.cc2
-rw-r--r--libs/pbd/pbd/controllable.h2
-rw-r--r--libs/surfaces/generic_midi/generic_midi_control_protocol.cc146
-rw-r--r--libs/surfaces/generic_midi/generic_midi_control_protocol.h8
-rw-r--r--libs/surfaces/generic_midi/midicontrollable.h6
12 files changed, 152 insertions, 47 deletions
diff --git a/libs/ardour/ardour/region_factory.h b/libs/ardour/ardour/region_factory.h
index b944202c36..ada5afcd9c 100644
--- a/libs/ardour/ardour/region_factory.h
+++ b/libs/ardour/ardour/region_factory.h
@@ -42,6 +42,12 @@ class RegionFactory {
static sigc::signal<void,boost::shared_ptr<Region> > CheckNewRegion;
+ static boost::shared_ptr<Region> create (boost::shared_ptr<const Region>);
+
+ /* note: both of the first two should use const shared_ptr as well, but
+ gcc 4.1 doesn't seem to be able to disambiguate them if they do.
+ */
+
static boost::shared_ptr<Region> create (boost::shared_ptr<Region>, nframes_t start,
nframes_t length, std::string name,
layer_t = 0, Region::Flag flags = Region::DefaultFlags, bool announce = true);
@@ -50,7 +56,6 @@ class RegionFactory {
layer_t = 0, Region::Flag flags = Region::DefaultFlags, bool announce = true);
static boost::shared_ptr<Region> create (boost::shared_ptr<Source>, nframes_t start, nframes_t length, const string& name, layer_t = 0, Region::Flag flags = Region::DefaultFlags, bool announce = true);
static boost::shared_ptr<Region> create (const SourceList &, nframes_t start, nframes_t length, const string& name, layer_t = 0, Region::Flag flags = Region::DefaultFlags, bool announce = true);
- static boost::shared_ptr<Region> create (boost::shared_ptr<Region>);
static boost::shared_ptr<Region> create (Session&, XMLNode&, bool);
static boost::shared_ptr<Region> create (SourceList &, const XMLNode&);
};
diff --git a/libs/ardour/ardour/session.h b/libs/ardour/ardour/session.h
index 76590368f8..fa50212f3a 100644
--- a/libs/ardour/ardour/session.h
+++ b/libs/ardour/ardour/session.h
@@ -249,6 +249,9 @@ class Session : public PBD::StatefulDestructible
bool deletion_in_progress() const { return _state_of_the_state & Deletion; }
sigc::signal<void> DirtyChanged;
+ static sigc::signal<void> AutoBindingOn;
+ static sigc::signal<void> AutoBindingOff;
+
std::string sound_dir (bool with_path = true) const;
std::string peak_dir () const;
std::string dead_sound_dir () const;
diff --git a/libs/ardour/region_factory.cc b/libs/ardour/region_factory.cc
index 5cab802801..163cb07c6c 100644
--- a/libs/ardour/region_factory.cc
+++ b/libs/ardour/region_factory.cc
@@ -35,8 +35,8 @@ sigc::signal<void,boost::shared_ptr<Region> > RegionFactory::CheckNewRegion;
boost::shared_ptr<Region>
RegionFactory::create (boost::shared_ptr<Region> region, nframes_t start,
- nframes_t length, std::string name,
- layer_t layer, Region::Flag flags, bool announce)
+ nframes_t length, std::string name,
+ layer_t layer, Region::Flag flags, bool announce)
{
boost::shared_ptr<const AudioRegion> other;
@@ -57,11 +57,11 @@ RegionFactory::create (boost::shared_ptr<Region> region, nframes_t start,
}
boost::shared_ptr<Region>
-RegionFactory::create (boost::shared_ptr<Region> region)
+RegionFactory::create (boost::shared_ptr<const Region> region)
{
- boost::shared_ptr<AudioRegion> other;
+ boost::shared_ptr<const AudioRegion> other;
- if ((other = boost::dynamic_pointer_cast<AudioRegion>(region)) != 0) {
+ if ((other = boost::dynamic_pointer_cast<const AudioRegion>(region)) != 0) {
boost::shared_ptr<Region> ret (new AudioRegion (other));
/* pure copy constructor - no CheckNewRegion emitted */
return ret;
@@ -75,8 +75,8 @@ RegionFactory::create (boost::shared_ptr<Region> region)
boost::shared_ptr<Region>
RegionFactory::create (boost::shared_ptr<AudioRegion> region, nframes_t start,
- nframes_t length, std::string name,
- layer_t layer, Region::Flag flags, bool announce)
+ nframes_t length, std::string name,
+ layer_t layer, Region::Flag flags, bool announce)
{
return create (boost::static_pointer_cast<Region> (region), start, length, name, layer, flags, announce);
}
diff --git a/libs/ardour/session.cc b/libs/ardour/session.cc
index d53291b178..d7c3c95d9d 100644
--- a/libs/ardour/session.cc
+++ b/libs/ardour/session.cc
@@ -113,6 +113,10 @@ sigc::signal<void> Session::SMPTEOffsetChanged;
sigc::signal<void> Session::StartTimeChanged;
sigc::signal<void> Session::EndTimeChanged;
+sigc::signal<void> Session::AutoBindingOn;
+sigc::signal<void> Session::AutoBindingOff;
+
+
int
Session::find_session (string str, string& path, string& snapshot, bool& isnew)
{
diff --git a/libs/gtkmm2ext/gtkmm2ext/barcontroller.h b/libs/gtkmm2ext/gtkmm2ext/barcontroller.h
index c91f4c8a06..d149ded527 100644
--- a/libs/gtkmm2ext/gtkmm2ext/barcontroller.h
+++ b/libs/gtkmm2ext/gtkmm2ext/barcontroller.h
@@ -59,6 +59,7 @@ class BarController : public Gtk::Frame
/* export this to allow direct connection to button events */
Gtk::Widget& event_widget() { return darea; }
+ PBD::Controllable* get_controllable() { return binding_proxy.get_controllable(); }
protected:
Gtk::Adjustment& adjustment;
diff --git a/libs/gtkmm2ext/gtkmm2ext/bindable_button.h b/libs/gtkmm2ext/gtkmm2ext/bindable_button.h
index 2ddd3628fc..1cde32c5ba 100644
--- a/libs/gtkmm2ext/gtkmm2ext/bindable_button.h
+++ b/libs/gtkmm2ext/gtkmm2ext/bindable_button.h
@@ -47,7 +47,8 @@ class BindableToggleButton : public Gtkmm2ext::StatefulToggleButton
return true;
}
}
-
+
+ PBD::Controllable* get_controllable() { return binding_proxy.get_controllable(); }
private:
BindingProxy binding_proxy;
};
@@ -71,6 +72,8 @@ class BindableButton : public Gtkmm2ext::StatefulButton
}
}
+ PBD::Controllable* get_controllable() { return binding_proxy.get_controllable(); }
+
private:
BindingProxy binding_proxy;
};
diff --git a/libs/gtkmm2ext/gtkmm2ext/binding_proxy.h b/libs/gtkmm2ext/gtkmm2ext/binding_proxy.h
index d8f37c7649..dd9b94319d 100644
--- a/libs/gtkmm2ext/gtkmm2ext/binding_proxy.h
+++ b/libs/gtkmm2ext/gtkmm2ext/binding_proxy.h
@@ -40,6 +40,7 @@ class BindingProxy : public sigc::trackable
bool button_press_handler (GdkEventButton *);
+ PBD::Controllable* get_controllable() { return &controllable; }
protected:
Gtkmm2ext::PopUp* prompter;
diff --git a/libs/pbd/controllable.cc b/libs/pbd/controllable.cc
index bf0f7f5c6d..6a0028668b 100644
--- a/libs/pbd/controllable.cc
+++ b/libs/pbd/controllable.cc
@@ -28,6 +28,8 @@ using namespace PBD;
sigc::signal<void,Controllable*> Controllable::Destroyed;
sigc::signal<bool,Controllable*> Controllable::StartLearning;
sigc::signal<void,Controllable*> Controllable::StopLearning;
+sigc::signal<void,Controllable*,int,int> Controllable::CreateBinding;
+sigc::signal<void,Controllable*> Controllable::DeleteBinding;
Glib::Mutex* Controllable::registry_lock = 0;
Controllable::Controllables Controllable::registry;
diff --git a/libs/pbd/pbd/controllable.h b/libs/pbd/pbd/controllable.h
index 85f09726ca..17ee8f1a6f 100644
--- a/libs/pbd/pbd/controllable.h
+++ b/libs/pbd/pbd/controllable.h
@@ -44,6 +44,8 @@ class Controllable : public PBD::StatefulDestructible {
virtual bool can_send_feedback() const { return true; }
sigc::signal<void> LearningFinished;
+ static sigc::signal<void,PBD::Controllable*,int,int> CreateBinding;
+ static sigc::signal<void,PBD::Controllable*> DeleteBinding;
static sigc::signal<bool,PBD::Controllable*> StartLearning;
static sigc::signal<void,PBD::Controllable*> StopLearning;
diff --git a/libs/surfaces/generic_midi/generic_midi_control_protocol.cc b/libs/surfaces/generic_midi/generic_midi_control_protocol.cc
index 720711d94b..90b6b4bda9 100644
--- a/libs/surfaces/generic_midi/generic_midi_control_protocol.cc
+++ b/libs/surfaces/generic_midi/generic_midi_control_protocol.cc
@@ -56,9 +56,17 @@ GenericMidiControlProtocol::GenericMidiControlProtocol (Session& s)
_feedback_interval = 10000; // microseconds
last_feedback_time = 0;
+ auto_binding = FALSE;
+
Controllable::StartLearning.connect (mem_fun (*this, &GenericMidiControlProtocol::start_learning));
Controllable::StopLearning.connect (mem_fun (*this, &GenericMidiControlProtocol::stop_learning));
Session::SendFeedback.connect (mem_fun (*this, &GenericMidiControlProtocol::send_feedback));
+
+ Controllable::CreateBinding.connect (mem_fun (*this, &GenericMidiControlProtocol::create_binding));
+ Controllable::DeleteBinding.connect (mem_fun (*this, &GenericMidiControlProtocol::delete_binding));
+
+ Session::AutoBindingOn.connect (mem_fun (*this, &GenericMidiControlProtocol::auto_binding_on));
+ Session::AutoBindingOff.connect (mem_fun (*this, &GenericMidiControlProtocol::auto_binding_off));
}
GenericMidiControlProtocol::~GenericMidiControlProtocol ()
@@ -225,6 +233,71 @@ GenericMidiControlProtocol::stop_learning (Controllable* c)
}
}
+void
+GenericMidiControlProtocol::delete_binding ( PBD::Controllable* control )
+{
+ if( control != 0 ) {
+ Glib::Mutex::Lock lm2 (controllables_lock);
+
+ for( MIDIControllables::iterator iter = controllables.begin(); iter != controllables.end(); ++iter) {
+ MIDIControllable* existingBinding = (*iter);
+
+ if( control == &(existingBinding->get_controllable()) ) {
+ delete existingBinding;
+ controllables.erase (iter);
+ }
+
+ } // end for midi controllables
+ } // end null check
+}
+void
+GenericMidiControlProtocol::create_binding (PBD::Controllable* control, int pos, int control_number)
+{
+ if( control != NULL ) {
+ Glib::Mutex::Lock lm2 (controllables_lock);
+
+ MIDI::channel_t channel = (pos & 0xf);
+ MIDI::byte value = control_number;
+
+ // Create a MIDIControllable::
+ MIDIControllable* mc = new MIDIControllable (*_port, *control);
+
+ // Remove any old binding for this midi channel/type/value pair
+ // Note: can't use delete_binding() here because we don't know the specific controllable we want to remove, only the midi information
+ for( MIDIControllables::iterator iter = controllables.begin(); iter != controllables.end(); ++iter) {
+ MIDIControllable* existingBinding = (*iter);
+
+ if( (existingBinding->get_control_channel() & 0xf ) == channel &&
+ existingBinding->get_control_additional() == value &&
+ (existingBinding->get_control_type() & 0xf0 ) == MIDI::controller ) {
+
+ delete existingBinding;
+ controllables.erase (iter);
+ }
+
+ } // end for midi controllables
+
+
+ // Update the MIDI Controllable based on the the pos param
+ // Here is where a table lookup for user mappings could go; for now we'll just wing it...
+ mc->bind_midi( channel, MIDI::controller, value );
+
+ controllables.insert (mc);
+ } // end null test
+}
+
+void
+GenericMidiControlProtocol::auto_binding_on()
+{
+ auto_binding = TRUE;
+}
+
+void
+GenericMidiControlProtocol::auto_binding_off()
+{
+ auto_binding = FALSE;
+}
+
XMLNode&
GenericMidiControlProtocol::get_state ()
{
@@ -269,46 +342,47 @@ GenericMidiControlProtocol::set_state (const XMLNode& node)
_feedback_interval = 10000;
}
- Controllable* c;
-
- {
- Glib::Mutex::Lock lm (pending_lock);
- pending_controllables.clear ();
- }
-
- Glib::Mutex::Lock lm2 (controllables_lock);
-
- controllables.clear ();
-
- nlist = node.children(); // "controls"
-
- if (nlist.empty()) {
- return 0;
- }
-
- nlist = nlist.front()->children ();
-
- for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
-
- if ((prop = (*niter)->property ("id")) != 0) {
-
- ID id = prop->value ();
-
- c = Controllable::by_id (id);
+ // Are we using the autobinding feature? If so skip this part
+ if ( !auto_binding ) {
+
+ Controllable* c;
+
+ {
+ Glib::Mutex::Lock lm (pending_lock);
+ pending_controllables.clear ();
+ }
+
+ Glib::Mutex::Lock lm2 (controllables_lock);
+ controllables.clear ();
+ nlist = node.children(); // "controls"
+
+ if (nlist.empty()) {
+ return 0;
+ }
+
+ nlist = nlist.front()->children ();
+
+ for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
- if (c) {
- MIDIControllable* mc = new MIDIControllable (*_port, *c);
- if (mc->set_state (**niter) == 0) {
- controllables.insert (mc);
- }
+ if ((prop = (*niter)->property ("id")) != 0) {
+
+ ID id = prop->value ();
+ c = session->controllable_by_id (id);
- } else {
- warning << string_compose (_("Generic MIDI control: controllable %1 not found (ignored)"), id)
- << endmsg;
+ if (c) {
+ MIDIControllable* mc = new MIDIControllable (*_port, *c);
+ if (mc->set_state (**niter) == 0) {
+ controllables.insert (mc);
+ }
+
+ } else {
+ warning << string_compose (_("Generic MIDI control: controllable %1 not found in session (ignored)"),
+ id)
+ << endmsg;
+ }
}
}
- }
-
+ } // end autobinding check
return 0;
}
diff --git a/libs/surfaces/generic_midi/generic_midi_control_protocol.h b/libs/surfaces/generic_midi/generic_midi_control_protocol.h
index 95aeb77cdb..dfff8810d1 100644
--- a/libs/surfaces/generic_midi/generic_midi_control_protocol.h
+++ b/libs/surfaces/generic_midi/generic_midi_control_protocol.h
@@ -44,6 +44,7 @@ class GenericMidiControlProtocol : public ARDOUR::ControlProtocol {
ARDOUR::microseconds_t last_feedback_time;
bool do_feedback;
+ bool auto_binding;
void _send_feedback ();
void send_feedback ();
@@ -59,6 +60,13 @@ class GenericMidiControlProtocol : public ARDOUR::ControlProtocol {
void stop_learning (PBD::Controllable*);
void learning_stopped (MIDIControllable*);
+
+ void create_binding (PBD::Controllable*, int, int);
+ void delete_binding (PBD::Controllable*);
+
+ void auto_binding_on();
+ void auto_binding_off();
+
};
#endif /* ardour_generic_midi_control_protocol_h */
diff --git a/libs/surfaces/generic_midi/midicontrollable.h b/libs/surfaces/generic_midi/midicontrollable.h
index 4bac325feb..df6eea396c 100644
--- a/libs/surfaces/generic_midi/midicontrollable.h
+++ b/libs/surfaces/generic_midi/midicontrollable.h
@@ -63,6 +63,10 @@ class MIDIControllable : public Stateful
XMLNode& get_state (void);
int set_state (const XMLNode&);
+ void bind_midi (MIDI::channel_t, MIDI::eventType, MIDI::byte);
+ MIDI::channel_t get_control_channel () { return control_channel; }
+ MIDI::eventType get_control_type () { return control_type; }
+ MIDI::byte get_control_additional () { return control_additional; }
private:
PBD::Controllable& controllable;
MIDI::Port& _port;
@@ -86,8 +90,6 @@ class MIDIControllable : public Stateful
void midi_sense_controller (MIDI::Parser &, MIDI::EventTwoBytes *);
void midi_sense_program_change (MIDI::Parser &, MIDI::byte);
void midi_sense_pitchbend (MIDI::Parser &, MIDI::pitchbend_t);
-
- void bind_midi (MIDI::channel_t, MIDI::eventType, MIDI::byte);
};
#endif // __gm_midicontrollable_h__