From bfbae251be8b67b33ad1c95b56e30da0cb537ec5 Mon Sep 17 00:00:00 2001 From: Hans Baier Date: Sat, 10 Jan 2009 08:41:51 +0000 Subject: [PATCH] * Extracted method void AudioDiskstream::process_varispeed_playback(nframes_t nframes, boost::shared_ptr c) from AudioDiskstream::process git-svn-id: svn://localhost/ardour2/branches/3.0@4396 d708f5d6-7413-0410-9779-e7cbd77b26cf --- libs/ardour/ardour/audio_diskstream.h | 5 +- libs/ardour/audio_diskstream.cc | 118 ++++++++++++++------------ 2 files changed, 68 insertions(+), 55 deletions(-) diff --git a/libs/ardour/ardour/audio_diskstream.h b/libs/ardour/ardour/audio_diskstream.h index 939587fbd8..f918655f98 100644 --- a/libs/ardour/ardour/audio_diskstream.h +++ b/libs/ardour/ardour/audio_diskstream.h @@ -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 ChannelList; + void process_varispeed_playback(nframes_t nframes, boost::shared_ptr 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); void transport_stopped (struct tm&, time_t, bool abort); void transport_looped (nframes_t transport_frame); diff --git a/libs/ardour/audio_diskstream.cc b/libs/ardour/audio_diskstream.cc index cd2148325a..36903f7699 100644 --- a/libs/ardour/audio_diskstream.cc +++ b/libs/ardour/audio_diskstream.cc @@ -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 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) { -- 2.30.2