Pass current (latency compensated) cycle times to plugin.
This fixes time-reporting to plugins and also fixes automation
and when bouncing (the session->transport* is not valid) etc.
ARDOUR::ChanMapping out_map(_plugin->get_info()->n_outputs);
_plugin->set_block_size (_buffer_size);
- _plugin->connect_and_run(_bufferset, in_map, out_map, _buffer_size, 0);
+ _plugin->connect_and_run(_bufferset, 0, _buffer_size, 1.0, in_map, out_map, _buffer_size, 0);
framecnt_t f = _plugin->signal_latency ();
// Adding user_latency() could be interesting
in_map = ARDOUR::ChanMapping(_plugin->get_info()->n_inputs);
out_map = ARDOUR::ChanMapping(_plugin->get_info()->n_outputs);
- _plugin->connect_and_run(_bufferset, in_map, out_map, _buffer_size, 0);
+ _plugin->connect_and_run (_bufferset, target_offset, target_offset + _buffer_size, 1.0, in_map, out_map, _buffer_size, 0);
}
} while ( frames_left > 0);
}
void
-Amp::run (BufferSet& bufs, framepos_t /*start_frame*/, framepos_t /*end_frame*/, pframes_t nframes, bool)
+Amp::run (BufferSet& bufs, framepos_t /*start_frame*/, framepos_t /*end_frame*/, double /*speed*/, pframes_t nframes, bool)
{
if (!_active && !_pending_active) {
return;
bool can_support_io_configuration (const ChanCount& in, ChanCount& out);
bool configure_io (ChanCount in, ChanCount out);
- void run (BufferSet& bufs, framepos_t start_frame, framepos_t end_frame, pframes_t nframes, bool);
+ void run (BufferSet& bufs, framepos_t start_frame, framepos_t end_frame, double speed, pframes_t nframes, bool);
bool apply_gain () const { return _apply_gain; }
void apply_gain (bool yn) { _apply_gain = yn; }
std::vector<std::pair<int,int> > io_configs;
pframes_t _current_block_size;
framecnt_t _last_nframes;
+ framepos_t _transport_frame;
+ framepos_t _transport_speed;
bool _requires_fixed_size_buffers;
AudioBufferList* buffers;
bool _has_midi_input;
void discover_factory_presets ();
- bool last_transport_rolling;
- float last_transport_speed;
+ framepos_t transport_frame;
+ float transport_speed;
+ floa t last_transport_speed;
static void _parameter_change_listener (void* /*arg*/, void* /*src*/, const AudioUnitEvent* event, UInt64 host_time, Float32 new_value);
void parameter_change_listener (void* /*arg*/, void* /*src*/, const AudioUnitEvent* event, UInt64 host_time, Float32 new_value);
public: // Processor overrides
bool display_to_user() const { return false; }
int set_block_size (pframes_t nframes);
- void run (BufferSet& bufs, framepos_t start_frame, framepos_t end_frame, pframes_t nframes, bool result_required);
+ void run (BufferSet& bufs, framepos_t start_frame, framepos_t end_frame, double speed, pframes_t nframes, bool result_required);
bool configure_io (ChanCount in, ChanCount out);
bool can_support_io_configuration (const ChanCount& in, ChanCount& out);
virtual XMLNode& state (bool);
bool display_to_user() const { return false; }
- void run (BufferSet&, framepos_t, framepos_t, pframes_t, bool);
+ void run (BufferSet&, framepos_t, framepos_t, double, pframes_t, bool);
void set_delay(framecnt_t signal_delay);
framecnt_t get_delay() { return _pending_delay; }
bool can_support_io_configuration (const ChanCount& in, ChanCount& out);
bool configure_io (ChanCount in, ChanCount out);
- void run (BufferSet& bufs, framepos_t start_frame, framepos_t end_frame, pframes_t nframes, bool);
+ void run (BufferSet& bufs, framepos_t start_frame, framepos_t end_frame, double speed, pframes_t nframes, bool);
/* supplemental method used with MIDI */
XMLNode& state (bool full);
XMLNode& get_state ();
- void run (BufferSet& bufs, framepos_t start_frame, framepos_t end_frame, pframes_t nframes, bool);
+ void run (BufferSet& bufs, framepos_t start_frame, framepos_t end_frame, double speed, pframes_t nframes, bool);
bool configure_io (ChanCount, ChanCount);
bool can_support_io_configuration (const ChanCount& in, ChanCount& out);
int set_state(const XMLNode& node, int version);
void cycle_start (pframes_t);
- void run (BufferSet& bufs, framepos_t start_frame, framepos_t end_frame, pframes_t nframes, bool);
+ void run (BufferSet& bufs, framepos_t start_frame, framepos_t end_frame, double speed, pframes_t nframes, bool);
bool feeds (boost::shared_ptr<Route> other) const;
bool can_support_io_configuration (const ChanCount& in, ChanCount& out);
bool configure_io (ChanCount in, ChanCount out);
/* three utility functions - this just seems to be simplest place to put them */
void collect_input (BufferSet& bufs, pframes_t nframes, ChanCount offset);
- void process_input (boost::shared_ptr<Processor>, framepos_t start_frame, framepos_t end_frame, pframes_t nframes);
+ void process_input (boost::shared_ptr<Processor>, framepos_t start_frame, framepos_t end_frame, double speed, pframes_t nframes);
void copy_to_outputs (BufferSet& bufs, DataType type, pframes_t nframes, framecnt_t offset);
/* AudioTrack::deprecated_use_diskstream_connections() needs these */
void set_input (boost::shared_ptr<IO>);
void set_output (boost::shared_ptr<IO>);
- void silence (framecnt_t nframes);
+ void silence (framecnt_t nframes, framepos_t start_frame);
void disconnect ();
void increment_port_buffer_offset (pframes_t);
int set_block_size (pframes_t /*nframes*/) { return 0; }
int connect_and_run (BufferSet& bufs,
+ framepos_t start, framepos_t end, double speed,
ChanMapping in, ChanMapping out,
pframes_t nframes, framecnt_t offset);
framecnt_t signal_latency() const { return 0; }
int connect_and_run (BufferSet& bufs,
+ framepos_t start, framepos_t end, double speed,
ChanMapping in, ChanMapping out,
pframes_t nframes, framecnt_t offset);
bool requires_fixed_sized_buffers () const;
int connect_and_run (BufferSet& bufs,
+ framepos_t start, framepos_t end, double speed,
ChanMapping in, ChanMapping out,
pframes_t nframes, framecnt_t offset);
void emit_configuration_changed ();
/** Compute peaks */
- void run (BufferSet& bufs, framepos_t start_frame, framepos_t end_frame, pframes_t nframes, bool);
+ void run (BufferSet& bufs, framepos_t start_frame, framepos_t end_frame, double speed, pframes_t nframes, bool);
void activate () { }
void deactivate () { }
bool display_to_user() const;
- void run (BufferSet& /*bufs*/, framepos_t /*start_frame*/, framepos_t /*end_frame*/, pframes_t /*nframes*/, bool /*result_required*/);
+ void run (BufferSet& /*bufs*/, framepos_t /*start_frame*/, framepos_t /*end_frame*/, double /*speed*/, pframes_t /*nframes*/, bool /*result_required*/);
XMLNode& state (bool full);
int set_state (const XMLNode&, int /* version */);
virtual bool inplace_broken() const { return false; }
virtual int connect_and_run (BufferSet& bufs,
- ChanMapping in, ChanMapping out,
- pframes_t nframes, framecnt_t offset);
+ framepos_t start, framepos_t end, double speed,
+ ChanMapping in, ChanMapping out,
+ pframes_t nframes, framecnt_t offset);
virtual std::set<Evoral::Parameter> automatable() const = 0;
virtual std::string describe_parameter (Evoral::Parameter) = 0;
void update_id (PBD::ID);
void set_state_dir (const std::string& d = "");
- void run (BufferSet& in, framepos_t start_frame, framepos_t end_frame, pframes_t nframes, bool);
- void silence (framecnt_t nframes);
+ void run (BufferSet& in, framepos_t start_frame, framepos_t end_frame, double speed, pframes_t nframes, bool);
+ void silence (framecnt_t nframes, framepos_t start_frame);
void activate ();
void deactivate ();
PinMappings _out_map;
ChanMapping _thru_map; // out-idx <= in-idx
- void automation_run (BufferSet& bufs, framepos_t start, pframes_t nframes);
- void connect_and_run (BufferSet& bufs, pframes_t nframes, framecnt_t offset, bool with_auto, framepos_t now = 0);
+ void automation_run (BufferSet& bufs, framepos_t start, framepos_t end, double speed, pframes_t nframes);
+ void connect_and_run (BufferSet& bufs, framepos_t start, framecnt_t end, double speed, pframes_t nframes, framecnt_t offset, bool with_auto);
void bypass (BufferSet& bufs, pframes_t nframes);
void inplace_silence_unconnected (BufferSet&, const PinMappings&, framecnt_t nframes, framecnt_t offset) const;
XMLNode& get_state(void);
int set_state (const XMLNode&, int version);
- void run (BufferSet& bufs, framepos_t start_frame, framepos_t end_frame, pframes_t nframes, bool);
+ void run (BufferSet& bufs, framepos_t start_frame, framepos_t end_frame, double speed, pframes_t nframes, bool);
framecnt_t signal_latency () const;
/** @param result_required true if, on return from this method, @a bufs is required to contain valid data;
* 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*/, pframes_t /*nframes*/, bool /*result_required*/) {}
- virtual void silence (framecnt_t /*nframes*/) {}
+ 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 activate () { _pending_active = true; ActiveChanged(); }
virtual void deactivate () { _pending_active = false; ActiveChanged(); }
uint32_t bit_slot() const { return _bitslot; }
- void run (BufferSet& bufs, framepos_t start_frame, framepos_t end_frame, pframes_t nframes, bool);
+ void run (BufferSet& bufs, framepos_t start_frame, framepos_t end_frame, double speed, pframes_t nframes, bool);
boost::shared_ptr<Amp> amp() const { return _amp; }
boost::shared_ptr<PeakMeter> meter() const { return _meter; }
uint32_t pans_required() const { return _configured_input.n_audio(); }
- void run (BufferSet& bufs, framepos_t start_frame, framepos_t end_frame, pframes_t nframes, bool);
+ void run (BufferSet& bufs, framepos_t start_frame, framepos_t end_frame, double speed, pframes_t nframes, bool);
bool can_support_io_configuration (const ChanCount& in, ChanCount& out);
bool configure_io (ChanCount in, ChanCount out);
bool synced_to_ltc () const { return config.get_external_sync() && Config->get_sync_source() == LTC && g_atomic_int_get (const_cast<gint*>(&_ltc_active)); }
double transport_speed() const { return _transport_speed; }
- bool transport_stopped() const { return _transport_speed == 0.0f; }
- bool transport_rolling() const { return _transport_speed != 0.0f; }
+ bool transport_stopped() const { return _transport_speed == 0.0; }
+ bool transport_rolling() const { return _transport_speed != 0.0; }
bool silent () { return _silent; }
SideChain (Session&, const std::string&);
virtual ~SideChain ();
- void run (BufferSet& bufs, framepos_t start_frame, framepos_t end_frame, pframes_t nframes, bool);
+ void run (BufferSet& bufs, framepos_t start_frame, framepos_t end_frame, double speed, pframes_t nframes, bool);
bool can_support_io_configuration (const ChanCount& in, ChanCount& out);
bool configure_io (ChanCount in, ChanCount out);
virtual ~UnknownProcessor ();
bool can_support_io_configuration (const ChanCount &, ChanCount &);
- void run (BufferSet& /*bufs*/, framepos_t /*start_frame*/, framepos_t /*end_frame*/, pframes_t /*nframes*/, bool /*result_required*/);
+ void run (BufferSet& /*bufs*/, framepos_t /*start_frame*/, framepos_t /*end_frame*/, double /*speed*/, pframes_t /*nframes*/, bool /*result_required*/);
XMLNode & state (bool);
bool parameter_is_input (uint32_t) const { return true; }
bool parameter_is_output (uint32_t) const { return false; }
- int connect_and_run (
- BufferSet&, ChanMapping in, ChanMapping out,
- pframes_t nframes, framecnt_t offset
- );
+ int connect_and_run (BufferSet&,
+ framepos_t start, framepos_t end, double speed,
+ ChanMapping in, ChanMapping out,
+ pframes_t nframes, framecnt_t offset
+ );
std::string unique_id () const;
const char * label () const;
PluginInsert* plugin_insert () const { return _pi; }
uint32_t plugin_number () const { return _num; }
VstTimeInfo* timeinfo () { return &_timeInfo; }
+ framepos_t transport_frame () const { return _transport_frame; }
+ float transport_speed () const { return _transport_speed; }
protected:
MidiBuffer* _midi_out_buf;
VstTimeInfo _timeInfo;
+
+ framepos_t _transport_frame;
+ float _transport_speed;
};
}
fill_buffers_with_input (bufs, _input, nframes);
if (_meter_point == MeterInput && ((_monitoring_control->monitoring_choice() & MonitorInput) || _diskstream->record_enabled())) {
- _meter->run (bufs, start_frame, end_frame, nframes, true);
+ _meter->run (bufs, start_frame, end_frame, 1.0 /*speed()*/, nframes, true);
}
if ((dret = diskstream->process (bufs, transport_frame, nframes, playback_distance, (monitoring_state() == MonitoringDisk))) != 0) {
, audio_input_cnt (0)
, _parameter_listener (0)
, _parameter_listener_arg (0)
- , last_transport_rolling (false)
+ , transport_frame (false)
+ , transport_speed (false)
, last_transport_speed (0.0)
{
if (!preset_search_path_initialized) {
}
int
-AUPlugin::connect_and_run (BufferSet& bufs, ChanMapping in_map, ChanMapping out_map, pframes_t nframes, framecnt_t offset)
+AUPlugin::connect_and_run (BufferSet& bufs,
+ framepos_t start, framepos_t end, double speed,
+ ChanMapping in_map, ChanMapping out_map,
+ pframes_t nframes, framecnt_t offset)
{
- Plugin::connect_and_run (bufs, in_map, out_map, nframes, offset);
+ Plugin::connect_and_run(bufs, start, end, speed, in_map, out_map, nframes, offset);
+
+ transport_frame = start;
+ transport_speed = speed;
AudioUnitRenderActionFlags flags = 0;
AudioTimeStamp ts;
return kAudioUnitErr_CannotDoInCurrentContext;
}
- TempoMetric metric = tmap.metric_at (_session.transport_frame() + input_offset);
- Timecode::BBT_Time bbt = _session.tempo_map().bbt_at_frame (_session.transport_frame() + input_offset);
+ TempoMetric metric = tmap.metric_at (transport_frame + input_offset);
+ Timecode::BBT_Time bbt = _session.tempo_map().bbt_at_frame (transport_frame + input_offset);
if (outCurrentBeat) {
const double ppq_scaling = metric.meter().note_divisor() / 4.0;
return kAudioUnitErr_CannotDoInCurrentContext;
}
- TempoMetric metric = tmap.metric_at (_session.transport_frame() + input_offset);
- Timecode::BBT_Time bbt = _session.tempo_map().bbt_at_frame (_session.transport_frame() + input_offset);
+ TempoMetric metric = tmap.metric_at (transport_frame + input_offset);
+ Timecode::BBT_Time bbt = _session.tempo_map().bbt_at_frame (transport_frame + input_offset);
if (outDeltaSampleOffsetToNextBeat) {
if (bbt.ticks == 0) {
*outDeltaSampleOffsetToNextBeat = 0;
} else {
double const beat_frac_to_next = (Timecode::BBT_Time::ticks_per_beat - bbt.ticks) / Timecode::BBT_Time::ticks_per_beat;
- *outDeltaSampleOffsetToNextBeat = tmap.frame_at_beat (tmap.beat_at_frame (_session.transport_frame() + input_offset) + beat_frac_to_next);
+ *outDeltaSampleOffsetToNextBeat = tmap.frame_at_beat (tmap.beat_at_frame (transport_frame + input_offset) + beat_frac_to_next);
}
}
Float64* outCycleStartBeat,
Float64* outCycleEndBeat)
{
- bool rolling;
- float speed;
+ const bool rolling = (transport_speed != 0);
+ const bool last_transport_rolling = (last_transport_speed != 0);
DEBUG_TRACE (DEBUG::AudioUnits, "AU calls ardour transport state callback\n");
- rolling = _session.transport_rolling();
- speed = _session.transport_speed ();
if (outIsPlaying) {
- *outIsPlaying = _session.transport_rolling();
+ *outIsPlaying = rolling;
}
if (outTransportStateChanged) {
if (rolling != last_transport_rolling) {
*outTransportStateChanged = true;
- } else if (speed != last_transport_speed) {
+ } else if (transport_speed != last_transport_speed) {
*outTransportStateChanged = true;
} else {
*outTransportStateChanged = false;
/* this assumes that the AU can only call this host callback from render context,
where input_offset is valid.
*/
- *outCurrentSampleInTimeLine = _session.transport_frame() + input_offset;
+ *outCurrentSampleInTimeLine = transport_frame + input_offset;
}
if (outIsCycling) {
+ // TODO check bounce-processing
Location* loc = _session.locations()->auto_loop_location();
- *outIsCycling = (loc && _session.transport_rolling() && _session.get_play_loop());
+ *outIsCycling = (loc && rolling && _session.get_play_loop());
if (*outIsCycling) {
}
}
- last_transport_rolling = rolling;
- last_transport_speed = speed;
+ last_transport_speed = transport_speed;
return noErr;
}
}
void
-CapturingProcessor::run (BufferSet& bufs, framepos_t, framepos_t, pframes_t nframes, bool)
+CapturingProcessor::run (BufferSet& bufs, framepos_t, framepos_t, double, pframes_t nframes, bool)
{
if (active()) {
capture_buffers.read_from (bufs, nframes);
#define FADE_LEN (16)
void
-DelayLine::run (BufferSet& bufs, framepos_t /* start_frame */, framepos_t /* end_frame */, pframes_t nsamples, bool)
+DelayLine::run (BufferSet& bufs, framepos_t /* start_frame */, framepos_t /* end_frame */, double /* speed */, pframes_t nsamples, bool)
{
const uint32_t chn = _configured_output.n_audio();
pframes_t p0 = 0;
}
void
-Delivery::run (BufferSet& bufs, framepos_t start_frame, framepos_t end_frame, pframes_t nframes, bool result_required)
+Delivery::run (BufferSet& bufs, framepos_t start_frame, framepos_t end_frame, double /*speed*/, pframes_t nframes, bool result_required)
{
assert (_output);
}
void
-InternalReturn::run (BufferSet& bufs, framepos_t /*start_frame*/, framepos_t /*end_frame*/, pframes_t nframes, bool)
+InternalReturn::run (BufferSet& bufs, framepos_t /*start_frame*/, framepos_t /*end_frame*/, double /*speed*/, pframes_t nframes, bool)
{
if (!_active && !_pending_active) {
return;
}
void
-InternalSend::run (BufferSet& bufs, framepos_t start_frame, framepos_t end_frame, pframes_t nframes, bool)
+InternalSend::run (BufferSet& bufs, framepos_t start_frame, framepos_t end_frame, double speed, pframes_t nframes, bool)
{
if ((!_active && !_pending_active) || !_send_to) {
_meter->reset ();
_amp->set_gain_automation_buffer (_session.send_gain_automation_buffer ());
_amp->setup_gain_automation (start_frame, end_frame, nframes);
- _amp->run (mixbufs, start_frame, end_frame, nframes, true);
+ _amp->run (mixbufs, start_frame, end_frame, speed, nframes, true);
- _delayline->run (mixbufs, start_frame, end_frame, nframes, true);
+ _delayline->run (mixbufs, start_frame, end_frame, speed, nframes, true);
/* consider metering */
if (_amp->gain_control()->get_value() == GAIN_COEFF_ZERO) {
_meter->reset();
} else {
- _meter->run (mixbufs, start_frame, end_frame, nframes, true);
+ _meter->run (mixbufs, start_frame, end_frame, speed, nframes, true);
}
}
* Caller must hold process lock.
*/
void
-IO::process_input (boost::shared_ptr<Processor> proc, framepos_t start_frame, framepos_t end_frame, pframes_t nframes)
+IO::process_input (boost::shared_ptr<Processor> proc, framepos_t start_frame, framepos_t end_frame, double speed, pframes_t nframes)
{
/* don't read the data into new buffers - just use the port buffers directly */
_buffers.get_backend_port_addresses (_ports, nframes);
if (proc) {
- proc->run (_buffers, start_frame, end_frame, nframes, true);
+ proc->run (_buffers, start_frame, end_frame, speed, nframes, true);
}
}
}
void
-IOProcessor::silence (framecnt_t nframes)
+IOProcessor::silence (framecnt_t nframes, framepos_t /* start_frame */)
{
if (_own_output && _output) {
_output->silence (nframes);
int
LadspaPlugin::connect_and_run (BufferSet& bufs,
+ framepos_t start, framepos_t end, double speed,
ChanMapping in_map, ChanMapping out_map,
pframes_t nframes, framecnt_t offset)
{
- Plugin::connect_and_run (bufs, in_map, out_map, nframes, offset);
+ Plugin::connect_and_run (bufs, start, end, speed, in_map, out_map, nframes, offset);
cycles_t now;
cycles_t then = get_cycles ();
int
LuaProc::connect_and_run (BufferSet& bufs,
+ framepos_t start, framepos_t end, double speed,
ChanMapping in, ChanMapping out,
pframes_t nframes, framecnt_t offset)
{
return 0;
}
- Plugin::connect_and_run (bufs, in, out, nframes, offset);
+ Plugin::connect_and_run (bufs, start, end, speed, in, out, nframes, offset);
// This is needed for ARDOUR::Session requests :(
if (! SessionEvent::has_per_thread_pool ()) {
int
LV2Plugin::connect_and_run(BufferSet& bufs,
- ChanMapping in_map, ChanMapping out_map,
- pframes_t nframes, framecnt_t offset)
+ framepos_t start, framepos_t end, double speed,
+ ChanMapping in_map, ChanMapping out_map,
+ pframes_t nframes, framecnt_t offset)
{
DEBUG_TRACE(DEBUG::LV2, string_compose("%1 run %2 offset %3\n", name(), nframes, offset));
- Plugin::connect_and_run(bufs, in_map, out_map, nframes, offset);
+ Plugin::connect_and_run(bufs, start, end, speed, in_map, out_map, nframes, offset);
cycles_t then = get_cycles();
TempoMap& tmap = _session.tempo_map();
Metrics::const_iterator metric_i = tmap.metrics_end();
- TempoMetric tmetric = tmap.metric_at(_session.transport_frame(), &metric_i);
+ TempoMetric tmetric = tmap.metric_at(start, &metric_i);
if (_freewheel_control_port) {
*_freewheel_control_port = _session.engine().freewheeling() ? 1.f : 0.f;
}
#ifdef LV2_EXTENDED
- if (_can_write_automation && _session.transport_frame() != _next_cycle_start) {
+ if (_can_write_automation && start != _next_cycle_start) {
// add guard-points after locating
for (AutomationCtrlMap::iterator i = _ctrl_map.begin(); i != _ctrl_map.end(); ++i) {
i->second->guard = true;
if (valid && (flags & PORT_INPUT)) {
Timecode::BBT_Time bbt;
if ((flags & PORT_POSITION)) {
- if (_session.transport_frame() != _next_cycle_start ||
- _session.transport_speed() != _next_cycle_speed) {
+ if (start != _next_cycle_start ||
+ speed != _next_cycle_speed) {
// Transport has changed, write position at cycle start
- bbt = tmap.bbt_at_frame (_session.transport_frame());
+ bbt = tmap.bbt_at_frame (start);
write_position(&_impl->forge, _ev_buffers[port_index],
- tmetric, bbt, _session.transport_speed(),
- _session.transport_frame(), 0);
+ tmetric, bbt, speed, start, 0);
}
}
// Now merge MIDI and any transport events into the buffer
const uint32_t type = _uri_map.urids.midi_MidiEvent;
- const framepos_t tend = _session.transport_frame() + nframes;
+ const framepos_t tend = end;
++metric_i;
while (m != m_end || (metric_i != tmap.metrics_end() &&
(*metric_i)->frame() < tend)) {
tmetric.set_metric(metric);
bbt = tmap.bbt_at_pulse (metric->pulse());
write_position(&_impl->forge, _ev_buffers[port_index],
- tmetric, bbt, _session.transport_speed(),
+ tmetric, bbt, speed,
metric->frame(),
- metric->frame() - _session.transport_frame());
+ metric->frame() - start);
++metric_i;
}
}
if (c &&
(c->ac->automation_state() == Touch || c->ac->automation_state() == Write)
) {
- framepos_t when = std::max ((framepos_t) 0, _session.transport_frame() + frames - _current_latency);
- assert (_session.transport_frame() + frames - _current_latency >= 0);
+ framepos_t when = std::max ((framepos_t) 0, start + frames - _current_latency);
+ assert (start + frames - _current_latency >= 0);
if (c->guard) {
c->guard = false;
c->ac->list()->add (when, v, true, true);
AutomationCtrlPtr c = get_automation_control (p);
DEBUG_TRACE(DEBUG::LV2Automate, string_compose ("Start Touch p: %1\n", p));
if (c) {
- c->ac->start_touch (std::max ((framepos_t)0, _session.transport_frame() - _current_latency));
+ c->ac->start_touch (std::max ((framepos_t)0, start - _current_latency));
c->guard = true;
}
}
AutomationCtrlPtr c = get_automation_control (p);
DEBUG_TRACE(DEBUG::LV2Automate, string_compose ("End Touch p: %1\n", p));
if (c) {
- c->ac->stop_touch (true, std::max ((framepos_t)0, _session.transport_frame() - _current_latency));
+ c->ac->stop_touch (true, std::max ((framepos_t)0, start - _current_latency));
}
}
}
set_cycles((uint32_t)(now - then));
// Update expected transport information for next cycle so we can detect changes
- _next_cycle_speed = _session.transport_speed();
- _next_cycle_start = _session.transport_frame() + (nframes * _next_cycle_speed);
+ _next_cycle_speed = speed;
+ _next_cycle_start = end;
if (_latency_control_port) {
framecnt_t new_latency = signal_latency ();
* (runs in jack realtime context)
*/
void
-PeakMeter::run (BufferSet& bufs, framepos_t /*start_frame*/, framepos_t /*end_frame*/, pframes_t nframes, bool)
+PeakMeter::run (BufferSet& bufs, framepos_t /*start_frame*/, framepos_t /*end_frame*/, double /*speed*/, pframes_t nframes, bool)
{
if (!_active && !_pending_active) {
return;
_capture_filter.filter (bufs);
if (_meter_point == MeterInput && ((_monitoring_control->monitoring_choice() & MonitorInput) || _diskstream->record_enabled())) {
- _meter->run (bufs, start_frame, end_frame, nframes, true);
+ _meter->run (bufs, start_frame, end_frame, 1.0 /*speed()*/, nframes, true);
}
}
void
-MonitorProcessor::run (BufferSet& bufs, framepos_t /*start_frame*/, framepos_t /*end_frame*/, pframes_t nframes, bool /*result_required*/)
+MonitorProcessor::run (BufferSet& bufs, framepos_t /*start_frame*/, framepos_t /*end_frame*/, double /*speed*/, pframes_t nframes, bool /*result_required*/)
{
uint32_t chn = 0;
gain_t target_gain;
int
Plugin::connect_and_run (BufferSet& bufs,
- ChanMapping /*in_map*/, ChanMapping /*out_map*/,
- pframes_t /* nframes */, framecnt_t /*offset*/)
+ framepos_t /*start*/, framepos_t /*end*/, double /*speed*/,
+ ChanMapping /*in_map*/, ChanMapping /*out_map*/,
+ pframes_t /* nframes */, framecnt_t /*offset*/)
{
if (bufs.count().n_midi() > 0) {
}
void
-PluginInsert::connect_and_run (BufferSet& bufs, pframes_t nframes, framecnt_t offset, bool with_auto, framepos_t now)
+PluginInsert::connect_and_run (BufferSet& bufs, framepos_t start, framepos_t end, double speed, pframes_t nframes, framecnt_t offset, bool with_auto)
{
// TODO: atomically copy maps & _no_inplace
PinMappings in_map (_in_map);
if (c->list() && c->automation_playback()) {
bool valid;
- const float val = c->list()->rt_safe_eval (now, valid);
+ const float val = c->list()->rt_safe_eval (start, valid);
if (valid) {
/* This is the ONLY place where we are
ChanMapping mb_in_map (ChanCount::min (_configured_in, ChanCount (DataType::AUDIO, 2)));
ChanMapping mb_out_map (ChanCount::min (_configured_out, ChanCount (DataType::AUDIO, 2)));
- _plugins.front()->connect_and_run (bufs, mb_in_map, mb_out_map, nframes, offset);
+ _plugins.front()->connect_and_run (bufs, start, end, speed, mb_in_map, mb_out_map, nframes, offset);
for (uint32_t out = _configured_in.n_audio (); out < bufs.count().get (DataType::AUDIO); ++out) {
bufs.get (DataType::AUDIO, out).silence (nframes, offset);
i_out_map.offset_to (*t, natural_input_streams ().get (*t));
}
- if ((*i)->connect_and_run (inplace_bufs, i_in_map, i_out_map, nframes, offset)) {
+ if ((*i)->connect_and_run (inplace_bufs, start, end, speed, i_in_map, i_out_map, nframes, offset)) {
deactivate ();
}
}
/* in-place processing */
uint32_t pc = 0;
for (Plugins::iterator i = _plugins.begin(); i != _plugins.end(); ++i, ++pc) {
- if ((*i)->connect_and_run(bufs, in_map[pc], out_map[pc], nframes, offset)) {
+ if ((*i)->connect_and_run(bufs, start, end, speed, in_map[pc], out_map[pc], nframes, offset)) {
deactivate ();
}
}
}
void
-PluginInsert::silence (framecnt_t nframes)
+PluginInsert::silence (framecnt_t nframes, framepos_t start_frame)
{
if (!active ()) {
return;
#ifdef MIXBUS
if (is_channelstrip ()) {
if (_configured_in.n_audio() > 0) {
- _plugins.front()->connect_and_run (_session.get_scratch_buffers (maxbuf, true), in_map, out_map, nframes, 0);
+ _plugins.front()->connect_and_run (_session.get_scratch_buffers (maxbuf, true), start_frame, start_frame + nframes, 1.0 in_map, out_map, nframes);
}
} else
#endif
for (Plugins::iterator i = _plugins.begin(); i != _plugins.end(); ++i) {
- (*i)->connect_and_run (_session.get_scratch_buffers (maxbuf, true), in_map, out_map, nframes, 0);
+ (*i)->connect_and_run (_session.get_scratch_buffers (maxbuf, true), start_frame, start_frame + nframes, 1.0, in_map, out_map, nframes, 0);
}
}
void
-PluginInsert::run (BufferSet& bufs, framepos_t start_frame, framepos_t end_frame, pframes_t nframes, bool)
+PluginInsert::run (BufferSet& bufs, framepos_t start_frame, framepos_t end_frame, double speed, pframes_t nframes, bool)
{
if (_pending_active) {
/* run as normal if we are active or moving from inactive to active */
if (_sidechain) {
// collect sidechain input for complete cycle (!)
// TODO we need delaylines here for latency compensation
- _sidechain->run (bufs, start_frame, end_frame, nframes, true);
+ _sidechain->run (bufs, start_frame, end_frame, speed, nframes, true);
}
if (_session.transport_rolling() || _session.bounce_processing()) {
- automation_run (bufs, start_frame, nframes);
+ automation_run (bufs, start_frame, end_frame, speed, nframes);
} else {
- connect_and_run (bufs, nframes, 0, false);
+ connect_and_run (bufs, start_frame, end_frame, speed, nframes, 0, false);
}
} else {
}
void
-PluginInsert::automation_run (BufferSet& bufs, framepos_t start, pframes_t nframes)
+PluginInsert::automation_run (BufferSet& bufs, framepos_t start, framepos_t end, double speed, pframes_t nframes)
{
Evoral::ControlEvent next_event (0, 0.0f);
- framepos_t now = start;
- framepos_t end = now + nframes;
framecnt_t offset = 0;
Glib::Threads::Mutex::Lock lm (control_lock(), Glib::Threads::TRY_LOCK);
if (!lm.locked()) {
- connect_and_run (bufs, nframes, offset, false);
+ connect_and_run (bufs, start, end, speed, nframes, offset, false);
return;
}
- if (!find_next_event (now, end, next_event) || _plugins.front()->requires_fixed_sized_buffers()) {
+ if (!find_next_event (start, end, next_event) || _plugins.front()->requires_fixed_sized_buffers()) {
/* no events have a time within the relevant range */
- connect_and_run (bufs, nframes, offset, true, now);
+ connect_and_run (bufs, start, end, speed, nframes, offset, true);
return;
}
while (nframes) {
- framecnt_t cnt = min (((framecnt_t) ceil (next_event.when) - now), (framecnt_t) nframes);
+ framecnt_t cnt = min (((framecnt_t) ceil (next_event.when) - start), (framecnt_t) nframes);
- connect_and_run (bufs, cnt, offset, true, now);
+ connect_and_run (bufs, start, start + cnt, speed, cnt, offset, true); // XXX (start + cnt) * speed
nframes -= cnt;
offset += cnt;
- now += cnt;
+ start += cnt;
- if (!find_next_event (now, end, next_event)) {
+ if (!find_next_event (start, end, next_event)) {
break;
}
}
/* cleanup anything that is left to do */
if (nframes) {
- connect_and_run (bufs, nframes, offset, true, now);
+ connect_and_run (bufs, start, start + nframes, speed, nframes, offset, true);
}
}
}
void
-PortInsert::run (BufferSet& bufs, framepos_t start_frame, framepos_t end_frame, pframes_t nframes, bool)
+PortInsert::run (BufferSet& bufs, framepos_t start_frame, framepos_t end_frame, double speed, pframes_t nframes, bool)
{
if (_output->n_ports().n_total() == 0) {
return;
hear the remnants of whatever MTDM pumped into the pipeline.
*/
- silence (nframes);
+ silence (nframes, start_frame);
if (_latency_flush_frames > nframes) {
_latency_flush_frames -= nframes;
if (!_active && !_pending_active) {
/* deliver silence */
- silence (nframes);
+ silence (nframes, start_frame);
goto out;
}
- _out->run (bufs, start_frame, end_frame, nframes, true);
+ _out->run (bufs, start_frame, end_frame, speed, nframes, true);
_input->collect_input (bufs, nframes, ChanCount::ZERO);
out:
}
void
-Return::run (BufferSet& bufs, framepos_t start_frame, framepos_t end_frame, pframes_t nframes, bool)
+Return::run (BufferSet& bufs, framepos_t start_frame, framepos_t end_frame, double speed, pframes_t nframes, bool)
{
if ((!_active && !_pending_active) || _input->n_ports() == ChanCount::ZERO) {
return;
// Can't automate gain for sends or returns yet because we need different buffers
// so that we don't overwrite the main automation data for the route amp
// _amp->setup_gain_automation (start_frame, end_frame, nframes);
- _amp->run (bufs, start_frame, end_frame, nframes, true);
+ _amp->run (bufs, start_frame, end_frame, speed, nframes, true);
if (_metering) {
if (_amp->gain_control()->get_value() == 0) {
_meter->reset();
} else {
- _meter->run (bufs, start_frame, end_frame, nframes, true);
+ _meter->run (bufs, start_frame, end_frame, speed, nframes, true);
}
}
bool const meter_already_run = metering_state() == MeteringInput;
framecnt_t latency = 0;
+ const double speed = _session.transport_speed ();
for (ProcessorList::const_iterator i = _processors.begin(); i != _processors.end(); ++i) {
_initial_delay + latency, longest_session_latency - latency);
}
- (*i)->run (bufs, start_frame - latency, end_frame - latency, nframes, *i != _processors.back());
+ (*i)->run (bufs, start_frame - latency, end_frame - latency, speed, nframes, *i != _processors.back());
bufs.set_count ((*i)->output_streams());
if ((*i)->active ()) {
_trim->setup_gain_automation (start, start + nframes, nframes);
latency = 0;
+ const double speed = _session.transport_speed ();
for (ProcessorList::iterator i = _processors.begin(); i != _processors.end(); ++i) {
if (!include_endpoint && (*i) == endpoint) {
*/
if ((*i) == _main_outs) {
assert ((*i)->does_routing());
- (*i)->run (buffers, start - latency, start - latency + nframes, nframes, true);
+ (*i)->run (buffers, start - latency, start - latency + nframes, speed, nframes, true);
buffers.set_count ((*i)->output_streams());
}
* Also don't bother with metering.
*/
if (!(*i)->does_routing() && !boost::dynamic_pointer_cast<PeakMeter>(*i)) {
- (*i)->run (buffers, start - latency, start - latency + nframes, nframes, true);
+ (*i)->run (buffers, start - latency, start - latency + nframes, 1.0, nframes, true);
buffers.set_count ((*i)->output_streams());
latency += (*i)->signal_latency ();
}
{
/* Must be called with the processor lock held */
+ const framepos_t now = _session.transport_frame ();
+
if (!_silent) {
_output->silence (nframes);
continue;
}
- (*i)->silence (nframes);
+ (*i)->silence (nframes, now);
}
if (nframes == _session.get_block_size()) {
fill_buffers_with_input (bufs, _input, nframes);
if (_meter_point == MeterInput) {
- _meter->run (bufs, start_frame, end_frame, nframes, true);
+ _meter->run (bufs, start_frame, end_frame, 0.0, nframes, true);
}
_amp->apply_gain_automation (false);
fill_buffers_with_input (bufs, _input, nframes);
if (_meter_point == MeterInput) {
- _meter->run (bufs, start_frame, end_frame, nframes, true);
+ _meter->run (bufs, start_frame, end_frame, 1.0, nframes, true);
}
passthru (bufs, start_frame, end_frame, nframes, declick);
}
void
-Send::run (BufferSet& bufs, framepos_t start_frame, framepos_t end_frame, pframes_t nframes, bool)
+Send::run (BufferSet& bufs, framepos_t start_frame, framepos_t end_frame, double speed, pframes_t nframes, bool)
{
if (_output->n_ports() == ChanCount::ZERO) {
_meter->reset ();
_amp->set_gain_automation_buffer (_session.send_gain_automation_buffer ());
_amp->setup_gain_automation (start_frame, end_frame, nframes);
- _amp->run (sendbufs, start_frame, end_frame, nframes, true);
+ _amp->run (sendbufs, start_frame, end_frame, speed, nframes, true);
- _delayline->run (sendbufs, start_frame, end_frame, nframes, true);
+ _delayline->run (sendbufs, start_frame, end_frame, speed, nframes, true);
/* deliver to outputs */
- Delivery::run (sendbufs, start_frame, end_frame, nframes, true);
+ Delivery::run (sendbufs, start_frame, end_frame, speed, nframes, true);
/* consider metering */
if (_amp->gain_control()->get_value() == 0) {
_meter->reset();
} else {
- _meter->run (*_output_buffers, start_frame, end_frame, nframes, true);
+ _meter->run (*_output_buffers, start_frame, end_frame, speed, nframes, true);
}
}
}
}
- _click_gain->run (bufs, 0, 0, nframes, false);
+ _click_gain->run (bufs, 0, 0, 1.0, nframes, false);
_click_io->copy_to_outputs (bufs, DataType::AUDIO, nframes, 0);
}
timeinfo->nanoSeconds = g_get_monotonic_time () * 1000;
- if (session) {
- framepos_t now = session->transport_frame();
+ if (plug && session) {
+ framepos_t now = plug->transport_frame();
timeinfo->samplePos = now;
timeinfo->sampleRate = session->frame_rate();
newflags |= kVstTransportRecording;
}
- if (session->transport_speed () != 0.0f) {
+ if (plug->transport_speed () != 0.0f) {
newflags |= kVstTransportPlaying;
}
}
void
-SideChain::run (BufferSet& bufs, framepos_t start_frame, framepos_t end_frame, pframes_t nframes, bool)
+SideChain::run (BufferSet& bufs, framepos_t start_frame, framepos_t end_frame, double /*speed*/, pframes_t nframes, bool)
{
if (_input->n_ports () == ChanCount::ZERO) {
// inplace pass-through
if (no_meter) {
BufferSet& bufs (_session.get_silent_buffers (n_process_buffers()));
- _meter->run (bufs, 0, 0, nframes, true);
- _input->process_input (boost::shared_ptr<Processor>(), start_frame, end_frame, nframes);
+ _meter->run (bufs, start_frame, end_frame, 1.0, nframes, true);
+ _input->process_input (boost::shared_ptr<Processor>(), start_frame, end_frame, speed(), nframes);
} else {
- _input->process_input (_meter, start_frame, end_frame, nframes);
+ _input->process_input (_meter, start_frame, end_frame, speed(), nframes);
}
}
fill_buffers_with_input (bufs, _input, nframes);
if (_meter_point == MeterInput) {
- _meter->run (bufs, start_frame, end_frame, nframes, true);
+ _meter->run (bufs, start_frame, end_frame, 1.0 /*speed()*/, nframes, true);
}
passthru (bufs, start_frame, end_frame, nframes, false);
}
void
-UnknownProcessor::run (BufferSet& bufs, framepos_t /*start_frame*/, framepos_t /*end_frame*/, pframes_t nframes, bool)
+UnknownProcessor::run (BufferSet& bufs, framepos_t /*start_frame*/, framepos_t /*end_frame*/, double /*speed*/, pframes_t nframes, bool)
{
if (!have_ioconfig) {
return;
, _plugin (0)
, _pi (0)
, _num (0)
+ , _transport_frame (0)
+ , _transport_speed (0.f)
{
memset (&_timeInfo, 0, sizeof(_timeInfo));
}
int
VSTPlugin::connect_and_run (BufferSet& bufs,
+ framepos_t start, framepos_t end, double speed,
ChanMapping in_map, ChanMapping out_map,
pframes_t nframes, framecnt_t offset)
{
- Plugin::connect_and_run (bufs, in_map, out_map, nframes, offset);
+ Plugin::connect_and_run(bufs, start, end, speed, in_map, out_map, nframes, offset);
+
+ _transport_frame = start;
+ _transport_speed = speed;
ChanCount bufs_count;
bufs_count.set(DataType::AUDIO, 1);