fix crash when copy'ing latent plugins
[ardour.git] / libs / ardour / midi_track.cc
index b078fa3f1b5141f2606484cc945bd9fd70f4534b..b79a1cf52cd6b56f85e7d20650ae45b596dff29a 100644 (file)
 #include "ardour/midi_port.h"
 #include "ardour/midi_region.h"
 #include "ardour/midi_track.h"
+#include "ardour/monitor_control.h"
 #include "ardour/parameter_types.h"
 #include "ardour/port.h"
 #include "ardour/processor.h"
 #include "ardour/profile.h"
+#include "ardour/route_group_specialized.h"
 #include "ardour/session.h"
 #include "ardour/session_playlists.h"
 #include "ardour/utils.h"
 
-#include "i18n.h"
+#include "pbd/i18n.h"
 
 namespace ARDOUR {
 class InterThreadInfo;
@@ -65,8 +67,8 @@ using namespace std;
 using namespace ARDOUR;
 using namespace PBD;
 
-MidiTrack::MidiTrack (Session& sess, string name, Route::Flag flag, TrackMode mode)
-       : Track (sess, name, flag, mode, DataType::MIDI)
+MidiTrack::MidiTrack (Session& sess, string name, TrackMode mode)
+       : Track (sess, name, PresentationInfo::MidiTrack, mode, DataType::MIDI)
        , _immediate_events(1024) // FIXME: size?
        , _step_edit_ring_buffer(64) // FIXME: size?
        , _note_mode(Sustained)
@@ -102,24 +104,24 @@ MidiTrack::create_diskstream ()
 }
 
 
-void
-MidiTrack::set_record_enabled (bool yn, void *src)
+bool
+MidiTrack::can_be_record_safe ()
 {
        if (_step_editing) {
-               return;
+               return false;
        }
 
-       Track::set_record_enabled (yn, src);
+       return Track::can_be_record_safe ();
 }
 
-void
-MidiTrack::set_record_safe (bool yn, void *src)
+bool
+MidiTrack::can_be_record_enabled ()
 {
-       if (_step_editing) { /* REQUIRES REVIEW */
-               return;
+       if (_step_editing) {
+               return false;
        }
 
-       Track::set_record_safe (yn, src);
+       return Track::can_be_record_enabled ();
 }
 
 void
@@ -160,7 +162,7 @@ MidiTrack::midi_diskstream() const
 int
 MidiTrack::set_state (const XMLNode& node, int version)
 {
-       const XMLProperty *prop;
+       XMLProperty const * prop;
 
        /* This must happen before Track::set_state(), as there will be a buffer
           fill during that call, and we must fill buffers using the correct
@@ -271,8 +273,8 @@ void
 MidiTrack::set_state_part_two ()
 {
        XMLNode* fnode;
-       XMLProperty* prop;
-       LocaleGuard lg (X_("C"));
+       XMLProperty const * prop;
+       LocaleGuard lg;
 
        /* This is called after all session state has been restored but before
           have been made ports and connections are established.
@@ -371,7 +373,7 @@ MidiTrack::roll (pframes_t nframes, framepos_t start_frame, framepos_t end_frame
 
        if (!_active) {
                silence (nframes);
-               if (_meter_point == MeterInput && (_monitoring & MonitorInput || _diskstream->record_enabled())) {
+               if (_meter_point == MeterInput && ((_monitoring_control->monitoring_choice() & MonitorInput) || _diskstream->record_enabled())) {
                        _meter->reset();
                }
                return 0;
@@ -401,8 +403,8 @@ MidiTrack::roll (pframes_t nframes, framepos_t start_frame, framepos_t end_frame
        /* filter captured data before meter sees it */
        _capture_filter.filter (bufs);
 
-       if (_meter_point == MeterInput && (_monitoring & MonitorInput || _diskstream->record_enabled())) {
-               _meter->run (bufs, start_frame, end_frame, nframes, true);
+       if (_meter_point == MeterInput && ((_monitoring_control->monitoring_choice() & MonitorInput) || _diskstream->record_enabled())) {
+               _meter->run (bufs, start_frame, end_frame, 1.0 /*speed()*/, nframes, true);
        }
 
 
@@ -442,12 +444,7 @@ MidiTrack::roll (pframes_t nframes, framepos_t start_frame, framepos_t end_frame
        process_output_buffers (bufs, start_frame, end_frame, nframes,
                                declick, (!diskstream->record_enabled() && !_session.transport_stopped()));
 
-       for (ProcessorList::iterator i = _processors.begin(); i != _processors.end(); ++i) {
-               boost::shared_ptr<Delivery> d = boost::dynamic_pointer_cast<Delivery> (*i);
-               if (d) {
-                       d->flush_buffers (nframes);
-               }
-       }
+       flush_processor_buffers_locked (nframes);
 
        need_butler = diskstream->commit (playback_distance);
 
@@ -533,7 +530,7 @@ MidiTrack::non_realtime_locate (framepos_t pos)
                    (rcontrol = region->control(tcontrol->parameter()))) {
                        const Evoral::Beats pos_beats = bfc.from(pos - origin);
                        if (rcontrol->list()->size() > 0) {
-                               tcontrol->set_value(rcontrol->list()->eval(pos_beats.to_double()));
+                               tcontrol->set_value(rcontrol->list()->eval(pos_beats.to_double()), Controllable::NoGroup);
                        }
                }
        }
@@ -715,15 +712,7 @@ MidiTrack::set_parameter_automation_state (Evoral::Parameter param, AutoState st
 }
 
 void
-MidiTrack::MidiControl::set_value(double val)
-{
-       if (writable()) {
-               set_value_unchecked (val);
-       }
-}
-
-void
-MidiTrack::MidiControl::set_value_unchecked(double val)
+MidiTrack::MidiControl::actually_set_value (double val, PBD::Controllable::GroupControlDisposition group_override)
 {
        const Evoral::Parameter &parameter = _list ? _list->parameter() : Control::parameter();
        const Evoral::ParameterDescriptor &desc = EventTypeMap::instance().descriptor(parameter);
@@ -780,7 +769,7 @@ MidiTrack::MidiControl::set_value_unchecked(double val)
                _route->write_immediate_event(size,  ev);
        }
 
-       AutomationControl::set_value(val);
+       AutomationControl::actually_set_value(val, group_override);
 }
 
 void
@@ -916,7 +905,7 @@ MidiTrack::act_on_mute ()
                return;
        }
 
-       if (muted() || _mute_master->muted_by_others_at(MuteMaster::AllPoints)) {
+       if (muted() || _mute_master->muted_by_others_soloing_at (MuteMaster::AllPoints)) {
                /* only send messages for channels we are using */
 
                uint16_t mask = _playback_filter.get_channel_mask();
@@ -940,30 +929,27 @@ MidiTrack::act_on_mute ()
 }
 
 void
-MidiTrack::set_monitoring (MonitorChoice mc)
+MidiTrack::monitoring_changed (bool self, Controllable::GroupControlDisposition gcd)
 {
-       if (mc != _monitoring) {
-
-               Track::set_monitoring (mc);
+       Track::monitoring_changed (self, gcd);
 
-               /* monitoring state changed, so flush out any on notes at the
-                * port level.
-                */
+       /* monitoring state changed, so flush out any on notes at the
+        * port level.
+        */
 
-               PortSet& ports (_output->ports());
+       PortSet& ports (_output->ports());
 
-               for (PortSet::iterator p = ports.begin(); p != ports.end(); ++p) {
-                       boost::shared_ptr<MidiPort> mp = boost::dynamic_pointer_cast<MidiPort> (*p);
-                       if (mp) {
-                               mp->require_resolve ();
-                       }
+       for (PortSet::iterator p = ports.begin(); p != ports.end(); ++p) {
+               boost::shared_ptr<MidiPort> mp = boost::dynamic_pointer_cast<MidiPort> (*p);
+               if (mp) {
+                       mp->require_resolve ();
                }
+       }
 
-               boost::shared_ptr<MidiDiskstream> md (midi_diskstream());
+       boost::shared_ptr<MidiDiskstream> md (midi_diskstream());
 
-               if (md) {
-                       md->reset_tracker ();
-               }
+       if (md) {
+               md->reset_tracker ();
        }
 }
 
@@ -976,4 +962,3 @@ MidiTrack::monitoring_state () const
        }
        return ms;
 }
-