From d68045d6c5933580dace6b63311040f4b1716f72 Mon Sep 17 00:00:00 2001 From: Paul Davis Date: Tue, 14 Apr 2009 19:23:58 +0000 Subject: [PATCH] EXPERIMENTAL! NEEDS TESTING! remove "offset" from almost everything in the process callback tree git-svn-id: svn://localhost/ardour2/branches/2.0-ongoing@4979 d708f5d6-7413-0410-9779-e7cbd77b26cf --- libs/ardour/ardour/audio_diskstream.h | 2 +- libs/ardour/ardour/audio_track.h | 8 +-- libs/ardour/ardour/diskstream.h | 2 +- libs/ardour/ardour/insert.h | 10 +-- libs/ardour/ardour/io.h | 25 ++++--- libs/ardour/ardour/port.h | 52 ++++++++++----- libs/ardour/ardour/redirect.h | 2 +- libs/ardour/ardour/route.h | 14 ++-- libs/ardour/ardour/send.h | 2 +- libs/ardour/ardour/session.h | 13 ++-- libs/ardour/ardour/track.h | 8 +-- libs/ardour/audio_diskstream.cc | 21 ++++-- libs/ardour/audio_track.cc | 63 +++++++++--------- libs/ardour/audioengine.cc | 24 +++++-- libs/ardour/auditioner.cc | 6 +- libs/ardour/insert.cc | 57 +++++----------- libs/ardour/io.cc | 95 ++++++++++++++++++--------- libs/ardour/port.cc | 2 + libs/ardour/redirect.cc | 2 +- libs/ardour/route.cc | 92 ++++++++++++++------------ libs/ardour/send.cc | 9 ++- libs/ardour/session_click.cc | 6 +- libs/ardour/session_export.cc | 4 +- libs/ardour/session_process.cc | 80 ++++++++++++---------- 24 files changed, 342 insertions(+), 257 deletions(-) diff --git a/libs/ardour/ardour/audio_diskstream.h b/libs/ardour/ardour/audio_diskstream.h index 7b7df480d8..223d86616a 100644 --- a/libs/ardour/ardour/audio_diskstream.h +++ b/libs/ardour/ardour/audio_diskstream.h @@ -174,7 +174,7 @@ class AudioDiskstream : public Diskstream 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: diff --git a/libs/ardour/ardour/audio_track.h b/libs/ardour/ardour/audio_track.h index b9722637f4..88fb006ebf 100644 --- a/libs/ardour/ardour/audio_track.h +++ b/libs/ardour/ardour/audio_track.h @@ -40,13 +40,13 @@ class AudioTrack : public Track 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 audio_diskstream() const; @@ -68,7 +68,7 @@ class AudioTrack : public Track 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 (); diff --git a/libs/ardour/ardour/diskstream.h b/libs/ardour/ardour/diskstream.h index fd558019c9..6fb659400d 100644 --- a/libs/ardour/ardour/diskstream.h +++ b/libs/ardour/ardour/diskstream.h @@ -177,7 +177,7 @@ class Diskstream : public PBD::StatefulDestructible 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 */ diff --git a/libs/ardour/ardour/insert.h b/libs/ardour/ardour/insert.h index 8691a292b1..c401a2062e 100644 --- a/libs/ardour/ardour/insert.h +++ b/libs/ardour/ardour/insert.h @@ -49,7 +49,7 @@ class Insert : public Redirect virtual ~Insert() { } - virtual void run (vector& bufs, uint32_t nbufs, nframes_t nframes, nframes_t offset) = 0; + virtual void run (vector& bufs, uint32_t nbufs, nframes_t nframes) = 0; virtual void activate () {} virtual void deactivate () {} @@ -70,7 +70,7 @@ class PortInsert : public Insert int set_state(const XMLNode&); void init (); - void run (vector& bufs, uint32_t nbufs, nframes_t nframes, nframes_t offset); + void run (vector& bufs, uint32_t nbufs, nframes_t nframes); nframes_t latency(); @@ -99,8 +99,8 @@ class PluginInsert : public Insert XMLNode& get_state(void); int set_state(const XMLNode&); - void run (vector& bufs, uint32_t nbufs, nframes_t nframes, nframes_t offset); - void silence (nframes_t nframes, nframes_t offset); + void run (vector& bufs, uint32_t nbufs, nframes_t nframes); + void silence (nframes_t nframes); void activate (); void deactivate (); @@ -149,7 +149,7 @@ class PluginInsert : public Insert void parameter_changed (uint32_t, float); vector > _plugins; - void automation_run (vector& bufs, uint32_t nbufs, nframes_t nframes, nframes_t offset); + void automation_run (vector& bufs, uint32_t nbufs, nframes_t nframes); void connect_and_run (vector& bufs, uint32_t nbufs, nframes_t nframes, nframes_t offset, bool with_auto, nframes_t now = 0); void init (); diff --git a/libs/ardour/ardour/io.h b/libs/ardour/ardour/io.h index a9be3c9e4e..556e30bfac 100644 --- a/libs/ardour/ardour/io.h +++ b/libs/ardour/ardour/io.h @@ -90,18 +90,17 @@ class IO : public PBD::StatefulDestructible 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& bufs, uint32_t nbufs, nframes_t nframes, nframes_t offset, gain_t gain_coeff); + void pan (vector& bufs, uint32_t nbufs, nframes_t nframes, gain_t gain_coeff); void pan_automated (vector& bufs, uint32_t nbufs, nframes_t start_frame, nframes_t end_frame, - nframes_t nframes, nframes_t offset); - void collect_input (vector&, uint32_t nbufs, nframes_t nframes, nframes_t offset); - void deliver_output (vector&, uint32_t nbufs, nframes_t nframes, nframes_t offset); - void deliver_output_no_pan (vector&, 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&, uint32_t nbufs, nframes_t nframes); + void deliver_output (vector&, uint32_t nbufs, nframes_t nframes); + void deliver_output_no_pan (vector&, 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; } @@ -161,6 +160,9 @@ class IO : public PBD::StatefulDestructible 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 active_changed; sigc::signal input_changed; @@ -214,6 +216,7 @@ class IO : public PBD::StatefulDestructible void reset_max_peak_meters (); + static sigc::signal CycleStart; static void update_meters(); static std::string name_from_state (const XMLNode&); @@ -348,6 +351,10 @@ class IO : public PBD::StatefulDestructible 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; @@ -355,6 +362,8 @@ class IO : public PBD::StatefulDestructible uint32_t _ninputs; uint32_t _noutputs; + nframes_t _output_offset; + /* are these the best variable names ever, or what? */ diff --git a/libs/ardour/ardour/port.h b/libs/ardour/ardour/port.h index bff6c7d298..6f97f035f5 100644 --- a/libs/ardour/ardour/port.h +++ b/libs/ardour/ardour/port.h @@ -36,8 +36,16 @@ class Port : public sigc::trackable { // 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() { @@ -97,8 +105,8 @@ class Port : public sigc::trackable { 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; } @@ -151,15 +159,11 @@ class Port : public sigc::trackable { 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; } } @@ -188,15 +192,33 @@ class Port : public sigc::trackable { 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 diff --git a/libs/ardour/ardour/redirect.h b/libs/ardour/ardour/redirect.h index ec0006c2ce..e24494f23d 100644 --- a/libs/ardour/ardour/redirect.h +++ b/libs/ardour/ardour/redirect.h @@ -70,7 +70,7 @@ class Redirect : public IO Placement placement() const { return _placement; } void set_placement (Placement, void *src); - virtual void run (vector& ibufs, uint32_t nbufs, nframes_t nframes, nframes_t offset) = 0; + virtual void run (vector& ibufs, uint32_t nbufs, nframes_t nframes) = 0; virtual void activate () = 0; virtual void deactivate () = 0; virtual nframes_t latency() { return 0; } diff --git a/libs/ardour/ardour/route.h b/libs/ardour/ardour/route.h index c3c92e9116..7dab4eecb7 100644 --- a/libs/ardour/ardour/route.h +++ b/libs/ardour/ardour/route.h @@ -90,13 +90,13 @@ class Route : public IO 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) {} @@ -285,7 +285,7 @@ class Route : public IO 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; @@ -303,11 +303,11 @@ class Route : public IO 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& 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: @@ -315,7 +315,7 @@ class Route : public IO 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; diff --git a/libs/ardour/ardour/send.h b/libs/ardour/ardour/send.h index 92e4fdade2..e241c6dbf8 100644 --- a/libs/ardour/ardour/send.h +++ b/libs/ardour/ardour/send.h @@ -42,7 +42,7 @@ class Send : public Redirect uint32_t bit_slot() const { return bitslot; } - void run (vector &bufs, uint32_t nbufs, nframes_t nframes, nframes_t offset); + void run (vector &bufs, uint32_t nbufs, nframes_t nframes); void activate() {} void deactivate () {} diff --git a/libs/ardour/ardour/session.h b/libs/ardour/ardour/session.h index cba51e2ce3..b2f9197a4d 100644 --- a/libs/ardour/ardour/session.h +++ b/libs/ardour/ardour/session.h @@ -1089,7 +1089,7 @@ class Session : public PBD::StatefulDestructible 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; @@ -1097,8 +1097,8 @@ class Session : public PBD::StatefulDestructible 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()) { @@ -1132,7 +1132,7 @@ class Session : public PBD::StatefulDestructible return false; } - bool maybe_sync_start (nframes_t&, nframes_t&); + bool maybe_sync_start (nframes_t&); void check_declick_out (); @@ -1379,7 +1379,8 @@ class Session : public PBD::StatefulDestructible 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(post_transport_work); } bool process_can_proceed() const { return !(post_transport_work & ProcessCannotProceedMask); } @@ -1716,7 +1717,7 @@ class Session : public PBD::StatefulDestructible 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 master_outs; diff --git a/libs/ardour/ardour/track.h b/libs/ardour/ardour/track.h index 6a1a4e2e7e..4699013369 100644 --- a/libs/ardour/ardour/track.h +++ b/libs/ardour/ardour/track.h @@ -45,13 +45,13 @@ class Track : public Route sigc::signal 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 (); @@ -101,7 +101,7 @@ class Track : public Route 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; diff --git a/libs/ardour/audio_diskstream.cc b/libs/ardour/audio_diskstream.cc index 419efe897d..4310e56b1b 100644 --- a/libs/ardour/audio_diskstream.cc +++ b/libs/ardour/audio_diskstream.cc @@ -407,6 +407,7 @@ AudioDiskstream::check_record_status (nframes_t transport_frame, nframes_t nfram /* 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; @@ -415,9 +416,11 @@ AudioDiskstream::check_record_status (nframes_t transport_frame, nframes_t nfram /* 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 { @@ -440,6 +443,7 @@ AudioDiskstream::check_record_status (nframes_t transport_frame, nframes_t nfram this is needed. */ + // cerr << "1 FRF += " << _capture_offset << endl; first_recordable_frame += _capture_offset; } else { @@ -450,12 +454,14 @@ AudioDiskstream::check_record_status (nframes_t transport_frame, nframes_t nfram 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; @@ -464,6 +470,8 @@ AudioDiskstream::check_record_status (nframes_t transport_frame, nframes_t nfram } + // cerr << _name << " FRF = " << first_recordable_frame << " CSF = " << capture_start_frame << endl; + if (recordable() && destructive()) { boost::shared_ptr c = channels.reader(); for (ChannelList::iterator chan = c->begin(); chan != c->end(); ++chan) { @@ -501,7 +509,7 @@ AudioDiskstream::check_record_status (nframes_t transport_frame, nframes_t nfram } 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 c = channels.reader(); @@ -645,7 +653,7 @@ AudioDiskstream::process (nframes_t transport_frame, nframes_t nframes, nframes_ 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 { @@ -656,7 +664,7 @@ AudioDiskstream::process (nframes_t transport_frame, nframes_t nframes, nframes_ 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); @@ -1407,7 +1415,8 @@ AudioDiskstream::do_flush (Session::RunContext context, bool force_flush) vector.buf[1] = 0; boost::shared_ptr 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); diff --git a/libs/ardour/audio_track.cc b/libs/ardour/audio_track.cc index 27d4a8a967..95099676e7 100644 --- a/libs/ardour/audio_track.cc +++ b/libs/ardour/audio_track.cc @@ -463,14 +463,15 @@ AudioTrack::n_process_buffers () } 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) { @@ -478,7 +479,7 @@ AudioTrack::no_roll (nframes_t nframes, nframes_t start_frame, nframes_t end_fra } if (!_active) { - silence (nframes, offset); + silence (nframes); return 0; } @@ -486,7 +487,7 @@ AudioTrack::no_roll (nframes_t nframes, nframes_t start_frame, nframes_t end_fra /* 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; } @@ -535,12 +536,12 @@ AudioTrack::no_roll (nframes_t nframes, nframes_t start_frame, nframes_t end_fra */ 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 { @@ -548,14 +549,14 @@ AudioTrack::no_roll (nframes_t nframes, nframes_t start_frame, nframes_t end_fra /* 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; @@ -579,26 +580,28 @@ AudioTrack::roll (nframes_t nframes, nframes_t start_frame, nframes_t end_frame, } 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; } @@ -606,7 +609,7 @@ AudioTrack::roll (nframes_t nframes, nframes_t start_frame, nframes_t end_frame, /* 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()) { @@ -615,7 +618,7 @@ AudioTrack::roll (nframes_t nframes, nframes_t start_frame, nframes_t end_frame, 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) { @@ -709,18 +712,18 @@ AudioTrack::roll (nframes_t nframes, nframes_t start_frame, nframes_t end_frame, } } - 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()) { @@ -728,16 +731,16 @@ AudioTrack::silent_roll (nframes_t nframes, nframes_t start_frame, nframes_t end } 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 @@ -793,7 +796,7 @@ AudioTrack::export_stuff (vector& buffers, uint32_t nbufs, nframes_t st if ((insert = boost::dynamic_pointer_cast(*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; @@ -830,7 +833,7 @@ AudioTrack::export_stuff (vector& buffers, uint32_t nbufs, nframes_t st case PreFader: break; case PostFader: - insert->run (buffers, nbufs, nframes, 0); + insert->run (buffers, nbufs, nframes); break; } } diff --git a/libs/ardour/audioengine.cc b/libs/ardour/audioengine.cc index cc74b92a69..c31ce98a37 100644 --- a/libs/ardour/audioengine.cc +++ b/libs/ardour/audioengine.cc @@ -29,6 +29,7 @@ #include #include #include +#include #include #include #include @@ -110,8 +111,11 @@ AudioEngine::start () 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")); @@ -293,6 +297,14 @@ AudioEngine::process_callback (nframes_t nframes) 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); @@ -340,7 +352,7 @@ AudioEngine::process_callback (nframes_t nframes) 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 @@ -391,8 +403,11 @@ AudioEngine::jack_bufsize_callback (nframes_t nframes) _usecs_per_cycle = (int) floor ((((double) nframes / frame_rate())) * 1000000.0); last_monitor_check = 0; - boost::shared_ptr p = ports.reader(); + cerr << "bufsize: Set Port buffer size to " << nframes << endl; + Port::set_buffer_size (nframes); + boost::shared_ptr p = ports.reader(); + for (Ports::iterator i = p->begin(); i != p->end(); ++i) { (*i)->reset(); } @@ -1173,7 +1188,7 @@ AudioEngine::reconnect_to_jack () (*i)->reset (); if ((*i)->flags() & JackPortIsOutput) { - (*i)->silence (jack_get_buffer_size (_jack), 0); + (*i)->silence (jack_get_buffer_size (_jack)); } } @@ -1189,6 +1204,7 @@ AudioEngine::reconnect_to_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)); } diff --git a/libs/ardour/auditioner.cc b/libs/ardour/auditioner.cc index 7f1154a13d..b9ebace352 100644 --- a/libs/ardour/auditioner.cc +++ b/libs/ardour/auditioner.cc @@ -173,7 +173,7 @@ Auditioner::play_audition (nframes_t nframes) int ret; if (g_atomic_int_get (&_active) == 0) { - silence (nframes, 0); + silence (nframes); return 0; } @@ -181,8 +181,8 @@ Auditioner::play_audition (nframes_t nframes) _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; } diff --git a/libs/ardour/insert.cc b/libs/ardour/insert.cc index e748e4bb29..a866191359 100644 --- a/libs/ardour/insert.cc +++ b/libs/ardour/insert.cc @@ -308,12 +308,8 @@ PluginInsert::connect_and_run (vector& bufs, uint32_t nbufs, nframes_t } for (vector >::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 @@ -355,7 +351,7 @@ PluginInsert::transport_stopped (nframes_t now) } void -PluginInsert::silence (nframes_t nframes, nframes_t offset) +PluginInsert::silence (nframes_t nframes) { int32_t in_index = 0; int32_t out_index = 0; @@ -364,20 +360,20 @@ PluginInsert::silence (nframes_t nframes, nframes_t offset) if (active()) { for (vector >::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& bufs, uint32_t nbufs, nframes_t nframes, nframes_t offset) +PluginInsert::run (vector& 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 { @@ -413,63 +409,46 @@ PluginInsert::set_parameter (uint32_t port, float val) } void -PluginInsert::automation_run (vector& bufs, uint32_t nbufs, nframes_t nframes, nframes_t offset) +PluginInsert::automation_run (vector& 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 @@ -939,7 +918,7 @@ PortInsert::~PortInsert () } void -PortInsert::run (vector& bufs, uint32_t nbufs, nframes_t nframes, nframes_t offset) +PortInsert::run (vector& bufs, uint32_t nbufs, nframes_t nframes) { if (n_outputs() == 0) { return; @@ -947,7 +926,7 @@ PortInsert::run (vector& bufs, uint32_t nbufs, nframes_t nframes, nfra if (!active()) { /* deliver silence */ - silence (nframes, offset); + silence (nframes); return; } @@ -958,14 +937,14 @@ PortInsert::run (vector& bufs, uint32_t nbufs, nframes_t nframes, nfra /* 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); } } diff --git a/libs/ardour/io.cc b/libs/ardour/io.cc index 4a993cae11..2e2482d8f0 100644 --- a/libs/ardour/io.cc +++ b/libs/ardour/io.cc @@ -72,6 +72,7 @@ sigc::signal IO::PortsLegal; sigc::signal IO::PannersLegal; sigc::signal IO::MoreOutputs; sigc::signal IO::PortsCreated; +sigc::signal IO::CycleStart; Glib::StaticMutex IO::m_meter_signal_lock = GLIBMM_STATIC_MUTEX_INIT; @@ -141,6 +142,9 @@ IO::IO (Session& s, string name, 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); } @@ -173,6 +177,9 @@ IO::IO (Session& s, const XMLNode& node, DataType dt) 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); } @@ -199,12 +206,12 @@ IO::~IO () } 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::iterator i = _outputs.begin(); i != _outputs.end(); ++i) { - (*i)->silence (nframes, offset); + (*i)->silence (nframes); } } @@ -265,7 +272,7 @@ IO::apply_declick (vector& bufs, uint32_t nbufs, nframes_t nframes, ga } void -IO::pan_automated (vector& bufs, uint32_t nbufs, nframes_t start, nframes_t end, nframes_t nframes, nframes_t offset) +IO::pan_automated (vector& bufs, uint32_t nbufs, nframes_t start, nframes_t end, nframes_t nframes) { Sample* dst; @@ -277,7 +284,7 @@ IO::pan_automated (vector& bufs, uint32_t nbufs, nframes_t start, nfram 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) { @@ -299,7 +306,7 @@ IO::pan_automated (vector& bufs, uint32_t nbufs, nframes_t start, nfram /* 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); } @@ -312,7 +319,7 @@ IO::pan_automated (vector& bufs, uint32_t nbufs, nframes_t start, nfram } void -IO::pan (vector& bufs, uint32_t nbufs, nframes_t nframes, nframes_t offset, gain_t gain_coeff) +IO::pan (vector& bufs, uint32_t nbufs, nframes_t nframes, gain_t gain_coeff) { Sample* dst; Sample* src; @@ -328,13 +335,13 @@ IO::pan (vector& bufs, uint32_t nbufs, nframes_t nframes, nframes_t off */ 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) { @@ -389,7 +396,7 @@ IO::pan (vector& bufs, uint32_t nbufs, nframes_t nframes, nframes_t off /* 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); } @@ -411,7 +418,7 @@ IO::pan (vector& bufs, uint32_t nbufs, nframes_t nframes, nframes_t off } void -IO::deliver_output (vector& bufs, uint32_t nbufs, nframes_t nframes, nframes_t offset) +IO::deliver_output (vector& bufs, uint32_t nbufs, nframes_t nframes) { /* io_lock, not taken: function must be called from Session::process() calltree */ @@ -420,7 +427,7 @@ IO::deliver_output (vector& bufs, uint32_t nbufs, nframes_t nframes, n } if (_panner->bypassed() || _panner->empty()) { - deliver_output_no_pan (bufs, nbufs, nframes, offset); + deliver_output_no_pan (bufs, nbufs, nframes); return; } @@ -447,14 +454,14 @@ IO::deliver_output (vector& bufs, uint32_t nbufs, nframes_t nframes, n /* 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& bufs, uint32_t nbufs, nframes_t nframes, nframes_t offset) +IO::deliver_output_no_pan (vector& bufs, uint32_t nbufs, nframes_t nframes) { /* io_lock, not taken: function must be called from Session::process() calltree */ @@ -504,7 +511,7 @@ IO::deliver_output_no_pan (vector& bufs, uint32_t nbufs, nframes_t nfr 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) { @@ -536,7 +543,7 @@ IO::deliver_output_no_pan (vector& bufs, uint32_t nbufs, nframes_t nfr } void -IO::collect_input (vector& bufs, uint32_t nbufs, nframes_t nframes, nframes_t offset) +IO::collect_input (vector& bufs, uint32_t nbufs, nframes_t nframes) { /* io_lock, not taken: function must be called from Session::process() calltree */ @@ -550,19 +557,8 @@ IO::collect_input (vector& bufs, uint32_t nbufs, nframes_t nframes, nf 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); } @@ -570,7 +566,6 @@ IO::collect_input (vector& bufs, uint32_t nbufs, nframes_t nframes, nf if (last) { while (n < nbufs) { - // the dest buffer's offset has already been applied memcpy (bufs[n], last, sizeof (Sample) * nframes); ++n; } @@ -583,13 +578,12 @@ IO::collect_input (vector& bufs, uint32_t nbufs, nframes_t nframes, nf } 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& 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]); @@ -2827,3 +2821,40 @@ IO::set_name_in_state (XMLNode& node, const string& new_name) 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; +} + diff --git a/libs/ardour/port.cc b/libs/ardour/port.cc index 83c835cac6..f218cbc914 100644 --- a/libs/ardour/port.cc +++ b/libs/ardour/port.cc @@ -24,6 +24,8 @@ using namespace std; 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) diff --git a/libs/ardour/redirect.cc b/libs/ardour/redirect.cc index 42195ba47f..5f99c742ad 100644 --- a/libs/ardour/redirect.cc +++ b/libs/ardour/redirect.cc @@ -456,7 +456,7 @@ Redirect::find_next_event (nframes_t now, nframes_t end, ControlEvent& next_even AutomationList::TimeComparator cmp; next_event.when = max_frames; - + for (li = parameter_automation.begin(); li != parameter_automation.end(); ++li) { const AutomationList* alist = *li; diff --git a/libs/ardour/route.cc b/libs/ardour/route.cc index 4553bf2909..6c791ca431 100644 --- a/libs/ardour/route.cc +++ b/libs/ardour/route.cc @@ -277,7 +277,7 @@ Route::set_gain (gain_t val, void *src) void Route::process_output_buffers (vector& 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; @@ -385,11 +385,11 @@ Route::process_output_buffers (vector& bufs, uint32_t nbufs, ) { - co->silence (nframes, offset); + co->silence (nframes); } else { - co->deliver_output (bufs, nbufs, nframes, offset); + co->deliver_output (bufs, nbufs, nframes); } } @@ -403,7 +403,7 @@ Route::process_output_buffers (vector& bufs, uint32_t nbufs, 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; } } @@ -423,10 +423,10 @@ Route::process_output_buffers (vector& bufs, uint32_t nbufs, case PreFader: if (dsg == 0) { if (boost::dynamic_pointer_cast(*i) || boost::dynamic_pointer_cast(*i)) { - (*i)->silence (nframes, offset); + (*i)->silence (nframes); } } else { - (*i)->run (bufs, nbufs, nframes, offset); + (*i)->run (bufs, nbufs, nframes); } break; case PostFader: @@ -438,7 +438,7 @@ Route::process_output_buffers (vector& bufs, uint32_t nbufs, 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; @@ -486,11 +486,11 @@ Route::process_output_buffers (vector& bufs, uint32_t nbufs, ) { - 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); } } @@ -596,10 +596,10 @@ Route::process_output_buffers (vector& bufs, uint32_t nbufs, case PostFader: if (dsg == 0) { if (boost::dynamic_pointer_cast(*i) || boost::dynamic_pointer_cast(*i)) { - (*i)->silence (nframes, offset); + (*i)->silence (nframes); } } else { - (*i)->run (bufs, nbufs, nframes, offset); + (*i)->run (bufs, nbufs, nframes); } break; } @@ -610,7 +610,7 @@ Route::process_output_buffers (vector& bufs, uint32_t nbufs, case PreFader: break; case PostFader: - (*i)->silence (nframes, offset); + (*i)->silence (nframes); break; } } @@ -651,11 +651,11 @@ Route::process_output_buffers (vector& bufs, uint32_t nbufs, ) { - 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); } } @@ -682,7 +682,7 @@ Route::process_output_buffers (vector& bufs, uint32_t nbufs, } else if (no_monitor && record_enabled() && (!Config->get_auto_input() || _session.actively_recording())) { - IO::silence (nframes, offset); + IO::silence (nframes); } else { @@ -708,22 +708,22 @@ Route::process_output_buffers (vector& bufs, uint32_t nbufs, 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); } } } @@ -744,7 +744,7 @@ Route::process_output_buffers (vector& bufs, uint32_t nbufs, } 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]); } } } @@ -758,14 +758,14 @@ Route::n_process_buffers () 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& 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 @@ -778,7 +778,7 @@ Route::passthru (nframes_t start_frame, nframes_t end_frame, nframes_t nframes, 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 } @@ -2005,16 +2005,16 @@ Route::curve_reallocate () } 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); } { @@ -2028,10 +2028,10 @@ Route::silence (nframes_t nframes, nframes_t offset) continue; } - (*i)->silence (nframes, offset); + (*i)->silence (nframes); } - if (nframes == _session.get_block_size() && offset == 0) { + if (nframes == _session.get_block_size()) { // _silent = true; } } @@ -2310,36 +2310,36 @@ Route::pans_required () const } 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; @@ -2347,9 +2347,15 @@ Route::check_initial_delay (nframes_t nframes, nframes_t& offset, nframes_t& tra 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; @@ -2359,7 +2365,7 @@ Route::check_initial_delay (nframes_t nframes, nframes_t& offset, nframes_t& tra } 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) { { @@ -2372,13 +2378,13 @@ Route::roll (nframes_t nframes, nframes_t start_frame, nframes_t end_frame, nfra } 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; } @@ -2399,16 +2405,16 @@ Route::roll (nframes_t nframes, nframes_t start_frame, nframes_t end_frame, nfra } } - 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; } diff --git a/libs/ardour/send.cc b/libs/ardour/send.cc index 20ec4819a1..19b9e43622 100644 --- a/libs/ardour/send.cc +++ b/libs/ardour/send.cc @@ -150,7 +150,7 @@ Send::set_state(const XMLNode& node) } void -Send::run (vector& bufs, uint32_t nbufs, nframes_t nframes, nframes_t offset) +Send::run (vector& bufs, uint32_t nbufs, nframes_t nframes) { if (active()) { @@ -163,8 +163,7 @@ Send::run (vector& bufs, uint32_t nbufs, nframes_t nframes, nframes_t 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; @@ -179,13 +178,13 @@ Send::run (vector& bufs, uint32_t nbufs, nframes_t nframes, nframes_t } 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; diff --git a/libs/ardour/session_click.cc b/libs/ardour/session_click.cc index f48054c532..7dbfe4d406 100644 --- a/libs/ardour/session_click.cc +++ b/libs/ardour/session_click.cc @@ -36,7 +36,7 @@ using namespace PBD; 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; @@ -50,7 +50,7 @@ Session::click (nframes_t start, nframes_t nframes, nframes_t offset) 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; } @@ -127,7 +127,7 @@ Session::click (nframes_t start, nframes_t nframes, nframes_t offset) i = next; } - _click_io->deliver_output (_passthru_buffers, 1, nframes, offset); + _click_io->deliver_output (_passthru_buffers, 1, nframes); } void diff --git a/libs/ardour/session_export.cc b/libs/ardour/session_export.cc index 53e63fd338..db11c61276 100644 --- a/libs/ardour/session_export.cc +++ b/libs/ardour/session_export.cc @@ -582,13 +582,13 @@ Session::process_export (nframes_t nframes, AudioExportSpecification* spec) if (!_exporting) { /* finished, but still freewheeling */ cerr << "\tExport ... not exporting yet, no_roll() for " << nframes <running || spec->stop || (this_nframes = min ((spec->end_frame - spec->pos), nframes)) == 0) { cerr << "\tExport ... not running or at end, no_roll() for " << nframes < 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) { @@ -95,7 +103,7 @@ Session::no_roll (nframes_t nframes, nframes_t offset) (*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; @@ -107,7 +115,7 @@ Session::no_roll (nframes_t nframes, nframes_t offset) } 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(); @@ -131,7 +139,7 @@ Session::process_routes (nframes_t nframes, nframes_t offset) (*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 @@ -152,7 +160,7 @@ Session::process_routes (nframes_t nframes, nframes_t offset) } 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(); @@ -172,7 +180,7 @@ Session::silent_process_routes (nframes_t nframes, nframes_t offset) 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 @@ -212,7 +220,7 @@ Session::commit_diskstreams (nframes_t nframes, bool &needs_butler) 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; } @@ -246,7 +254,7 @@ Session::process_with_events (nframes_t nframes) 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; @@ -254,7 +262,7 @@ Session::process_with_events (nframes_t nframes) /* make sure the auditioner is silent */ if (auditioner) { - auditioner->silence (nframes, 0); + auditioner->silence (nframes); } /* handle any pending events */ @@ -296,13 +304,13 @@ Session::process_with_events (nframes_t nframes) } 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; } @@ -318,7 +326,7 @@ Session::process_with_events (nframes_t nframes) } if (maybe_stop (stop_limit)) { - no_roll (nframes, 0); + no_roll (nframes); return; } @@ -326,7 +334,6 @@ Session::process_with_events (nframes_t nframes) the_next_one = next_event; ++the_next_one; - offset = 0; while (nframes) { @@ -342,20 +349,19 @@ Session::process_with_events (nframes_t 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); @@ -367,6 +373,10 @@ Session::process_with_events (nframes_t nframes) 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) { @@ -383,13 +393,12 @@ Session::process_with_events (nframes_t nframes) /* 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 (); @@ -430,7 +439,7 @@ Session::transport_locked () const } bool -Session::follow_slave (nframes_t nframes, nframes_t offset) +Session::follow_slave (nframes_t nframes) { float slave_speed; nframes_t slave_transport_frame; @@ -680,7 +689,7 @@ Session::follow_slave (nframes_t nframes, nframes_t offset) bool need_butler; prepare_diskstreams (); - silent_process_routes (nframes, offset); + silent_process_routes (nframes); commit_diskstreams (nframes, need_butler); if (need_butler) { @@ -712,7 +721,7 @@ Session::follow_slave (nframes_t nframes, nframes_t offset) noroll: /* don't move at all */ - no_roll (nframes, 0); + no_roll (nframes); return false; } @@ -722,7 +731,6 @@ Session::process_without_events (nframes_t nframes) bool session_needs_butler = false; nframes_t stop_limit; long frames_moved; - nframes_t offset = 0; if (!process_can_proceed()) { _silent = true; @@ -730,13 +738,13 @@ Session::process_without_events (nframes_t nframes) } 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; } @@ -751,22 +759,22 @@ Session::process_without_events (nframes_t nframes) } 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; } @@ -800,7 +808,7 @@ Session::process_audition (nframes_t nframes) for (RouteList::iterator i = r->begin(); i != r->end(); ++i) { if (!(*i)->hidden()) { - (*i)->silence (nframes, 0); + (*i)->silence (nframes); } } @@ -833,7 +841,7 @@ Session::process_audition (nframes_t nframes) } bool -Session::maybe_sync_start (nframes_t& nframes, nframes_t& offset) +Session::maybe_sync_start (nframes_t& nframes) { nframes_t sync_offset; @@ -848,9 +856,9 @@ Session::maybe_sync_start (nframes_t& nframes, nframes_t& 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) { -- 2.30.2