X-Git-Url: https://main.carlh.net/gitweb/?a=blobdiff_plain;f=libs%2Fardour%2Fmidi_track.cc;h=d3653dc929d279422422bde635660f9d6ce2b7af;hb=9e5b7db89f381c70232fab35dc21fd885863f998;hp=3f154644812345e4bf56d641c1f3d07621c805b9;hpb=546cd974ec2d90f64dcaae6f347e68c6682117b9;p=ardour.git diff --git a/libs/ardour/midi_track.cc b/libs/ardour/midi_track.cc index 3f15464481..d3653dc929 100644 --- a/libs/ardour/midi_track.cc +++ b/libs/ardour/midi_track.cc @@ -47,6 +47,7 @@ #include "ardour/parameter_types.h" #include "ardour/port.h" #include "ardour/processor.h" +#include "ardour/profile.h" #include "ardour/session.h" #include "ardour/session_playlists.h" #include "ardour/utils.h" @@ -102,13 +103,23 @@ MidiTrack::create_diskstream () void -MidiTrack::set_record_enabled (bool yn, void *src) +MidiTrack::set_record_enabled (bool yn, Controllable::GroupControlDisposition group_override) { if (_step_editing) { return; } - Track::set_record_enabled (yn, src); + Track::set_record_enabled (yn, group_override); +} + +void +MidiTrack::set_record_safe (bool yn, Controllable::GroupControlDisposition group_override) +{ + if (_step_editing) { /* REQUIRES REVIEW */ + return; + } + + Track::set_record_safe (yn, group_override); } void @@ -119,13 +130,17 @@ MidiTrack::set_diskstream (boost::shared_ptr ds) */ boost::shared_ptr mds = boost::dynamic_pointer_cast (ds); mds->set_note_mode (_note_mode); - + Track::set_diskstream (ds); - mds->reset_tracker (); + mds->reset_tracker (); _diskstream->set_track (this); - _diskstream->set_destructive (_mode == Destructive); + if (Profile->get_trx()) { + _diskstream->set_destructive (false); + } else { + _diskstream->set_destructive (_mode == Destructive); + } _diskstream->set_record_enabled (false); _diskstream_data_recorded_connection.disconnect (); @@ -341,7 +356,7 @@ MidiTrack::roll (pframes_t nframes, framepos_t start_frame, framepos_t end_frame if (!lm.locked()) { boost::shared_ptr diskstream = midi_diskstream(); framecnt_t playback_distance = diskstream->calculate_playback_distance(nframes); - if (can_internal_playback_seek(llabs(playback_distance))) { + if (can_internal_playback_seek(::llabs(playback_distance))) { /* TODO should declick, and/or note-off */ internal_playback_seek(playback_distance); } @@ -379,6 +394,16 @@ MidiTrack::roll (pframes_t nframes, framepos_t start_frame, framepos_t end_frame return dret; } + if (_mute_control->list() && _mute_control->automation_playback()) { + bool valid = false; + const float mute = _mute_control->list()->rt_safe_eval(transport_frame, valid); + if (mute >= 0.5 && !muted()) { + _mute_control->set_value_unchecked(1.0); // mute + } else if (mute < 0.5 && muted()) { + _mute_control->set_value_unchecked(0.0); // unmute + } + } + BufferSet& bufs = _session.get_route_buffers (n_process_buffers()); fill_buffers_with_input (bufs, _input, nframes); @@ -415,15 +440,15 @@ MidiTrack::roll (pframes_t nframes, framepos_t start_frame, framepos_t end_frame diskstream->flush_playback (start_frame, end_frame); - } + } + - /* append immediate messages to the first MIDI buffer (thus sending it to the first output port) */ - + write_out_of_band_data (bufs, start_frame, end_frame, nframes); - + /* final argument: don't waste time with automation if we're not recording or rolling */ - + process_output_buffers (bufs, start_frame, end_frame, nframes, declick, (!diskstream->record_enabled() && !_session.transport_stopped())); @@ -435,7 +460,7 @@ MidiTrack::roll (pframes_t nframes, framepos_t start_frame, framepos_t end_frame } need_butler = diskstream->commit (playback_distance); - + return 0; } @@ -498,6 +523,11 @@ MidiTrack::non_realtime_locate (framepos_t pos) return; } + /* the source may be missing, but the control still referenced in the GUI */ + if (!region->midi_source() || !region->model()) { + return; + } + Glib::Threads::Mutex::Lock lm (_control_lock, Glib::Threads::TRY_LOCK); if (!lm.locked()) { return; @@ -512,7 +542,9 @@ MidiTrack::non_realtime_locate (framepos_t pos) if ((tcontrol = boost::dynamic_pointer_cast(c->second)) && (rcontrol = region->control(tcontrol->parameter()))) { const Evoral::Beats pos_beats = bfc.from(pos - origin); - tcontrol->set_value(rcontrol->list()->eval(pos_beats.to_double())); + if (rcontrol->list()->size() > 0) { + tcontrol->set_value(rcontrol->list()->eval(pos_beats.to_double()), Controllable::NoGroup); + } } } } @@ -693,7 +725,22 @@ MidiTrack::set_parameter_automation_state (Evoral::Parameter param, AutoState st } void -MidiTrack::MidiControl::set_value(double val) +MidiTrack::MidiControl::set_value (double val, PBD::Controllable::GroupControlDisposition group_override) +{ + if (writable()) { + _set_value (val, group_override); + } +} + +void +MidiTrack::MidiControl::set_value_unchecked (double val) +{ + /* used only by automation playback */ + _set_value (val, Controllable::NoGroup); +} + +void +MidiTrack::MidiControl::_set_value (double val, PBD::Controllable::GroupControlDisposition group_override) { const Evoral::Parameter ¶meter = _list ? _list->parameter() : Control::parameter(); const Evoral::ParameterDescriptor &desc = EventTypeMap::instance().descriptor(parameter); @@ -750,7 +797,7 @@ MidiTrack::MidiControl::set_value(double val) _route->write_immediate_event(size, ev); } - AutomationControl::set_value(val); + AutomationControl::set_value(val, group_override); } void @@ -905,23 +952,23 @@ MidiTrack::act_on_mute () } /* Resolve active notes. */ - midi_diskstream()->resolve_tracker(_immediate_events, 0); + midi_diskstream()->resolve_tracker(_immediate_events, Port::port_offset()); } } - + void MidiTrack::set_monitoring (MonitorChoice mc) { if (mc != _monitoring) { Track::set_monitoring (mc); - + /* monitoring state changed, so flush out any on notes at the * port level. */ PortSet& ports (_output->ports()); - + for (PortSet::iterator p = ports.begin(); p != ports.end(); ++p) { boost::shared_ptr mp = boost::dynamic_pointer_cast (*p); if (mp) { @@ -930,7 +977,7 @@ MidiTrack::set_monitoring (MonitorChoice mc) } boost::shared_ptr md (midi_diskstream()); - + if (md) { md->reset_tracker (); } @@ -943,7 +990,7 @@ MidiTrack::monitoring_state () const MonitorState ms = Track::monitoring_state(); if (ms == MonitoringSilence) { return MonitoringInput; - } + } return ms; }