protected:
friend class AudioTrack;
- int process (nframes_t transport_frame, nframes_t nframes, nframes_t offset, bool can_record, bool rec_monitors_input);
+ int process (nframes_t transport_frame, nframes_t nframes, bool can_record, bool rec_monitors_input);
bool commit (nframes_t nframes);
private:
bool can_use_mode (TrackMode m, bool& bounce_required);
int roll (nframes_t nframes, nframes_t start_frame, nframes_t end_frame,
- nframes_t offset, int declick, bool can_record, bool rec_monitors_input);
+ int declick, bool can_record, bool rec_monitors_input);
int no_roll (nframes_t nframes, nframes_t start_frame, nframes_t end_frame,
- nframes_t offset, bool state_changing, bool can_record, bool rec_monitors_input);
+ bool state_changing, bool can_record, bool rec_monitors_input);
int silent_roll (nframes_t nframes, nframes_t start_frame, nframes_t end_frame,
- nframes_t offset, bool can_record, bool rec_monitors_input);
+ bool can_record, bool rec_monitors_input);
boost::shared_ptr<AudioDiskstream> audio_diskstream() const;
XMLNode& state (bool full);
void passthru_silence (nframes_t start_frame, nframes_t end_frame,
- nframes_t nframes, nframes_t offset, int declick,
+ nframes_t nframes, int declick,
bool meter);
uint32_t n_process_buffers ();
friend class Track;
virtual void prepare ();
- virtual int process (nframes_t transport_frame, nframes_t nframes, nframes_t offset, bool can_record, bool rec_monitors_input) = 0;
+ virtual int process (nframes_t transport_frame, nframes_t nframes, bool can_record, bool rec_monitors_input) = 0;
virtual bool commit (nframes_t nframes) = 0;
virtual void recover (); /* called if commit will not be called, but process was */
virtual ~Insert() { }
- virtual void run (vector<Sample *>& bufs, uint32_t nbufs, nframes_t nframes, nframes_t offset) = 0;
+ virtual void run (vector<Sample *>& bufs, uint32_t nbufs, nframes_t nframes) = 0;
virtual void activate () {}
virtual void deactivate () {}
int set_state(const XMLNode&);
void init ();
- void run (vector<Sample *>& bufs, uint32_t nbufs, nframes_t nframes, nframes_t offset);
+ void run (vector<Sample *>& bufs, uint32_t nbufs, nframes_t nframes);
nframes_t latency();
XMLNode& get_state(void);
int set_state(const XMLNode&);
- void run (vector<Sample *>& bufs, uint32_t nbufs, nframes_t nframes, nframes_t offset);
- void silence (nframes_t nframes, nframes_t offset);
+ void run (vector<Sample *>& bufs, uint32_t nbufs, nframes_t nframes);
+ void silence (nframes_t nframes);
void activate ();
void deactivate ();
void parameter_changed (uint32_t, float);
vector<boost::shared_ptr<Plugin> > _plugins;
- void automation_run (vector<Sample *>& bufs, uint32_t nbufs, nframes_t nframes, nframes_t offset);
+ void automation_run (vector<Sample *>& bufs, uint32_t nbufs, nframes_t nframes);
void connect_and_run (vector<Sample *>& bufs, uint32_t nbufs, nframes_t nframes, nframes_t offset, bool with_auto, nframes_t now = 0);
void init ();
const string& name() const { return _name; }
virtual int set_name (string str, void *src);
- virtual void silence (nframes_t, nframes_t offset);
+ virtual void silence (nframes_t);
// These should be moved in to a separate object that manipulates an IO
- void pan (vector<Sample*>& bufs, uint32_t nbufs, nframes_t nframes, nframes_t offset, gain_t gain_coeff);
+ void pan (vector<Sample*>& bufs, uint32_t nbufs, nframes_t nframes, gain_t gain_coeff);
void pan_automated (vector<Sample*>& bufs, uint32_t nbufs, nframes_t start_frame, nframes_t end_frame,
- nframes_t nframes, nframes_t offset);
- void collect_input (vector<Sample*>&, uint32_t nbufs, nframes_t nframes, nframes_t offset);
- void deliver_output (vector<Sample*>&, uint32_t nbufs, nframes_t nframes, nframes_t offset);
- void deliver_output_no_pan (vector<Sample*>&, uint32_t nbufs, nframes_t nframes, nframes_t offset);
- void just_meter_input (nframes_t start_frame, nframes_t end_frame,
- nframes_t nframes, nframes_t offset);
+ nframes_t nframes);
+ void collect_input (vector<Sample*>&, uint32_t nbufs, nframes_t nframes);
+ void deliver_output (vector<Sample*>&, uint32_t nbufs, nframes_t nframes);
+ void deliver_output_no_pan (vector<Sample*>&, uint32_t nbufs, nframes_t nframes);
+ void just_meter_input (nframes_t start_frame, nframes_t end_frame, nframes_t nframes);
virtual uint32_t n_process_buffers () { return 0; }
uint32_t n_inputs () const { return _ninputs; }
uint32_t n_outputs () const { return _noutputs; }
+ Sample* get_input_buffer (int n, nframes_t);
+ Sample* get_output_buffer (int n, nframes_t);
+
sigc::signal<void> active_changed;
sigc::signal<void,IOChange,void*> input_changed;
void reset_max_peak_meters ();
+ static sigc::signal<void,nframes_t> CycleStart;
static void update_meters();
static std::string name_from_state (const XMLNode&);
int set_inputs (const string& str);
int set_outputs (const string& str);
+ void increment_output_offset (nframes_t);
+
+ void cycle_start (nframes_t);
+
static bool connecting_legal;
static bool ports_legal;
uint32_t _ninputs;
uint32_t _noutputs;
+ nframes_t _output_offset;
+
/* are these the best variable names ever, or what? */
// Port is an opage pointer, so should be be desallocated ??
}
- Sample *get_buffer (nframes_t nframes) {
- return (Sample *) jack_port_get_buffer (_port, nframes);
+ static nframes_t port_offset() { return _port_offset; }
+
+ static void set_port_offset (nframes_t off) {
+ _port_offset = off;
+ }
+ static void increment_port_offset (nframes_t n) {
+ _port_offset += n;
+ }
+ static void set_buffer_size (nframes_t sz) {
+ _buffer_size = sz;
}
std::string name() {
if (_metering) { _metering--; }
}
- float peak_db() const { return _peak_db; }
- jack_default_audio_sample_t peak() const { return _peak; }
+ float peak_db() const { return _peak_db; }
+ Sample peak() const { return _peak; }
uint32_t short_overs () const { return _short_overs; }
uint32_t long_overs () const { return _long_overs; }
bool is_silent() const { return _silent; }
/** Assumes that the port is an audio output port */
- void silence (nframes_t nframes, nframes_t offset) {
+ void silence (nframes_t nframes) {
if (!_silent) {
- memset ((Sample *) jack_port_get_buffer (_port, nframes) + offset, 0, sizeof (Sample) * nframes);
- if (offset == 0) {
- /* XXX this isn't really true, but i am not sure
- how to set this correctly. we really just
- want to set it true when the entire port
- buffer has been overrwritten.
- */
+ memset ((Sample *) jack_port_get_buffer (_port, nframes) + _port_offset, 0, sizeof (Sample) * nframes);
+ if (nframes == _buffer_size) {
+ /* its a heuristic. its not perfect */
_silent = true;
}
}
bool _last_monitor : 1;
bool _silent : 1;
jack_port_t *_port;
- nframes_t _overlen;
- jack_default_audio_sample_t _peak;
+ nframes_t _overlen;
+ Sample _peak;
float _peak_db;
uint32_t _short_overs;
uint32_t _long_overs;
unsigned short _metering;
-
+
static nframes_t _long_over_length;
static nframes_t _short_over_length;
+
+ static nframes_t _port_offset;
+ static nframes_t _buffer_size;
+
+ private:
+ friend class IO; // get_(input|output)_buffer
+ friend class Session; // session_export.cc
+
+ Sample *get_buffer (nframes_t nframes) {
+
+ /* ignore requested size, because jack always
+ reads the entire port buffer.
+ */
+
+ return (Sample *) jack_port_get_buffer (_port, _buffer_size) + _port_offset;
+ }
+
+
};
} // namespace ARDOUR
Placement placement() const { return _placement; }
void set_placement (Placement, void *src);
- virtual void run (vector<Sample *>& ibufs, uint32_t nbufs, nframes_t nframes, nframes_t offset) = 0;
+ virtual void run (vector<Sample *>& ibufs, uint32_t nbufs, nframes_t nframes) = 0;
virtual void activate () = 0;
virtual void deactivate () = 0;
virtual nframes_t latency() { return 0; }
virtual int roll (nframes_t nframes, nframes_t start_frame, nframes_t end_frame,
- nframes_t offset, int declick, bool can_record, bool rec_monitors_input);
+ int declick, bool can_record, bool rec_monitors_input);
virtual int no_roll (nframes_t nframes, nframes_t start_frame, nframes_t end_frame,
- nframes_t offset, bool state_changing, bool can_record, bool rec_monitors_input);
+ bool state_changing, bool can_record, bool rec_monitors_input);
virtual int silent_roll (nframes_t nframes, nframes_t start_frame, nframes_t end_frame,
- nframes_t offset, bool can_record, bool rec_monitors_input);
+ bool can_record, bool rec_monitors_input);
virtual void toggle_monitor_input ();
virtual bool can_record() { return false; }
virtual void set_record_enable (bool yn, void *src) {}
gain_t desired_solo_gain;
gain_t desired_mute_gain;
- nframes_t check_initial_delay (nframes_t, nframes_t&, nframes_t&);
+ nframes_t check_initial_delay (nframes_t, nframes_t&);
nframes_t _initial_delay;
nframes_t _roll_delay;
ToggleControllable _mute_control;
void passthru (nframes_t start_frame, nframes_t end_frame,
- nframes_t nframes, nframes_t offset, int declick, bool meter_inputs);
+ nframes_t nframes, int declick, bool meter_inputs);
void process_output_buffers (vector<Sample*>& bufs, uint32_t nbufs,
nframes_t start_frame, nframes_t end_frame,
- nframes_t nframes, nframes_t offset, bool with_redirects, int declick,
+ nframes_t nframes, bool with_redirects, int declick,
bool meter);
protected:
virtual XMLNode& state(bool);
- void silence (nframes_t nframes, nframes_t offset);
+ void silence (nframes_t nframes);
sigc::connection input_signal_connection;
uint32_t redirect_max_outs;
uint32_t bit_slot() const { return bitslot; }
- void run (vector<Sample *> &bufs, uint32_t nbufs, nframes_t nframes, nframes_t offset);
+ void run (vector<Sample *> &bufs, uint32_t nbufs, nframes_t nframes);
void activate() {}
void deactivate () {}
nframes_t slave_wait_end;
void reset_slave_state ();
- bool follow_slave (nframes_t, nframes_t);
+ bool follow_slave (nframes_t);
void set_slave_source (SlaveSource);
bool _exporting;
void prepare_diskstreams ();
void commit_diskstreams (nframes_t, bool& session_requires_butler);
- int process_routes (nframes_t, nframes_t);
- int silent_process_routes (nframes_t, nframes_t);
+ int process_routes (nframes_t);
+ int silent_process_routes (nframes_t);
bool get_rec_monitors_input () {
if (actively_recording()) {
return false;
}
- bool maybe_sync_start (nframes_t&, nframes_t&);
+ bool maybe_sync_start (nframes_t&);
void check_declick_out ();
void reset_record_status ();
- int no_roll (nframes_t nframes, nframes_t offset);
+ int fail_roll (nframes_t nframes);
+ int no_roll (nframes_t nframes);
bool non_realtime_work_pending() const { return static_cast<bool>(post_transport_work); }
bool process_can_proceed() const { return !(post_transport_work & ProcessCannotProceedMask); }
Click *get_click();
void setup_click_sounds (int which);
void clear_clicks ();
- void click (nframes_t start, nframes_t nframes, nframes_t offset);
+ void click (nframes_t start, nframes_t nframes);
vector<Route*> master_outs;
sigc::signal<void> TrackModeChanged;
virtual int roll (nframes_t nframes, nframes_t start_frame, nframes_t end_frame,
- nframes_t offset, int declick, bool can_record, bool rec_monitors_input) = 0;
+ int declick, bool can_record, bool rec_monitors_input) = 0;
virtual int no_roll (nframes_t nframes, nframes_t start_frame, nframes_t end_frame,
- nframes_t offset, bool state_changing, bool can_record, bool rec_monitors_input) = 0;
+ bool state_changing, bool can_record, bool rec_monitors_input) = 0;
virtual int silent_roll (nframes_t nframes, nframes_t start_frame, nframes_t end_frame,
- nframes_t offset, bool can_record, bool rec_monitors_input) = 0;
+ bool can_record, bool rec_monitors_input) = 0;
void toggle_monitor_input ();
virtual XMLNode& state (bool full) = 0;
virtual void passthru_silence (nframes_t start_frame, nframes_t end_frame,
- nframes_t nframes, nframes_t offset, int declick, bool meter) = 0;
+ nframes_t nframes, int declick, bool meter) = 0;
virtual uint32_t n_process_buffers () = 0;
/* starting to record: compute first+last frames */
first_recordable_frame = transport_frame + _capture_offset;
+ // cerr << "set FRF = " << transport_frame << " + " << _capture_offset << " = " << first_recordable_frame << endl;
last_recordable_frame = max_frames;
capture_start_frame = transport_frame;
/* was stopped, now rolling (and recording) */
if (_alignment_style == ExistingMaterial) {
- first_recordable_frame += _session.worst_output_latency();
+ //cerr << "A FRF += " << _session.worst_output_latency () << endl;
+ // first_recordable_frame += _session.worst_output_latency();
} else {
- first_recordable_frame += _roll_delay;
+ // cerr << "B FRF += " << _roll_delay<< endl;
+ // first_recordable_frame += _roll_delay;
}
} else {
this is needed.
*/
+ // cerr << "1 FRF += " << _capture_offset << endl;
first_recordable_frame += _capture_offset;
} else {
on the output latency.
*/
+ // cerr << "2 FRF += " << _session.worst_output_latency() << endl;
first_recordable_frame += _session.worst_output_latency();
}
} else {
if (Config->get_punch_in()) {
+ // cerr << "3 FRF += " << _roll_delay << endl;
first_recordable_frame += _roll_delay;
} else {
capture_start_frame -= _roll_delay;
}
+ // cerr << _name << " FRF = " << first_recordable_frame << " CSF = " << capture_start_frame << endl;
+
if (recordable() && destructive()) {
boost::shared_ptr<ChannelList> c = channels.reader();
for (ChannelList::iterator chan = c->begin(); chan != c->end(); ++chan) {
}
int
-AudioDiskstream::process (nframes_t transport_frame, nframes_t nframes, nframes_t offset, bool can_record, bool rec_monitors_input)
+AudioDiskstream::process (nframes_t transport_frame, nframes_t nframes, bool can_record, bool rec_monitors_input)
{
uint32_t n;
boost::shared_ptr<ChannelList> c = channels.reader();
rec_offset
*/
- memcpy (chaninfo->current_capture_buffer, _io->input(n)->get_buffer (rec_nframes) + offset + rec_offset, sizeof (Sample) * rec_nframes);
+ memcpy (chaninfo->current_capture_buffer, _io->get_input_buffer (n, rec_nframes) + rec_offset, sizeof (Sample) * rec_nframes);
} else {
goto out;
}
- Sample* buf = _io->input (n)->get_buffer (nframes) + offset;
+ Sample* buf = _io->get_input_buffer (n, nframes);
nframes_t first = chaninfo->capture_vector.len[0];
memcpy (chaninfo->capture_wrap_buffer, buf, sizeof (Sample) * first);
vector.buf[1] = 0;
boost::shared_ptr<ChannelList> c = channels.reader();
- for (ChannelList::iterator chan = c->begin(); chan != c->end(); ++chan) {
+ int nn = 0;
+ for (ChannelList::iterator chan = c->begin(); chan != c->end(); ++chan, ++nn) {
(*chan)->capture_buf->get_read_vector (&vector);
}
void
-AudioTrack::passthru_silence (nframes_t start_frame, nframes_t end_frame, nframes_t nframes, nframes_t offset, int declick, bool meter)
+AudioTrack::passthru_silence (nframes_t start_frame, nframes_t end_frame, nframes_t nframes, int declick, bool meter)
{
uint32_t nbufs = n_process_buffers ();
- process_output_buffers (_session.get_silent_buffers (nbufs), nbufs, start_frame, end_frame, nframes, offset, true, declick, meter);
+
+ process_output_buffers (_session.get_silent_buffers (nbufs), nbufs, start_frame, end_frame, nframes, true, declick, meter);
}
int
-AudioTrack::no_roll (nframes_t nframes, nframes_t start_frame, nframes_t end_frame, nframes_t offset,
+AudioTrack::no_roll (nframes_t nframes, nframes_t start_frame, nframes_t end_frame,
bool session_state_changing, bool can_record, bool rec_monitors_input)
{
if (n_outputs() == 0) {
}
if (!_active) {
- silence (nframes, offset);
+ silence (nframes);
return 0;
}
/* XXX is this safe to do against transport state changes? */
- passthru_silence (start_frame, end_frame, nframes, offset, 0, false);
+ passthru_silence (start_frame, end_frame, nframes, 0, false);
return 0;
}
*/
if (_have_internal_generator) {
- passthru_silence (start_frame, end_frame, nframes, offset, 0, true);
+ passthru_silence (start_frame, end_frame, nframes, 0, true);
} else {
if (_meter_point == MeterInput) {
- just_meter_input (start_frame, end_frame, nframes, offset);
+ just_meter_input (start_frame, end_frame, nframes);
}
- passthru_silence (start_frame, end_frame, nframes, offset, 0, false);
+ passthru_silence (start_frame, end_frame, nframes, 0, false);
}
} else {
/* we're sending signal, but we may still want to meter the input.
*/
- passthru (start_frame, end_frame, nframes, offset, 0, (_meter_point == MeterInput));
+ passthru (start_frame, end_frame, nframes, 0, (_meter_point == MeterInput));
}
return 0;
}
int
-AudioTrack::roll (nframes_t nframes, nframes_t start_frame, nframes_t end_frame, nframes_t offset, int declick,
+AudioTrack::roll (nframes_t nframes, nframes_t start_frame, nframes_t end_frame, int declick,
bool can_record, bool rec_monitors_input)
{
int dret;
}
if (!_active) {
- silence (nframes, offset);
+ silence (nframes);
return 0;
}
transport_frame = _session.transport_frame();
- if ((nframes = check_initial_delay (nframes, offset, transport_frame)) == 0) {
- /* need to do this so that the diskstream sets its
- playback distance to zero, thus causing diskstream::commit
- to do nothing.
- */
- return diskstream->process (transport_frame, 0, 0, can_record, rec_monitors_input);
- }
+ if (!can_record || !diskstream->record_enabled()) {
+ if ((nframes = check_initial_delay (nframes, transport_frame)) == 0) {
+ /* need to do this so that the diskstream sets its
+ playback distance to zero, thus causing diskstream::commit
+ to do nothing.
+ */
+ return diskstream->process (transport_frame, 0, can_record, rec_monitors_input);
+ }
+ }
_silent = false;
apply_gain_automation = false;
- if ((dret = diskstream->process (transport_frame, nframes, offset, can_record, rec_monitors_input)) != 0) {
+ if ((dret = diskstream->process (transport_frame, nframes, can_record, rec_monitors_input)) != 0) {
- silence (nframes, offset);
+ silence (nframes);
return dret;
}
/* special condition applies */
if (_meter_point == MeterInput) {
- just_meter_input (start_frame, end_frame, nframes, offset);
+ just_meter_input (start_frame, end_frame, nframes);
}
if (diskstream->record_enabled() && !can_record && !Config->get_auto_input()) {
at least potentially (depending on monitoring options)
*/
- passthru (start_frame, end_frame, nframes, offset, 0, true);
+ passthru (start_frame, end_frame, nframes, 0, true);
} else if ((b = diskstream->playback_buffer(0)) != 0) {
}
}
- process_output_buffers (bufs, limit, start_frame, end_frame, nframes, offset, (!_session.get_record_enabled() || !Config->get_do_not_record_plugins()), declick, (_meter_point != MeterInput));
+ process_output_buffers (bufs, limit, start_frame, end_frame, nframes, (!_session.get_record_enabled() || !Config->get_do_not_record_plugins()), declick, (_meter_point != MeterInput));
} else {
/* problem with the diskstream; just be quiet for a bit */
- silence (nframes, offset);
+ silence (nframes);
}
return 0;
}
int
-AudioTrack::silent_roll (nframes_t nframes, nframes_t start_frame, nframes_t end_frame, nframes_t offset,
+AudioTrack::silent_roll (nframes_t nframes, nframes_t start_frame, nframes_t end_frame,
bool can_record, bool rec_monitors_input)
{
if (n_outputs() == 0 && _redirects.empty()) {
}
if (!_active) {
- silence (nframes, offset);
+ silence (nframes);
return 0;
}
_silent = true;
apply_gain_automation = false;
- silence (nframes, offset);
+ silence (nframes);
- return audio_diskstream()->process (_session.transport_frame() + offset, nframes, offset, can_record, rec_monitors_input);
+ return audio_diskstream()->process (_session.transport_frame(), nframes, can_record, rec_monitors_input);
}
int
if ((insert = boost::dynamic_pointer_cast<Insert>(*i)) != 0) {
switch (insert->placement()) {
case PreFader:
- insert->run (buffers, nbufs, nframes, 0);
+ insert->run (buffers, nbufs, nframes);
break;
case PostFader:
post_fader_work = true;
case PreFader:
break;
case PostFader:
- insert->run (buffers, nbufs, nframes, 0);
+ insert->run (buffers, nbufs, nframes);
break;
}
}
#include <ardour/audioengine.h>
#include <ardour/buffer.h>
#include <ardour/port.h>
+#include <ardour/io.h>
#include <ardour/session.h>
#include <ardour/cycle_timer.h>
#include <ardour/utils.h>
if (!_running) {
+ nframes_t blocksize = jack_get_buffer_size (_jack);
+ cerr << "pre-run: Set Port buffer size to " << blocksize << endl;
+ Port::set_buffer_size (blocksize);
+
if (session) {
- nframes_t blocksize = jack_get_buffer_size (_jack);
BootMessage (_("Connect session to engine"));
return 0;
}
+ /* reset port buffer offset for the start of a new cycle */
+
+ Port::set_port_offset (0);
+
+ /* tell all IO objects that we're starting a new cycle */
+
+ IO::CycleStart (nframes);
+
if (_freewheeling) {
if (Freewheel (nframes)) {
jack_set_freewheel (_jack, false);
Port *port = (*i);
if (port->sends_output()) {
- Sample *buf = port->get_buffer(nframes);
+ Sample *buf = port->get_buffer (nframes);
memset (buf, 0, sizeof(Sample) * nframes);
// this should work but doesn't
//port->silence(0, nframes); //need to implement declicking fade
_usecs_per_cycle = (int) floor ((((double) nframes / frame_rate())) * 1000000.0);
last_monitor_check = 0;
- boost::shared_ptr<Ports> p = ports.reader();
+ cerr << "bufsize: Set Port buffer size to " << nframes << endl;
+ Port::set_buffer_size (nframes);
+ boost::shared_ptr<Ports> p = ports.reader();
+
for (Ports::iterator i = p->begin(); i != p->end(); ++i) {
(*i)->reset();
}
(*i)->reset ();
if ((*i)->flags() & JackPortIsOutput) {
- (*i)->silence (jack_get_buffer_size (_jack), 0);
+ (*i)->silence (jack_get_buffer_size (_jack));
}
}
if (session) {
session->reset_jack_connection (_jack);
nframes_t blocksize = jack_get_buffer_size (_jack);
+ Port::set_buffer_size (blocksize);
session->set_block_size (blocksize);
session->set_frame_rate (jack_get_sample_rate (_jack));
}
int ret;
if (g_atomic_int_get (&_active) == 0) {
- silence (nframes, 0);
+ silence (nframes);
return 0;
}
_diskstream->prepare ();
- if ((ret = roll (this_nframes, current_frame, current_frame + nframes, 0, false, false, false)) != 0) {
- silence (nframes, 0);
+ if ((ret = roll (this_nframes, current_frame, current_frame + nframes, false, false, false)) != 0) {
+ silence (nframes);
return ret;
}
}
for (vector<boost::shared_ptr<Plugin> >::iterator i = _plugins.begin(); i != _plugins.end(); ++i) {
- // cerr << "\trun C&R with in = " << in_index << " out = " << out_index << " nf = " << nframes << " off = " << offset << endl;
(*i)->connect_and_run (bufs, nbufs, in_index, out_index, nframes, offset);
}
-
- /* leave remaining channel buffers alone */
- // cerr << "--- and out\n";
}
void
}
void
-PluginInsert::silence (nframes_t nframes, nframes_t offset)
+PluginInsert::silence (nframes_t nframes)
{
int32_t in_index = 0;
int32_t out_index = 0;
if (active()) {
for (vector<boost::shared_ptr<Plugin> >::iterator i = _plugins.begin(); i != _plugins.end(); ++i) {
n = input_streams();
- (*i)->connect_and_run (_session.get_silent_buffers (n), n, in_index, out_index, nframes, offset);
+ (*i)->connect_and_run (_session.get_silent_buffers (n), n, in_index, out_index, nframes, 0);
}
}
}
void
-PluginInsert::run (vector<Sample *>& bufs, uint32_t nbufs, nframes_t nframes, nframes_t offset)
+PluginInsert::run (vector<Sample *>& bufs, uint32_t nbufs, nframes_t nframes)
{
if (active()) {
if (_session.transport_rolling()) {
- automation_run (bufs, nbufs, nframes, offset);
+ automation_run (bufs, nbufs, nframes);
} else {
- connect_and_run (bufs, nbufs, nframes, offset, false);
+ connect_and_run (bufs, nbufs, nframes, 0, false);
}
} else {
}
void
-PluginInsert::automation_run (vector<Sample *>& bufs, uint32_t nbufs, nframes_t nframes, nframes_t offset)
+PluginInsert::automation_run (vector<Sample *>& bufs, uint32_t nbufs, nframes_t nframes)
{
ControlEvent next_event (0, 0.0f);
nframes_t now = _session.transport_frame ();
nframes_t end = now + nframes;
+ nframes_t offset = 0;
Glib::Mutex::Lock lm (_automation_lock, Glib::TRY_LOCK);
if (!lm.locked()) {
- connect_and_run (bufs, nbufs, nframes, offset, false);
+ connect_and_run (bufs, nbufs, nframes, 0, false, now);
return;
}
-
+
if (!find_next_event (now, end, next_event)) {
-
/* no events have a time within the relevant range */
-
- connect_and_run (bufs, nbufs, nframes, offset, true, now);
+ connect_and_run (bufs, nbufs, nframes, 0, true, now);
return;
- }
+ }
- nframes_t buffer_correct = 0;
-
while (nframes) {
nframes_t cnt = min (((nframes_t) ceil (next_event.when) - now), nframes);
- // This is called first, but nframes = 256
connect_and_run (bufs, nbufs, cnt, offset, true, now);
nframes -= cnt;
now += cnt;
- buffer_correct += cnt;
-
- /* we are going to advance the buffer pointers by "cnt" so there
- is no reason to specify a non-zero offset anymore.
- */
-
- offset = 0;
-
- for (uint32_t i = 0; i < nbufs; i++) {
- bufs[i] += cnt;
- }
+ offset += cnt;
if (!find_next_event (now, end, next_event)) {
break;
}
- }
-
+ }
+
/* cleanup anything that is left to do */
if (nframes) {
connect_and_run (bufs, nbufs, nframes, offset, true, now);
}
- for (uint32_t i = 0; i < nbufs; i++) {
- bufs[i] -= buffer_correct;
- }
}
float
}
void
-PortInsert::run (vector<Sample *>& bufs, uint32_t nbufs, nframes_t nframes, nframes_t offset)
+PortInsert::run (vector<Sample *>& bufs, uint32_t nbufs, nframes_t nframes)
{
if (n_outputs() == 0) {
return;
if (!active()) {
/* deliver silence */
- silence (nframes, offset);
+ silence (nframes);
return;
}
/* deliver output */
for (o = _outputs.begin(), n = 0; o != _outputs.end(); ++o, ++n) {
- memcpy ((*o)->get_buffer (nframes) + offset, bufs[min(nbufs,n)], sizeof (Sample) * nframes);
+ memcpy (get_output_buffer (n, nframes), bufs[min(nbufs,n)], sizeof (Sample) * nframes);
(*o)->mark_silence (false);
}
/* collect input */
for (i = _inputs.begin(), n = 0; i != _inputs.end(); ++i, ++n) {
- memcpy (bufs[min(nbufs,n)], (*i)->get_buffer (nframes) + offset, sizeof (Sample) * nframes);
+ memcpy (bufs[min(nbufs,n)], get_input_buffer (n, nframes), sizeof (Sample) * nframes);
}
}
sigc::signal<int> IO::PannersLegal;
sigc::signal<void,uint32_t> IO::MoreOutputs;
sigc::signal<int> IO::PortsCreated;
+sigc::signal<void,nframes_t> IO::CycleStart;
Glib::StaticMutex IO::m_meter_signal_lock = GLIBMM_STATIC_MUTEX_INIT;
m_meter_connection = Meter.connect (mem_fun (*this, &IO::meter));
}
+ _output_offset = 0;
+ CycleStart.connect (mem_fun (*this, &IO::cycle_start));
+
_session.add_controllable (&_gain_control);
}
m_meter_connection = Meter.connect (mem_fun (*this, &IO::meter));
}
+ _output_offset = 0;
+ CycleStart.connect (mem_fun (*this, &IO::cycle_start));
+
_session.add_controllable (&_gain_control);
}
}
void
-IO::silence (nframes_t nframes, nframes_t offset)
+IO::silence (nframes_t nframes)
{
/* io_lock, not taken: function must be called from Session::process() calltree */
for (vector<Port *>::iterator i = _outputs.begin(); i != _outputs.end(); ++i) {
- (*i)->silence (nframes, offset);
+ (*i)->silence (nframes);
}
}
}
void
-IO::pan_automated (vector<Sample*>& bufs, uint32_t nbufs, nframes_t start, nframes_t end, nframes_t nframes, nframes_t offset)
+IO::pan_automated (vector<Sample*>& bufs, uint32_t nbufs, nframes_t start, nframes_t end, nframes_t nframes)
{
Sample* dst;
if (_noutputs == 1) {
- dst = output(0)->get_buffer (nframes) + offset;
+ dst = get_output_buffer (0, nframes);
for (uint32_t n = 0; n < nbufs; ++n) {
if (bufs[n] != dst) {
/* the terrible silence ... */
for (out = _outputs.begin(), o = 0; out != _outputs.end(); ++out, ++o) {
- obufs[o] = (*out)->get_buffer (nframes) + offset;
+ obufs[o] = get_output_buffer (o, nframes);
memset (obufs[o], 0, sizeof (Sample) * nframes);
(*out)->mark_silence (false);
}
}
void
-IO::pan (vector<Sample*>& bufs, uint32_t nbufs, nframes_t nframes, nframes_t offset, gain_t gain_coeff)
+IO::pan (vector<Sample*>& bufs, uint32_t nbufs, nframes_t nframes, gain_t gain_coeff)
{
Sample* dst;
Sample* src;
*/
if (_panner->bypassed() || _panner->empty()) {
- deliver_output_no_pan (bufs, nbufs, nframes, offset);
+ deliver_output_no_pan (bufs, nbufs, nframes);
return;
}
if (_noutputs == 1) {
- dst = output(0)->get_buffer (nframes) + offset;
+ dst = get_output_buffer (0, nframes);
if (gain_coeff == 0.0f) {
/* XXX this is wasteful but i see no way to avoid it */
for (out = _outputs.begin(), o = 0; out != _outputs.end(); ++out, ++o) {
- obufs[o] = (*out)->get_buffer (nframes) + offset;
+ obufs[o] = get_output_buffer (o, nframes);
memset (obufs[o], 0, sizeof (Sample) * nframes);
(*out)->mark_silence (false);
}
}
void
-IO::deliver_output (vector<Sample *>& bufs, uint32_t nbufs, nframes_t nframes, nframes_t offset)
+IO::deliver_output (vector<Sample *>& bufs, uint32_t nbufs, nframes_t nframes)
{
/* io_lock, not taken: function must be called from Session::process() calltree */
}
if (_panner->bypassed() || _panner->empty()) {
- deliver_output_no_pan (bufs, nbufs, nframes, offset);
+ deliver_output_no_pan (bufs, nbufs, nframes);
return;
}
/* simple, non-automation panning to outputs */
if (_session.transport_speed() > 1.5f || _session.transport_speed() < -1.5f) {
- pan (bufs, nbufs, nframes, offset, pangain * speed_quietning);
+ pan (bufs, nbufs, nframes, pangain * speed_quietning);
} else {
- pan (bufs, nbufs, nframes, offset, pangain);
+ pan (bufs, nbufs, nframes, pangain);
}
}
void
-IO::deliver_output_no_pan (vector<Sample *>& bufs, uint32_t nbufs, nframes_t nframes, nframes_t offset)
+IO::deliver_output_no_pan (vector<Sample *>& bufs, uint32_t nbufs, nframes_t nframes)
{
/* io_lock, not taken: function must be called from Session::process() calltree */
for (o = _outputs.begin(), i = 0; o != _outputs.end(); ++o, ++i) {
- dst = (*o)->get_buffer (nframes) + offset;
+ dst = get_output_buffer (i, nframes);
src = bufs[min(nbufs,i)];
if (dg != _gain) {
}
void
-IO::collect_input (vector<Sample *>& bufs, uint32_t nbufs, nframes_t nframes, nframes_t offset)
+IO::collect_input (vector<Sample *>& bufs, uint32_t nbufs, nframes_t nframes)
{
/* io_lock, not taken: function must be called from Session::process() calltree */
if (i == _inputs.end()) {
break;
}
-
- /* XXX always read the full extent of the port buffer that
- we need. One day, we may use jack_port_get_buffer_at_offset()
- or something similar. For now, this simple hack will
- have to do.
- Hack? Why yes .. we only need to read nframes-worth of
- data, but the data we want is at `offset' within the
- buffer.
- */
-
- last = (*i)->get_buffer (nframes+offset) + offset;
- // the dest buffer's offset has already been applied
+ last = get_input_buffer (n, nframes);
memcpy (bufs[n], last, sizeof (Sample) * nframes);
}
if (last) {
while (n < nbufs) {
- // the dest buffer's offset has already been applied
memcpy (bufs[n], last, sizeof (Sample) * nframes);
++n;
}
}
void
-IO::just_meter_input (nframes_t start_frame, nframes_t end_frame,
- nframes_t nframes, nframes_t offset)
+IO::just_meter_input (nframes_t start_frame, nframes_t end_frame, nframes_t nframes)
{
vector<Sample*>& bufs = _session.get_passthru_buffers ();
uint32_t nbufs = n_process_buffers ();
- collect_input (bufs, nbufs, nframes, offset);
+ collect_input (bufs, nbufs, nframes);
for (uint32_t n = 0; n < nbufs; ++n) {
_peak_power[n] = Session::compute_peak (bufs[n], nframes, _peak_power[n]);
node.add_property ("name", new_name);
}
}
+
+void
+IO::cycle_start (nframes_t nframes)
+{
+ _output_offset = 0;
+}
+
+void
+IO::increment_output_offset (nframes_t n)
+{
+ _output_offset += n;
+}
+
+Sample*
+IO::get_input_buffer (int n, nframes_t nframes)
+{
+ Port* port;
+
+ if (!(port = input (n))) {
+ return 0;
+ }
+
+ return port->get_buffer (nframes);
+}
+
+Sample*
+IO::get_output_buffer (int n, nframes_t nframes)
+{
+ Port* port;
+
+ if (!(port = output (n))) {
+ return 0;
+ }
+
+ return port->get_buffer (nframes) + _output_offset;
+}
+
nframes_t Port::_short_over_length = 2;
nframes_t Port::_long_over_length = 10;
+nframes_t Port::_port_offset = 0;
+nframes_t Port::_buffer_size = 0;
Port::Port (jack_port_t *p)
: _port (p)
AutomationList::TimeComparator cmp;
next_event.when = max_frames;
-
+
for (li = parameter_automation.begin(); li != parameter_automation.end(); ++li) {
const AutomationList* alist = *li;
void
Route::process_output_buffers (vector<Sample*>& bufs, uint32_t nbufs,
nframes_t start_frame, nframes_t end_frame,
- nframes_t nframes, nframes_t offset, bool with_redirects, int declick,
+ nframes_t nframes, bool with_redirects, int declick,
bool meter)
{
uint32_t n;
) {
- co->silence (nframes, offset);
+ co->silence (nframes);
} else {
- co->deliver_output (bufs, nbufs, nframes, offset);
+ co->deliver_output (bufs, nbufs, nframes);
}
}
for (n = 0; n < nbufs; ++n) {
Sample *sp = bufs[n];
- for (nframes_t nx = offset; nx < nframes + offset; ++nx) {
+ for (nframes_t nx = 0; nx < nframes; ++nx) {
sp[nx] += 1.0e-27f;
}
}
case PreFader:
if (dsg == 0) {
if (boost::dynamic_pointer_cast<Send>(*i) || boost::dynamic_pointer_cast<PortInsert>(*i)) {
- (*i)->silence (nframes, offset);
+ (*i)->silence (nframes);
}
} else {
- (*i)->run (bufs, nbufs, nframes, offset);
+ (*i)->run (bufs, nbufs, nframes);
}
break;
case PostFader:
for (i = _redirects.begin(); i != _redirects.end(); ++i) {
switch ((*i)->placement()) {
case PreFader:
- (*i)->silence (nframes, offset);
+ (*i)->silence (nframes);
break;
case PostFader:
post_fader_work = true;
) {
- co->silence (nframes, offset);
+ co->silence (nframes);
} else {
- co->deliver_output_no_pan (bufs, nbufs, nframes, offset);
+ co->deliver_output_no_pan (bufs, nbufs, nframes);
}
}
case PostFader:
if (dsg == 0) {
if (boost::dynamic_pointer_cast<Send>(*i) || boost::dynamic_pointer_cast<PortInsert>(*i)) {
- (*i)->silence (nframes, offset);
+ (*i)->silence (nframes);
}
} else {
- (*i)->run (bufs, nbufs, nframes, offset);
+ (*i)->run (bufs, nbufs, nframes);
}
break;
}
case PreFader:
break;
case PostFader:
- (*i)->silence (nframes, offset);
+ (*i)->silence (nframes);
break;
}
}
) {
- co->silence (nframes, offset);
+ co->silence (nframes);
} else {
- co->deliver_output_no_pan (bufs, nbufs, nframes, offset);
+ co->deliver_output_no_pan (bufs, nbufs, nframes);
}
}
} else if (no_monitor && record_enabled() && (!Config->get_auto_input() || _session.actively_recording())) {
- IO::silence (nframes, offset);
+ IO::silence (nframes);
} else {
reset_peak_meters ();
}
- IO::silence (nframes, offset);
+ IO::silence (nframes);
} else {
if ((_session.transport_speed() > 1.5f ||
_session.transport_speed() < -1.5f) &&
Config->get_quieten_at_speed()) {
- pan (bufs, nbufs, nframes, offset, speed_quietning);
+ pan (bufs, nbufs, nframes, speed_quietning);
} else {
// cerr << _name << " panner state = " << _panner->automation_state() << endl;
if (!_panner->empty() &&
(_panner->automation_state() & Play ||
((_panner->automation_state() & Touch) && !_panner->touching()))) {
- pan_automated (bufs, nbufs, start_frame, end_frame, nframes, offset);
+ pan_automated (bufs, nbufs, start_frame, end_frame, nframes);
} else {
- pan (bufs, nbufs, nframes, offset, 1.0);
+ pan (bufs, nbufs, nframes, 1.0);
}
}
}
} else {
uint32_t no = n_outputs();
for (n = 0; n < no; ++n) {
- _peak_power[n] = Session::compute_peak (output(n)->get_buffer (nframes) + offset, nframes, _peak_power[n]);
+ _peak_power[n] = Session::compute_peak (get_output_buffer (n, nframes), nframes, _peak_power[n]);
}
}
}
void
-Route::passthru (nframes_t start_frame, nframes_t end_frame, nframes_t nframes, nframes_t offset, int declick, bool meter_first)
+Route::passthru (nframes_t start_frame, nframes_t end_frame, nframes_t nframes, int declick, bool meter_first)
{
vector<Sample*>& bufs = _session.get_passthru_buffers();
uint32_t limit = n_process_buffers ();
_silent = false;
- collect_input (bufs, limit, nframes, offset);
+ collect_input (bufs, limit, nframes);
#define meter_stream meter_first
meter_stream = true;
}
- process_output_buffers (bufs, limit, start_frame, end_frame, nframes, offset, true, declick, meter_stream);
+ process_output_buffers (bufs, limit, start_frame, end_frame, nframes, true, declick, meter_stream);
#undef meter_stream
}
}
void
-Route::silence (nframes_t nframes, nframes_t offset)
+Route::silence (nframes_t nframes)
{
if (!_silent) {
// reset_peak_meters ();
- IO::silence (nframes, offset);
+ IO::silence (nframes);
if (_control_outs) {
- _control_outs->silence (nframes, offset);
+ _control_outs->silence (nframes);
}
{
continue;
}
- (*i)->silence (nframes, offset);
+ (*i)->silence (nframes);
}
- if (nframes == _session.get_block_size() && offset == 0) {
+ if (nframes == _session.get_block_size()) {
// _silent = true;
}
}
}
int
-Route::no_roll (nframes_t nframes, nframes_t start_frame, nframes_t end_frame, nframes_t offset,
- bool session_state_changing, bool can_record, bool rec_monitors_input)
+Route::no_roll (nframes_t nframes, nframes_t start_frame, nframes_t end_frame,
+ bool session_state_changing, bool can_record, bool rec_monitors_input)
{
if (n_outputs() == 0) {
return 0;
}
if (session_state_changing || !_active) {
- silence (nframes, offset);
+ silence (nframes);
return 0;
}
apply_gain_automation = false;
if (n_inputs()) {
- passthru (start_frame, end_frame, nframes, offset, 0, false);
+ passthru (start_frame, end_frame, nframes, 0, false);
} else {
- silence (nframes, offset);
+ silence (nframes);
}
return 0;
}
nframes_t
-Route::check_initial_delay (nframes_t nframes, nframes_t& offset, nframes_t& transport_frame)
+Route::check_initial_delay (nframes_t nframes, nframes_t& transport_frame)
{
if (_roll_delay > nframes) {
_roll_delay -= nframes;
- silence (nframes, offset);
+ silence (nframes);
/* transport frame is not legal for caller to use */
return 0;
nframes -= _roll_delay;
- silence (_roll_delay, offset);
+ silence (_roll_delay);
+
+ /* we've written _roll_delay of samples into the
+ output ports, so make a note of that for
+ future reference.
+ */
+
+ increment_output_offset (_roll_delay);
- offset += _roll_delay;
transport_frame += _roll_delay;
_roll_delay = 0;
}
int
-Route::roll (nframes_t nframes, nframes_t start_frame, nframes_t end_frame, nframes_t offset, int declick,
+Route::roll (nframes_t nframes, nframes_t start_frame, nframes_t end_frame, int declick,
bool can_record, bool rec_monitors_input)
{
{
}
if ((n_outputs() == 0 && _redirects.empty()) || n_inputs() == 0 || !_active) {
- silence (nframes, offset);
+ silence (nframes);
return 0;
}
nframes_t unused = 0;
- if ((nframes = check_initial_delay (nframes, offset, unused)) == 0) {
+ if ((nframes = check_initial_delay (nframes, unused)) == 0) {
return 0;
}
}
}
- passthru (start_frame, end_frame, nframes, offset, declick, false);
+ passthru (start_frame, end_frame, nframes, declick, false);
return 0;
}
int
-Route::silent_roll (nframes_t nframes, nframes_t start_frame, nframes_t end_frame, nframes_t offset,
+Route::silent_roll (nframes_t nframes, nframes_t start_frame, nframes_t end_frame,
bool can_record, bool rec_monitors_input)
{
- silence (nframes, offset);
+ silence (nframes);
return 0;
}
}
void
-Send::run (vector<Sample *>& bufs, uint32_t nbufs, nframes_t nframes, nframes_t offset)
+Send::run (vector<Sample *>& bufs, uint32_t nbufs, nframes_t nframes)
{
if (active()) {
memcpy (sendbufs[i], bufs[i], sizeof (Sample) * nframes);
}
-
- IO::deliver_output (sendbufs, nbufs, nframes, offset);
+ IO::deliver_output (sendbufs, nbufs, nframes);
if (_metering) {
uint32_t n;
} else {
for (n = 0; n < no; ++n) {
- _peak_power[n] = Session::compute_peak (output(n)->get_buffer(nframes) + offset, nframes, _peak_power[n]);
+ _peak_power[n] = Session::compute_peak (get_output_buffer(n, nframes), nframes, _peak_power[n]);
}
}
}
} else {
- silence (nframes, offset);
+ silence (nframes);
if (_metering) {
uint32_t n;
Pool Session::Click::pool ("click", sizeof (Click), 128);
void
-Session::click (nframes_t start, nframes_t nframes, nframes_t offset)
+Session::click (nframes_t start, nframes_t nframes)
{
TempoMap::BBTPointList *points;
nframes_t end;
Glib::RWLock::WriterLock clickm (click_lock, Glib::TRY_LOCK);
if (!clickm.locked() || _transport_speed != 1.0 || !_clicking || click_data == 0) {
- _click_io->silence (nframes, offset);
+ _click_io->silence (nframes);
return;
}
i = next;
}
- _click_io->deliver_output (_passthru_buffers, 1, nframes, offset);
+ _click_io->deliver_output (_passthru_buffers, 1, nframes);
}
void
if (!_exporting) {
/* finished, but still freewheeling */
cerr << "\tExport ... not exporting yet, no_roll() for " << nframes <<endl;
- no_roll (nframes, 0);
+ no_roll (nframes);
return 0;
}
if (!spec->running || spec->stop || (this_nframes = min ((spec->end_frame - spec->pos), nframes)) == 0) {
cerr << "\tExport ... not running or at end, no_roll() for " << nframes <<endl;
- no_roll (nframes, 0);
+ no_roll (nframes);
return stop_audio_export (*spec);
}
}
int
-Session::no_roll (nframes_t nframes, nframes_t offset)
+Session::fail_roll (nframes_t nframes)
+{
+ Port::set_port_offset (0);
+ return no_roll (nframes);
+
+}
+
+int
+Session::no_roll (nframes_t nframes)
{
nframes_t end_frame = _transport_frame + nframes;
int ret = 0;
boost::shared_ptr<RouteList> r = routes.reader ();
if (_click_io) {
- _click_io->silence (nframes, offset);
+ _click_io->silence (nframes);
}
for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
(*i)->set_pending_declick (declick);
- if ((*i)->no_roll (nframes, _transport_frame, end_frame, offset, non_realtime_work_pending(),
+ if ((*i)->no_roll (nframes, _transport_frame, end_frame, non_realtime_work_pending(),
actively_recording(), declick)) {
error << string_compose(_("Session: error in no roll for %1"), (*i)->name()) << endmsg;
ret = -1;
}
int
-Session::process_routes (nframes_t nframes, nframes_t offset)
+Session::process_routes (nframes_t nframes)
{
bool record_active;
int declick = get_transport_declick_required();
(*i)->set_pending_declick (declick);
- if ((ret = (*i)->roll (nframes, _transport_frame, _transport_frame + nframes, offset, declick, record_active, rec_monitors)) < 0) {
+ if ((ret = (*i)->roll (nframes, _transport_frame, _transport_frame + nframes, declick, record_active, rec_monitors)) < 0) {
/* we have to do this here. Route::roll() for an AudioTrack will have called AudioDiskstream::process(),
and the DS will expect AudioDiskstream::commit() to be called. but we're aborting from that
}
int
-Session::silent_process_routes (nframes_t nframes, nframes_t offset)
+Session::silent_process_routes (nframes_t nframes)
{
bool record_active = actively_recording();
int declick = get_transport_declick_required();
continue;
}
- if ((ret = (*i)->silent_roll (nframes, _transport_frame, _transport_frame + nframes, offset, record_active, rec_monitors)) < 0) {
+ if ((ret = (*i)->silent_roll (nframes, _transport_frame, _transport_frame + nframes, record_active, rec_monitors)) < 0) {
/* we have to do this here. Route::roll() for an AudioTrack will have called AudioDiskstream::process(),
and the DS will expect AudioDiskstream::commit() to be called. but we're aborting from that
also runs commit() for every diskstream.
*/
- if ((dret = (*i)->process (_transport_frame, nframes, 0, actively_recording(), get_rec_monitors_input())) == 0) {
+ if ((dret = (*i)->process (_transport_frame, nframes, actively_recording(), get_rec_monitors_input())) == 0) {
if ((*i)->commit (nframes)) {
needs_butler = true;
}
Event* ev;
nframes_t this_nframes;
nframes_t end_frame;
- nframes_t offset;
+
bool session_needs_butler = false;
nframes_t stop_limit;
long frames_moved;
/* make sure the auditioner is silent */
if (auditioner) {
- auditioner->silence (nframes, 0);
+ auditioner->silence (nframes);
}
/* handle any pending events */
}
if (!_exporting && _slave) {
- if (!follow_slave (nframes, 0)) {
+ if (!follow_slave (nframes)) {
return;
}
}
if (_transport_speed == 0) {
- no_roll (nframes, 0);
+ no_roll (nframes);
return;
}
}
if (maybe_stop (stop_limit)) {
- no_roll (nframes, 0);
+ no_roll (nframes);
return;
}
the_next_one = next_event;
++the_next_one;
- offset = 0;
while (nframes) {
if (this_nframes) {
- click (_transport_frame, nframes, offset);
+ click (_transport_frame, nframes);
/* now process frames between now and the first event in this block */
prepare_diskstreams ();
- if (process_routes (this_nframes, offset)) {
- no_roll (nframes, 0);
+ if (process_routes (this_nframes)) {
+ fail_roll (nframes);
return;
}
commit_diskstreams (this_nframes, session_needs_butler);
-
+
nframes -= this_nframes;
- offset += this_nframes;
if (frames_moved < 0) {
decrement_transport_position (-frames_moved);
check_declick_out ();
}
+ /* reset port offsets so that Port::get_buffer() will fetch the correct data */
+
+ Port::increment_port_offset (this_nframes);
+
/* now handle this event and all others scheduled for the same time */
while (this_event && this_event->action_frame == _transport_frame) {
/* if an event left our state changing, do the right thing */
if (nframes && non_realtime_work_pending()) {
- no_roll (nframes, offset);
+ no_roll (nframes);
break;
}
/* this is necessary to handle the case of seamless looping */
end_frame = _transport_frame + (nframes_t) floor (nframes * _transport_speed);
-
}
set_next_event ();
}
bool
-Session::follow_slave (nframes_t nframes, nframes_t offset)
+Session::follow_slave (nframes_t nframes)
{
float slave_speed;
nframes_t slave_transport_frame;
bool need_butler;
prepare_diskstreams ();
- silent_process_routes (nframes, offset);
+ silent_process_routes (nframes);
commit_diskstreams (nframes, need_butler);
if (need_butler) {
noroll:
/* don't move at all */
- no_roll (nframes, 0);
+ no_roll (nframes);
return false;
}
bool session_needs_butler = false;
nframes_t stop_limit;
long frames_moved;
- nframes_t offset = 0;
if (!process_can_proceed()) {
_silent = true;
}
if (!_exporting && _slave) {
- if (!follow_slave (nframes, 0)) {
+ if (!follow_slave (nframes)) {
return;
}
}
if (_transport_speed == 0) {
- no_roll (nframes, 0);
+ fail_roll (nframes);
return;
}
}
if (maybe_stop (stop_limit)) {
- no_roll (nframes, 0);
+ fail_roll (nframes);
return;
}
- if (maybe_sync_start (nframes, offset)) {
+ if (maybe_sync_start (nframes)) {
return;
}
- click (_transport_frame, nframes, offset);
+ click (_transport_frame, nframes);
prepare_diskstreams ();
frames_moved = (long) floor (_transport_speed * nframes);
- if (process_routes (nframes, offset)) {
- no_roll (nframes, offset);
+ if (process_routes (nframes)) {
+ fail_roll (nframes);
return;
}
for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
if (!(*i)->hidden()) {
- (*i)->silence (nframes, 0);
+ (*i)->silence (nframes);
}
}
}
bool
-Session::maybe_sync_start (nframes_t& nframes, nframes_t& offset)
+Session::maybe_sync_start (nframes_t& nframes)
{
nframes_t sync_offset;
is left to do.
*/
- no_roll (sync_offset, 0);
+ no_roll (sync_offset);
nframes -= sync_offset;
- offset += sync_offset;
+ Port::increment_port_offset (sync_offset);
waiting_for_sync_offset = false;
if (nframes == 0) {