gain_t* gab = _gain_automation_buffer;
assert (gab);
+ /* see note in PluginInsert::connect_and_run -- emit Changed signal */
+ _gain_control->set_value_unchecked (gab[0]);
+
if (_midi_amp) {
for (BufferSet::midi_iterator i = bufs.midi_begin(); i != bufs.midi_end(); ++i) {
MidiBuffer& mb (*i);
_current_gain = Amp::apply_gain (bufs, _session.nominal_frame_rate(), nframes, _current_gain, dg, _midi_amp);
+ /* see note in PluginInsert::connect_and_run ()
+ * set_value_unchecked() won't emit a signal since the value is effectively unchanged
+ */
+
+ _gain_control->Changed (false, PBD::Controllable::NoGroup);
+
} else if (_current_gain != GAIN_COEFF_UNITY) {
/* gain has not changed, but its non-unity */
Automatable(Session&);
Automatable (const Automatable& other);
- virtual ~Automatable();
+ virtual ~Automatable();
boost::shared_ptr<Evoral::Control> control_factory(const Evoral::Parameter& id);
virtual bool find_next_event (double start, double end, Evoral::ControlEvent& ev, bool only_active = true) const;
void clear_controls ();
- virtual void transport_located (framepos_t now);
+ virtual void transport_located (framepos_t now);
virtual void transport_stopped (framepos_t now);
+ virtual void automation_run (framepos_t, pframes_t);
+
virtual std::string describe_parameter(Evoral::Parameter param);
AutoState get_parameter_automation_state (Evoral::Parameter param);
PBD::Signal0<void> AutomationStateChanged;
- protected:
+protected:
Session& _a_session;
void can_automate(Evoral::Parameter);
* if false, the method need not bother writing to @a bufs if it doesn't want to.
*/
virtual void run (BufferSet& /*bufs*/, framepos_t /*start_frame*/, framepos_t /*end_frame*/, double speed, pframes_t /*nframes*/, bool /*result_required*/) {}
- virtual void silence (framecnt_t /*nframes*/, framepos_t /*start_frame*/) {}
+ virtual void silence (framecnt_t nframes, framepos_t start_frame) { automation_run (start_frame, nframes); }
virtual void activate () { _pending_active = true; ActiveChanged(); }
virtual void deactivate () { _pending_active = false; ActiveChanged(); }
boost::shared_ptr<AutomationControl> c
= boost::dynamic_pointer_cast<AutomationControl>(li->second);
if (c) {
- boost::shared_ptr<AutomationList> l
+ boost::shared_ptr<AutomationList> l
= boost::dynamic_pointer_cast<AutomationList>(c->list());
if (l) {
}
}
+void
+Automatable::automation_run (framepos_t start, pframes_t nframes)
+{
+ for (Controls::iterator li = controls().begin(); li != controls().end(); ++li) {
+ boost::shared_ptr<AutomationControl> c =
+ boost::dynamic_pointer_cast<AutomationControl>(li->second);
+ if (!c) {
+ continue;
+ }
+ c->automation_run (start, nframes);
+ }
+}
+
boost::shared_ptr<Evoral::Control>
Automatable::control_factory(const Evoral::Parameter& param)
{
}
} else {
AutomationWatch::instance().remove_automation_watch (shared_from_this());
+ Changed (false, Controllable::NoGroup);
}
}
}
} else {
bypass (bufs, nframes);
+ automation_run (start_frame, nframes);
_delaybuffers.flush ();
}
return;
}
- _mute_control->automation_run (start_frame, nframes);
+ automation_run (start_frame, nframes);
/* figure out if we're going to use gain automation */
if (gain_automation_ok) {
_output->silence (nframes);
+ // update owned automated controllables
+ automation_run (now, nframes);
+
for (ProcessorList::iterator i = _processors.begin(); i != _processors.end(); ++i) {
boost::shared_ptr<PluginInsert> pi;
if (!_active && (pi = boost::dynamic_pointer_cast<PluginInsert> (*i)) != 0) {
- // skip plugins, they don't need anything when we're not active
+ /* evaluate automated automation controls */
+ pi->automation_run (now, nframes);
+ /* skip plugins, they don't need anything when we're not active */
continue;
}
#include "ardour/slave.h"
#include "ardour/ticker.h"
#include "ardour/types.h"
+#include "ardour/vca.h"
+#include "ardour/vca_manager.h"
#include "midi++/mmc.h"
ltc_tx_send_time_code_for_cycle (_transport_frame, end_frame, _target_transport_speed, _transport_speed, nframes);
+ VCAList v = _vca_manager->vcas ();
+ for (VCAList::const_iterator i = v.begin(); i != v.end(); ++i) {
+ (*i)->automation_run (_transport_frame, nframes);
+ }
+
if (_process_graph) {
DEBUG_TRACE(DEBUG::ProcessThreads,"calling graph/no-roll\n");
_process_graph->routes_no_roll( nframes, _transport_frame, end_frame, non_realtime_work_pending(), declick);
const framepos_t start_frame = _transport_frame;
const framepos_t end_frame = _transport_frame + floor (nframes * _transport_speed);
+ VCAList v = _vca_manager->vcas ();
+ for (VCAList::const_iterator i = v.begin(); i != v.end(); ++i) {
+ (*i)->automation_run (start_frame, nframes);
+ }
+
if (_process_graph) {
DEBUG_TRACE(DEBUG::ProcessThreads,"calling graph/process-routes\n");
if (_process_graph->process_routes (nframes, start_frame, end_frame, declick, need_butler) < 0) {
const framepos_t start_frame = _transport_frame;
const framepos_t end_frame = _transport_frame + lrintf(nframes * _transport_speed);
+ VCAList v = _vca_manager->vcas ();
+ for (VCAList::const_iterator i = v.begin(); i != v.end(); ++i) {
+ (*i)->automation_run (start_frame, nframes);
+ }
+
if (_process_graph) {
_process_graph->silent_process_routes (nframes, start_frame, end_frame, need_butler);
} else {