Per-region MIDI CC "automation".
[ardour.git] / gtk2_ardour / midi_region_view.cc
index e96a65d893e640201fc82189bfc8bff7359a3d15..b12f8ef4d90b19e4525f962282f376ab10afab1c 100644 (file)
@@ -45,6 +45,8 @@
 #include "public_editor.h"
 #include "ghostregion.h"
 #include "midi_time_axis.h"
+#include "automation_time_axis.h"
+#include "automation_region_view.h"
 #include "utils.h"
 #include "midi_util.h"
 #include "gui_thread.h"
@@ -58,8 +60,7 @@ using namespace PBD;
 using namespace Editing;
 using namespace ArdourCanvas;
 
-MidiRegionView::MidiRegionView (ArdourCanvas::Group *parent, RouteTimeAxisView &tv, boost::shared_ptr<MidiRegion> r, double spu,
-                                 Gdk::Color& basic_color)
+MidiRegionView::MidiRegionView (ArdourCanvas::Group *parent, RouteTimeAxisView &tv, boost::shared_ptr<MidiRegion> r, double spu, Gdk::Color& basic_color)
        : RegionView (parent, tv, r, spu, basic_color)
        , _default_note_length(0.0)
        , _active_notes(0)
@@ -71,8 +72,7 @@ MidiRegionView::MidiRegionView (ArdourCanvas::Group *parent, RouteTimeAxisView &
        _note_group->raise_to_top();
 }
 
-MidiRegionView::MidiRegionView (ArdourCanvas::Group *parent, RouteTimeAxisView &tv, boost::shared_ptr<MidiRegion> r, double spu, 
-                                 Gdk::Color& basic_color, TimeAxisViewItem::Visibility visibility)
+MidiRegionView::MidiRegionView (ArdourCanvas::Group *parent, RouteTimeAxisView &tv, boost::shared_ptr<MidiRegion> r, double spu, Gdk::Color& basic_color, TimeAxisViewItem::Visibility visibility)
        : RegionView (parent, tv, r, spu, basic_color, visibility)
        , _default_note_length(0.0)
        , _active_notes(0)
@@ -394,19 +394,54 @@ MidiRegionView::display_model(boost::shared_ptr<MidiModel> model)
 void
 MidiRegionView::redisplay_model()
 {
-       clear_events();
-
-       //cerr << "Redisplaying model " << _model << endl;
+       // Don't redisplay the model if we're currently recording and displaying that
+       if (_active_notes)
+               return;
        
        if (_model) {
+
+               clear_events();
                begin_write();
+               
+               _model->read_lock();
 
                for (size_t i=0; i < _model->n_notes(); ++i)
                        add_note(_model->note_at(i));
 
                end_write();
+
+               for (Automatable::Controls::const_iterator i = _model->controls().begin();
+                               i != _model->controls().end(); ++i) {
+
+                       assert(i->second);
+
+                       boost::shared_ptr<AutomationTimeAxisView> at
+                               = midi_view()->automation_child(i->second->parameter());
+                       if (!at)
+                               continue;
+
+                       Gdk::Color col = midi_stream_view()->get_region_color();
+                               
+                       boost::shared_ptr<AutomationRegionView> arv;
+
+                       {
+                               Glib::Mutex::Lock list_lock (i->second->list()->lock());
+
+                               arv = boost::shared_ptr<AutomationRegionView>(
+                                               new AutomationRegionView(at->canvas_display,
+                                                       *at.get(), _region, i->second->list(),
+                                                       midi_stream_view()->get_samples_per_unit(), col));
+
+                               _automation_children.insert(std::make_pair(i->second->parameter(), arv));
+                       }
+
+                       arv->init(col, true);
+               }
+               
+               _model->read_unlock();
+
        } else {
-               warning << "MidiRegionView::redisplay_model called without a model" << endmsg;
+               cerr << "MidiRegionView::redisplay_model called without a model" << endmsg;
        }
 }
 
@@ -414,7 +449,10 @@ MidiRegionView::redisplay_model()
 MidiRegionView::~MidiRegionView ()
 {
        in_destructor = true;
-       end_write();
+       if (_active_notes)
+               end_write();
+
+       clear_events();
 
        RegionViewGoingAway (this); /* EMIT_SIGNAL */
 }
@@ -488,6 +526,7 @@ MidiRegionView::add_ghost (AutomationTimeAxisView& atv)
 void
 MidiRegionView::begin_write()
 {
+       assert(!_active_notes);
        _active_notes = new CanvasNote*[128];
        for (unsigned i=0; i < 128; ++i)
                _active_notes[i] = NULL;
@@ -512,9 +551,9 @@ MidiRegionView::end_write()
 void
 MidiRegionView::add_event (const MidiEvent& ev)
 {
-       /*printf("Event, time = %f, size = %zu, data = ", ev.time, ev.size);
-       for (size_t i=0; i < ev.size; ++i) {
-               printf("%X ", ev.buffer[i]);
+       /*printf("MRV add Event, time = %f, size = %u, data = ", ev.time(), ev.size());
+       for (size_t i=0; i < ev.size(); ++i) {
+               printf("%X ", ev.buffer()[i]);
        }
        printf("\n\n");*/