EXPERIMENTAL! NEEDS TESTING! remove "offset" from almost everything in the process...
authorPaul Davis <paul@linuxaudiosystems.com>
Tue, 14 Apr 2009 19:23:58 +0000 (19:23 +0000)
committerPaul Davis <paul@linuxaudiosystems.com>
Tue, 14 Apr 2009 19:23:58 +0000 (19:23 +0000)
git-svn-id: svn://localhost/ardour2/branches/2.0-ongoing@4979 d708f5d6-7413-0410-9779-e7cbd77b26cf

24 files changed:
libs/ardour/ardour/audio_diskstream.h
libs/ardour/ardour/audio_track.h
libs/ardour/ardour/diskstream.h
libs/ardour/ardour/insert.h
libs/ardour/ardour/io.h
libs/ardour/ardour/port.h
libs/ardour/ardour/redirect.h
libs/ardour/ardour/route.h
libs/ardour/ardour/send.h
libs/ardour/ardour/session.h
libs/ardour/ardour/track.h
libs/ardour/audio_diskstream.cc
libs/ardour/audio_track.cc
libs/ardour/audioengine.cc
libs/ardour/auditioner.cc
libs/ardour/insert.cc
libs/ardour/io.cc
libs/ardour/port.cc
libs/ardour/redirect.cc
libs/ardour/route.cc
libs/ardour/send.cc
libs/ardour/session_click.cc
libs/ardour/session_export.cc
libs/ardour/session_process.cc

index 7b7df480d8673062dd9c8c859feaa9c7e1eb3f70..223d86616ac3471f4658ff46d79ab8af312cd462 100644 (file)
@@ -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:
index b9722637f4820de2d4e428b84a2dbac0e6466800..88fb006ebfddab8594f0bc0620ec8e72109392a1 100644 (file)
@@ -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<AudioDiskstream> 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 ();
index fd558019c9daba858dacb96231c77b921ecaabf2..6fb659400dbd6030e4517b865fd6585c710264b3 100644 (file)
@@ -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 */
 
index 8691a292b134c04ad99cb790dcc5cb4336d8c1b2..c401a2062e038cd9a445a8458f14c8c8efa87754 100644 (file)
@@ -49,7 +49,7 @@ class Insert : public Redirect
        
        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 () {}
 
@@ -70,7 +70,7 @@ class PortInsert : public Insert
        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();
        
@@ -99,8 +99,8 @@ class PluginInsert : public Insert
        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 ();
 
@@ -149,7 +149,7 @@ class PluginInsert : public Insert
        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 ();
index a9be3c9e4ee0c6984cad4bcd910f5d4f1dfc3d36..556e30bfacf496eb2c94ed14403a3b4f0ba57934 100644 (file)
@@ -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<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; }
 
@@ -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<void>                active_changed;
 
        sigc::signal<void,IOChange,void*> input_changed;
@@ -214,6 +216,7 @@ class IO : public PBD::StatefulDestructible
 
        void reset_max_peak_meters ();
 
+       static sigc::signal<void,nframes_t> 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? */
 
index bff6c7d29817b45e479dba0ed4ef3b1b5f571a8c..6f97f035f55606dee33b52ced0396bacb0c928d4 100644 (file)
@@ -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
index ec0006c2ce65032969db32f9c0989568f94cb0dd..e24494f23d24fbbde7c6c9054fa78e081027ba33 100644 (file)
@@ -70,7 +70,7 @@ class Redirect : public IO
        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; }
index c3c92e9116c293bf42f4acb62b0b17d11ce9f975..7dab4eecb7adced45be6f77b4e031f90d181ce12 100644 (file)
@@ -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<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:
@@ -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;
index 92e4fdade2958ef8a9a734aeff205e594d9f9e45..e241c6dbf810f9267ab1690d3532a398d95e154b 100644 (file)
@@ -42,7 +42,7 @@ class Send : public Redirect
 
        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 () {}
 
index cba51e2ce39e94812c9bc46d7b8ba6cef905046d..b2f9197a4de297188d674d600b98d94c010505bd 100644 (file)
@@ -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<bool>(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<Route*> master_outs;
        
index 6a1a4e2e7e2a40d9e240a64d7366051644fb6cc2..4699013369a9d3ac592981a823038ad8bfa17ef5 100644 (file)
@@ -45,13 +45,13 @@ class Track : public Route
        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 ();
 
@@ -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;
        
index 419efe897d0e36499980ab8f25a8e0d7c148acf6..4310e56b1b4dd486c1826e9b16b51d3149010e5c 100644 (file)
@@ -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<ChannelList> 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<ChannelList> 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<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);
 
index 27d4a8a967c31a3f4d2d6bb92b2b3ef8b9582a6b..95099676e76256044b34ac3d6f9b13f9ad8d35ed 100644 (file)
@@ -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<Sample*>& buffers, uint32_t nbufs, nframes_t st
                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;
@@ -830,7 +833,7 @@ AudioTrack::export_stuff (vector<Sample*>& buffers, uint32_t nbufs, nframes_t st
                                case PreFader:
                                        break;
                                case PostFader:
-                                       insert->run (buffers, nbufs, nframes, 0);
+                                       insert->run (buffers, nbufs, nframes);
                                        break;
                                }
                        }
index cc74b92a6942c464aec4596d237bf61f28e58c96..c31ce98a37e71dcf2f3487e48db17b9ca40f956d 100644 (file)
@@ -29,6 +29,7 @@
 #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>
@@ -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<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();
        }
@@ -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));
        }
index 7f1154a13d017288b296a3f0616a307c945a1c8e..b9ebace35203e58901910d9bac4c1389e0ba8fd0 100644 (file)
@@ -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;
        }
 
index e748e4bb2970e597341562638cd1541885723d47..a8661913591316c89ab4bca1f36a56509af104a8 100644 (file)
@@ -308,12 +308,8 @@ PluginInsert::connect_and_run (vector<Sample*>& bufs, uint32_t nbufs, nframes_t
        } 
 
        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
@@ -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<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 {
@@ -413,63 +409,46 @@ PluginInsert::set_parameter (uint32_t port, float val)
 }
 
 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
@@ -939,7 +918,7 @@ PortInsert::~PortInsert ()
 }
 
 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;
@@ -947,7 +926,7 @@ PortInsert::run (vector<Sample *>& 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<Sample *>& 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);
        }
 }
 
index 4a993cae11d20bcdb5f42bba946fb76396bdd967..2e2482d8f0ebd5e26b27ce5b726dc985b77ccf44 100644 (file)
@@ -72,6 +72,7 @@ sigc::signal<int>                 IO::PortsLegal;
 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;
 
@@ -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<Port *>::iterator i = _outputs.begin(); i != _outputs.end(); ++i) {
-               (*i)->silence (nframes, offset);
+               (*i)->silence (nframes);
        }
 }
 
@@ -265,7 +272,7 @@ IO::apply_declick (vector<Sample *>& bufs, uint32_t nbufs, nframes_t nframes, ga
 }
 
 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;
 
@@ -277,7 +284,7 @@ IO::pan_automated (vector<Sample*>& 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<Sample*>& 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<Sample*>& bufs, uint32_t nbufs, nframes_t start, nfram
 }
 
 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;
@@ -328,13 +335,13 @@ IO::pan (vector<Sample*>& 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<Sample*>& 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<Sample*>& bufs, uint32_t nbufs, nframes_t nframes, nframes_t off
 }
 
 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 */
 
@@ -420,7 +427,7 @@ IO::deliver_output (vector<Sample *>& 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<Sample *>& 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<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 */
 
@@ -504,7 +511,7 @@ IO::deliver_output_no_pan (vector<Sample *>& 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<Sample *>& bufs, uint32_t nbufs, nframes_t nfr
 }
 
 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 */
 
@@ -550,19 +557,8 @@ IO::collect_input (vector<Sample *>& 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<Sample *>& 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<Sample *>& 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<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]);
@@ -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;
+}
+              
index 83c835cac681d6ac5cf585f059181cca3abadae7..f218cbc914bb4f2e70befc6e90957000ce9b7469 100644 (file)
@@ -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)
index 42195ba47ff1ff4ad368d74961b9a433a6c8739b..5f99c742ad4fd0b334ad66a62eb8c6a1d09f7477 100644 (file)
@@ -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;
index 4553bf2909f3b9f517b4fe591e45f5f3172cc98e..6c791ca4315277acc5a196babec9ea444683cb5e 100644 (file)
@@ -277,7 +277,7 @@ Route::set_gain (gain_t val, void *src)
 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;
@@ -385,11 +385,11 @@ Route::process_output_buffers (vector<Sample*>& 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<Sample*>& 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<Sample*>& bufs, uint32_t nbufs,
                                        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:
@@ -438,7 +438,7 @@ Route::process_output_buffers (vector<Sample*>& 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<Sample*>& 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<Sample*>& bufs, uint32_t nbufs,
                                        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;
                                        }
@@ -610,7 +610,7 @@ Route::process_output_buffers (vector<Sample*>& 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<Sample*>& 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<Sample*>& 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<Sample*>& 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<Sample*>& 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<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
 
@@ -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;
 }
 
index 20ec4819a15f212685ab690210c3991d92416015..19b9e436228aa7c2ede0ca5414238a90701d16ac 100644 (file)
@@ -150,7 +150,7 @@ Send::set_state(const XMLNode& node)
 }
 
 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()) {
 
@@ -163,8 +163,7 @@ Send::run (vector<Sample *>& 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<Sample *>& 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;
index f48054c532c76517fdea9a1278b29650c456aa4e..7dbfe4d40629c69d9324e8315244057583f988c9 100644 (file)
@@ -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
index 53e63fd338358d0c50b0087d3f661bb0f6e7c3bf..db11c6127695ff9a762ce430e4458c7227d1c6ba 100644 (file)
@@ -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 <<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);
        }
 
index 31cf3a930d6c48e2ac13ba8c0eb37975252be2a7..8d831ee40d31bcacb4f5fbe895408e3b2e98e3da 100644 (file)
@@ -76,7 +76,15 @@ Session::prepare_diskstreams ()
 }
 
 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;
@@ -84,7 +92,7 @@ Session::no_roll (nframes_t nframes, nframes_t offset)
        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) {
@@ -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) {