* Extracted method void AudioDiskstream::process_varispeed_playback(nframes_t nframes...
authorHans Baier <hansfbaier@googlemail.com>
Sat, 10 Jan 2009 08:41:51 +0000 (08:41 +0000)
committerHans Baier <hansfbaier@googlemail.com>
Sat, 10 Jan 2009 08:41:51 +0000 (08:41 +0000)
  from AudioDiskstream::process

git-svn-id: svn://localhost/ardour2/branches/3.0@4396 d708f5d6-7413-0410-9779-e7cbd77b26cf

libs/ardour/ardour/audio_diskstream.h
libs/ardour/audio_diskstream.cc

index 939587fbd839a894f2adfbf68136b2b126f53a80..f918655f9800d631423444b4384c3215473e9a2f 100644 (file)
@@ -175,7 +175,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, nframes_t offset, bool can_record, bool rec_monitors_input);        
        bool commit  (nframes_t nframes);
 
   private:
@@ -216,6 +216,8 @@ class AudioDiskstream : public Diskstream
 
        typedef std::vector<ChannelInfo*> ChannelList;
 
+       void process_varispeed_playback(nframes_t nframes, boost::shared_ptr<ChannelList> c);
+       
        /* The two central butler operations */
        int do_flush (Session::RunContext context, bool force = false);
        int do_refill () { return _do_refill(_mixdown_buffer, _gain_buffer); }
@@ -226,6 +228,7 @@ class AudioDiskstream : public Diskstream
                  nframes_t& start, nframes_t cnt, 
                  ChannelInfo* channel_info, int channel, bool reversed);
 
+       
        void finish_capture (bool rec_monitors_input, boost::shared_ptr<ChannelList>);
        void transport_stopped (struct tm&, time_t, bool abort);
        void transport_looped (nframes_t transport_frame);
index cd2148325a3afffa300b88b3d14297be80b353fa..36903f76993133291b446ff9157e979339d2efca 100644 (file)
@@ -779,60 +779,7 @@ AudioDiskstream::process (nframes_t transport_frame, nframes_t nframes, nframes_
                } 
 
                if (rec_nframes == 0 && _actual_speed != 1.0f && _actual_speed != -1.0f) {
-                       
-                       // the idea behind phase is that when the speed is not 1.0, we have to 
-                       // interpolate between samples and then we have to store where we thought we were. 
-                       // rather than being at sample N or N+1, we were at N+0.8792922
-                       // so the "phase" element, if you want to think about this way, 
-                       // varies from 0 to 1, representing the "offset" between samples
-                       uint64_t phase = last_phase;
-                       int64_t phi_delta;
-                       nframes_t i = 0;
-
-                       // Linearly interpolate into the alt buffer
-                       // using 40.24 fixp maths
-                       //
-                       // Fixedpoint is just an integer with an implied scaling factor. 
-                       // In 40.24 the scaling factor is 2^24 = 16777216,  
-                       // so a value of 10*2^24 (in integer space) is equivalent to 10.0. 
-                       //
-                       // The advantage is that addition and modulus [like x = (x + y) % 2^40]  
-                       // has no rounding errors and no drift, and just requires a single integer add.
-                       // (swh)
-                       
-                       const int64_t fractional_part_mask  = 0xFFFFFF;
-                       const Sample  binary_scaling_factor = 16777216.0f;
-
-                       // phi = fixed point speed
-                       if (phi != target_phi) {
-                               phi_delta = ((int64_t)(target_phi - phi)) / nframes;
-                       } else {
-                               phi_delta = 0;
-                       }
-
-                       for (chan = c->begin(); chan != c->end(); ++chan) {
-
-                               Sample fractional_part;
-                               ChannelInfo* chaninfo (*chan);
-
-                               i = 0;
-                               phase = last_phase;
-
-                               for (nframes_t outsample = 0; outsample < nframes; ++outsample) {
-                                       i = phase >> 24;
-                                       fractional_part = (phase & fractional_part_mask) / binary_scaling_factor;
-                                       chaninfo->speed_buffer[outsample] = 
-                                               chaninfo->current_playback_buffer[i] * (1.0f - fractional_part) +
-                                               chaninfo->current_playback_buffer[i+1] * fractional_part;
-                                       phase += phi + phi_delta;
-                               }
-                               
-                               chaninfo->current_playback_buffer = chaninfo->speed_buffer;
-                       }
-
-                       playback_distance = i; // + 1;
-                       last_phase = (phase & fractional_part_mask);
-
+                       process_varispeed_playback(nframes, c);
                } else {
                        playback_distance = nframes;
                }
@@ -859,6 +806,69 @@ AudioDiskstream::process (nframes_t transport_frame, nframes_t nframes, nframes_
        return ret;
 }
 
+void
+AudioDiskstream::process_varispeed_playback(nframes_t nframes, boost::shared_ptr<ChannelList> c)
+{
+       ChannelList::iterator chan;
+       
+       // the idea behind phase is that when the speed is not 1.0, we have to 
+       // interpolate between samples and then we have to store where we thought we were. 
+       // rather than being at sample N or N+1, we were at N+0.8792922
+       // so the "phase" element, if you want to think about this way, 
+       // varies from 0 to 1, representing the "offset" between samples
+       uint64_t    phase = last_phase;
+       
+       // acceleration
+       int64_t     phi_delta;
+       
+       // index in the input buffers
+       nframes_t   i = 0;
+
+       // Linearly interpolate into the speed buffer
+       // using 40.24 fixed point math
+       //
+       // Fixed point is just an integer with an implied scaling factor. 
+       // In 40.24 the scaling factor is 2^24 = 16777216,  
+       // so a value of 10*2^24 (in integer space) is equivalent to 10.0. 
+       //
+       // The advantage is that addition and modulus [like x = (x + y) % 2^40]  
+       // have no rounding errors and no drift, and just require a single integer add.
+       // (swh)
+       
+       const int64_t fractional_part_mask  = 0xFFFFFF;
+       const Sample  binary_scaling_factor = 16777216.0f;
+
+       // phi = fixed point speed
+       if (phi != target_phi) {
+               phi_delta = ((int64_t)(target_phi - phi)) / nframes;
+       } else {
+               phi_delta = 0;
+       }
+
+       for (chan = c->begin(); chan != c->end(); ++chan) {
+
+               Sample fractional_phase_part;
+               ChannelInfo* chaninfo (*chan);
+
+               i = 0;
+               phase = last_phase;
+
+               for (nframes_t outsample = 0; outsample < nframes; ++outsample) {
+                       i = phase >> 24;
+                       fractional_phase_part = (phase & fractional_part_mask) / binary_scaling_factor;
+                       chaninfo->speed_buffer[outsample] = 
+                               chaninfo->current_playback_buffer[i] * (1.0f - fractional_phase_part) +
+                               chaninfo->current_playback_buffer[i+1] * fractional_phase_part;
+                       phase += phi + phi_delta;
+               }
+               
+               chaninfo->current_playback_buffer = chaninfo->speed_buffer;
+       }
+
+       playback_distance = i; // + 1;
+       last_phase = (phase & fractional_part_mask);
+}
+
 bool
 AudioDiskstream::commit (nframes_t nframes)
 {