Remove global declick API
De-click will be per disk-reader, latency compensated and buffer-size independent. Cue-monitoring should not be affected by de-click.
This commit is contained in:
parent
8664768efa
commit
249640267c
|
@ -237,48 +237,6 @@ Amp::apply_gain (BufferSet& bufs, samplecnt_t sample_rate, samplecnt_t nframes,
|
|||
return rv;
|
||||
}
|
||||
|
||||
void
|
||||
Amp::declick (BufferSet& bufs, samplecnt_t nframes, int dir)
|
||||
{
|
||||
if (nframes == 0 || bufs.count().n_total() == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
const samplecnt_t declick = std::min ((samplecnt_t) 512, nframes);
|
||||
const double fractional_shift = 1.0 / declick ;
|
||||
gain_t delta, initial;
|
||||
|
||||
if (dir < 0) {
|
||||
/* fade out: remove more and more of delta from initial */
|
||||
delta = -1.0;
|
||||
initial = GAIN_COEFF_UNITY;
|
||||
} else {
|
||||
/* fade in: add more and more of delta from initial */
|
||||
delta = 1.0;
|
||||
initial = GAIN_COEFF_ZERO;
|
||||
}
|
||||
|
||||
/* Audio Gain */
|
||||
for (BufferSet::audio_iterator i = bufs.audio_begin(); i != bufs.audio_end(); ++i) {
|
||||
Sample* const buffer = i->data();
|
||||
|
||||
double fractional_pos = 0.0;
|
||||
|
||||
for (pframes_t nx = 0; nx < declick; ++nx) {
|
||||
buffer[nx] *= initial + (delta * fractional_pos);
|
||||
fractional_pos += fractional_shift;
|
||||
}
|
||||
|
||||
/* now ensure the rest of the buffer has the target value applied, if necessary. */
|
||||
if (declick != nframes) {
|
||||
if (dir < 0) {
|
||||
memset (&buffer[declick], 0, sizeof (Sample) * (nframes - declick));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
gain_t
|
||||
Amp::apply_gain (AudioBuffer& buf, samplecnt_t sample_rate, samplecnt_t nframes, gain_t initial, gain_t target, sampleoffset_t offset)
|
||||
{
|
||||
|
|
|
@ -32,9 +32,7 @@ class BufferSet;
|
|||
class GainControl;
|
||||
class IO;
|
||||
|
||||
/** Applies a declick operation to all audio inputs, passing the same number of
|
||||
* audio outputs, and passing through any other types unchanged.
|
||||
*/
|
||||
/** Gain Stage (Fader, Trim). */
|
||||
class LIBARDOUR_API Amp : public Processor {
|
||||
public:
|
||||
Amp(Session& s, const std::string& display_name, boost::shared_ptr<GainControl> control, bool control_midi_also);
|
||||
|
@ -62,9 +60,6 @@ public:
|
|||
static gain_t apply_gain (AudioBuffer& buf, samplecnt_t sample_rate, samplecnt_t nframes, gain_t initial, gain_t target, sampleoffset_t offset = 0);
|
||||
static void apply_simple_gain (AudioBuffer& buf, samplecnt_t nframes, gain_t target, sampleoffset_t offset = 0);
|
||||
|
||||
static void declick (BufferSet& bufs, samplecnt_t nframes, int dir);
|
||||
static void update_meters();
|
||||
|
||||
boost::shared_ptr<GainControl> gain_control() {
|
||||
return _gain_control;
|
||||
}
|
||||
|
|
|
@ -70,11 +70,11 @@ class LIBARDOUR_API Auditioner : public Track
|
|||
PBD::Signal2<void, ARDOUR::samplecnt_t, ARDOUR::samplecnt_t> AuditionProgress;
|
||||
|
||||
/* Track */
|
||||
int roll (pframes_t nframes, samplepos_t start_sample, samplepos_t end_sample, int declick, bool& need_butler);
|
||||
int roll (pframes_t nframes, samplepos_t start_sample, samplepos_t end_sample, bool& need_butler);
|
||||
DataType data_type () const;
|
||||
|
||||
int roll_audio (pframes_t nframes, samplepos_t start_sample, samplepos_t end_sample, int declick, bool& need_butler);
|
||||
int roll_midi (pframes_t nframes, samplepos_t start_sample, samplepos_t end_sample, int declick, bool& need_butler);
|
||||
int roll_audio (pframes_t nframes, samplepos_t start_sample, samplepos_t end_sample, bool& need_butler);
|
||||
int roll_midi (pframes_t nframes, samplepos_t start_sample, samplepos_t end_sample, bool& need_butler);
|
||||
|
||||
/* fake track */
|
||||
void set_state_part_two () {}
|
||||
|
|
|
@ -65,11 +65,9 @@ public:
|
|||
|
||||
void helper_thread();
|
||||
|
||||
int process_routes (pframes_t nframes, samplepos_t start_sample, samplepos_t end_sample, int declick,
|
||||
bool& need_butler);
|
||||
int process_routes (pframes_t nframes, samplepos_t start_sample, samplepos_t end_sample, bool& need_butler);
|
||||
|
||||
int routes_no_roll (pframes_t nframes, samplepos_t start_sample, samplepos_t end_sample,
|
||||
bool non_rt_pending, int declick);
|
||||
int routes_no_roll (pframes_t nframes, samplepos_t start_sample, samplepos_t end_sample, bool non_rt_pending );
|
||||
|
||||
void process_one_route (Route * route);
|
||||
|
||||
|
@ -125,7 +123,6 @@ private:
|
|||
samplepos_t _process_end_sample;
|
||||
bool _process_can_record;
|
||||
bool _process_non_rt_pending;
|
||||
int _process_declick;
|
||||
|
||||
bool _process_noroll;
|
||||
int _process_retval;
|
||||
|
|
|
@ -142,7 +142,7 @@ public:
|
|||
|
||||
virtual void filter_input (BufferSet &) {}
|
||||
|
||||
int roll (pframes_t nframes, samplepos_t start_sample, samplepos_t end_sample, int declick, bool& need_butler);
|
||||
int roll (pframes_t nframes, samplepos_t start_sample, samplepos_t end_sample, bool& need_butler);
|
||||
|
||||
int no_roll (pframes_t nframes, samplepos_t start_sample, samplepos_t end_sample, bool state_changing);
|
||||
|
||||
|
@ -154,7 +154,6 @@ public:
|
|||
virtual void realtime_handle_transport_stopped () {}
|
||||
virtual void realtime_locate () {}
|
||||
virtual void non_realtime_locate (samplepos_t);
|
||||
virtual void set_pending_declick (int);
|
||||
void set_loop (ARDOUR::Location *);
|
||||
|
||||
/* end of vfunc-based API */
|
||||
|
@ -586,8 +585,7 @@ public:
|
|||
/* can only be executed by a route for which is_monitor() is true
|
||||
* (i.e. the monitor out)
|
||||
*/
|
||||
void monitor_run (samplepos_t start_sample, samplepos_t end_sample,
|
||||
pframes_t nframes, int declick);
|
||||
void monitor_run (samplepos_t start_sample, samplepos_t end_sample, pframes_t nframes);
|
||||
|
||||
bool slaved_to (boost::shared_ptr<VCA>) const;
|
||||
bool slaved () const;
|
||||
|
@ -611,7 +609,7 @@ protected:
|
|||
|
||||
void process_output_buffers (BufferSet& bufs,
|
||||
samplepos_t start_sample, samplepos_t end_sample,
|
||||
pframes_t nframes, int declick,
|
||||
pframes_t nframes,
|
||||
bool gain_automation_ok,
|
||||
bool run_disk_processors);
|
||||
|
||||
|
@ -657,7 +655,6 @@ protected:
|
|||
gint _pending_process_reorder; // atomic
|
||||
gint _pending_signals; // atomic
|
||||
|
||||
int _pending_declick;
|
||||
MeterPoint _meter_point;
|
||||
MeterPoint _pending_meter_point;
|
||||
MeterType _meter_type;
|
||||
|
@ -665,7 +662,6 @@ protected:
|
|||
bool _denormal_protection;
|
||||
|
||||
bool _recordable : 1;
|
||||
bool _declickable : 1;
|
||||
|
||||
boost::shared_ptr<SoloControl> _solo_control;
|
||||
boost::shared_ptr<MuteControl> _mute_control;
|
||||
|
@ -695,8 +691,6 @@ protected:
|
|||
uint32_t pans_required() const;
|
||||
ChanCount n_process_buffers ();
|
||||
|
||||
virtual void maybe_declick (BufferSet&, samplecnt_t, int);
|
||||
|
||||
boost::shared_ptr<GainControl> _gain_control;
|
||||
boost::shared_ptr<GainControl> _trim_control;
|
||||
boost::shared_ptr<PhaseControl> _phase_control;
|
||||
|
@ -752,7 +746,7 @@ private:
|
|||
|
||||
pframes_t latency_preroll (pframes_t nframes, samplepos_t& start_sample, samplepos_t& end_sample);
|
||||
|
||||
void run_route (samplepos_t start_sample, samplepos_t end_sample, pframes_t nframes, int declick, bool gain_automation_ok, bool run_disk_reader);
|
||||
void run_route (samplepos_t start_sample, samplepos_t end_sample, pframes_t nframes, bool gain_automation_ok, bool run_disk_reader);
|
||||
void fill_buffers_with_input (BufferSet& bufs, boost::shared_ptr<IO> io, pframes_t nframes);
|
||||
|
||||
void reset_instrument_info ();
|
||||
|
|
|
@ -175,12 +175,8 @@ class LIBARDOUR_API Session : public PBD::StatefulDestructible, public PBD::Scop
|
|||
{
|
||||
private:
|
||||
enum SubState {
|
||||
PendingDeclickIn = 0x1, ///< pending de-click fade-in for start
|
||||
PendingDeclickOut = 0x2, ///< pending de-click fade-out for stop
|
||||
StopPendingCapture = 0x4,
|
||||
PendingLoopDeclickIn = 0x8, ///< pending de-click fade-in at the start of a loop
|
||||
PendingLoopDeclickOut = 0x10, ///< pending de-click fade-out at the end of a loop
|
||||
PendingLocate = 0x20,
|
||||
};
|
||||
|
||||
public:
|
||||
|
@ -440,7 +436,6 @@ public:
|
|||
|
||||
bool global_locate_pending() const { return _global_locate_pending; }
|
||||
bool locate_pending() const { return static_cast<bool>(post_transport_work()&PostTransportLocate); }
|
||||
bool declick_out_pending() const { return static_cast<bool>(transport_sub_state&(PendingDeclickOut)); }
|
||||
bool transport_locked () const;
|
||||
|
||||
int wipe ();
|
||||
|
@ -1376,31 +1371,9 @@ private:
|
|||
-1 if there is a pending declick fade-out,
|
||||
0 if there is no pending declick.
|
||||
*/
|
||||
int get_transport_declick_required () {
|
||||
if (transport_sub_state & PendingDeclickIn) {
|
||||
transport_sub_state &= ~PendingDeclickIn;
|
||||
return 1;
|
||||
} else if (transport_sub_state & PendingDeclickOut) {
|
||||
/* XXX: not entirely sure why we don't clear this */
|
||||
return -1;
|
||||
} else if (transport_sub_state & PendingLoopDeclickOut) {
|
||||
/* Return the declick out first ... */
|
||||
transport_sub_state &= ~PendingLoopDeclickOut;
|
||||
return -1;
|
||||
} else if (transport_sub_state & PendingLoopDeclickIn) {
|
||||
/* ... then the declick in on the next call */
|
||||
transport_sub_state &= ~PendingLoopDeclickIn;
|
||||
return 1;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
bool maybe_stop (samplepos_t limit);
|
||||
bool maybe_sync_start (pframes_t &);
|
||||
|
||||
void check_declick_out ();
|
||||
|
||||
std::string _path;
|
||||
std::string _name;
|
||||
bool _is_new;
|
||||
|
@ -1443,9 +1416,6 @@ private:
|
|||
samplepos_t _last_roll_or_reversal_location;
|
||||
samplepos_t _last_record_location;
|
||||
|
||||
bool pending_locate_roll;
|
||||
samplepos_t pending_locate_sample;
|
||||
bool pending_locate_flush;
|
||||
bool pending_abort;
|
||||
bool pending_auto_loop;
|
||||
|
||||
|
|
|
@ -209,8 +209,6 @@ protected:
|
|||
XMLNode* pending_state;
|
||||
bool _destructive;
|
||||
|
||||
void maybe_declick (BufferSet&, samplecnt_t, int);
|
||||
|
||||
boost::shared_ptr<AutomationControl> _record_enable_control;
|
||||
boost::shared_ptr<AutomationControl> _record_safe_control;
|
||||
|
||||
|
|
|
@ -220,7 +220,7 @@ Auditioner::data_type () const {
|
|||
}
|
||||
|
||||
int
|
||||
Auditioner::roll (pframes_t nframes, samplepos_t start_sample, samplepos_t end_sample, int declick, bool& need_butler)
|
||||
Auditioner::roll (pframes_t nframes, samplepos_t start_sample, samplepos_t end_sample, bool& need_butler)
|
||||
{
|
||||
Glib::Threads::RWLock::ReaderLock lm (_processor_lock, Glib::Threads::TRY_LOCK);
|
||||
if (!lm.locked()) {
|
||||
|
@ -244,7 +244,7 @@ Auditioner::roll (pframes_t nframes, samplepos_t start_sample, samplepos_t end_s
|
|||
}
|
||||
}
|
||||
|
||||
process_output_buffers (bufs, start_sample, end_sample, nframes, declick, !_session.transport_stopped(), true);
|
||||
process_output_buffers (bufs, start_sample, end_sample, nframes, !_session.transport_stopped(), true);
|
||||
|
||||
/* note: auditioner never writes to disk, so we don't care about the
|
||||
* disk writer status (it's buffers will always have no data in them).
|
||||
|
@ -425,7 +425,7 @@ Auditioner::play_audition (samplecnt_t nframes)
|
|||
/* process audio */
|
||||
this_nframes = min (nframes, length - current_sample + _import_position);
|
||||
|
||||
if (this_nframes > 0 && 0 != (ret = roll (this_nframes, current_sample, current_sample + this_nframes, false, need_butler))) {
|
||||
if (this_nframes > 0 && 0 != (ret = roll (this_nframes, current_sample, current_sample + this_nframes, need_butler))) {
|
||||
silence (nframes);
|
||||
return ret;
|
||||
}
|
||||
|
|
|
@ -412,7 +412,7 @@ DiskReader::run (BufferSet& bufs, samplepos_t start_sample, samplepos_t end_samp
|
|||
/* MIDI data handling */
|
||||
|
||||
midi:
|
||||
if (!_session.declick_out_pending() && bufs.count().n_midi()) {
|
||||
if (/*!_session.declick_out_pending() && */ bufs.count().n_midi()) {
|
||||
MidiBuffer* dst;
|
||||
|
||||
if (_no_disk_output) {
|
||||
|
|
|
@ -513,7 +513,7 @@ Graph::dump (int chain)
|
|||
}
|
||||
|
||||
int
|
||||
Graph::process_routes (pframes_t nframes, samplepos_t start_sample, samplepos_t end_sample, int declick, bool& need_butler)
|
||||
Graph::process_routes (pframes_t nframes, samplepos_t start_sample, samplepos_t end_sample, bool& need_butler)
|
||||
{
|
||||
DEBUG_TRACE (DEBUG::ProcessThreads, string_compose ("graph execution from %1 to %2 = %3\n", start_sample, end_sample, nframes));
|
||||
|
||||
|
@ -522,7 +522,6 @@ Graph::process_routes (pframes_t nframes, samplepos_t start_sample, samplepos_t
|
|||
_process_nframes = nframes;
|
||||
_process_start_sample = start_sample;
|
||||
_process_end_sample = end_sample;
|
||||
_process_declick = declick;
|
||||
|
||||
_process_noroll = false;
|
||||
_process_retval = 0;
|
||||
|
@ -539,8 +538,7 @@ Graph::process_routes (pframes_t nframes, samplepos_t start_sample, samplepos_t
|
|||
}
|
||||
|
||||
int
|
||||
Graph::routes_no_roll (pframes_t nframes, samplepos_t start_sample, samplepos_t end_sample,
|
||||
bool non_rt_pending, int declick)
|
||||
Graph::routes_no_roll (pframes_t nframes, samplepos_t start_sample, samplepos_t end_sample, bool non_rt_pending)
|
||||
{
|
||||
DEBUG_TRACE (DEBUG::ProcessThreads, string_compose ("no-roll graph execution from %1 to %2 = %3\n", start_sample, end_sample, nframes));
|
||||
|
||||
|
@ -549,7 +547,6 @@ Graph::routes_no_roll (pframes_t nframes, samplepos_t start_sample, samplepos_t
|
|||
_process_nframes = nframes;
|
||||
_process_start_sample = start_sample;
|
||||
_process_end_sample = end_sample;
|
||||
_process_declick = declick;
|
||||
_process_non_rt_pending = non_rt_pending;
|
||||
|
||||
_process_noroll = true;
|
||||
|
@ -574,11 +571,9 @@ Graph::process_one_route (Route* route)
|
|||
DEBUG_TRACE (DEBUG::ProcessThreads, string_compose ("%1 runs route %2\n", pthread_name(), route->name()));
|
||||
|
||||
if (_process_noroll) {
|
||||
route->set_pending_declick (_process_declick);
|
||||
retval = route->no_roll (_process_nframes, _process_start_sample, _process_end_sample, _process_non_rt_pending);
|
||||
} else {
|
||||
route->set_pending_declick (_process_declick);
|
||||
retval = route->roll (_process_nframes, _process_start_sample, _process_end_sample, _process_declick, need_butler);
|
||||
retval = route->roll (_process_nframes, _process_start_sample, _process_end_sample, need_butler);
|
||||
}
|
||||
|
||||
if (retval) {
|
||||
|
|
|
@ -100,13 +100,11 @@ Route::Route (Session& sess, string name, PresentationInfo::Flag flag, DataType
|
|||
, _disk_io_point (DiskIOPreFader)
|
||||
, _pending_process_reorder (0)
|
||||
, _pending_signals (0)
|
||||
, _pending_declick (true)
|
||||
, _meter_point (MeterPostFader)
|
||||
, _pending_meter_point (MeterPostFader)
|
||||
, _meter_type (MeterPeak)
|
||||
, _denormal_protection (false)
|
||||
, _recordable (true)
|
||||
, _declickable (false)
|
||||
, _have_internal_generator (false)
|
||||
, _default_type (default_type)
|
||||
, _loop_location (NULL)
|
||||
|
@ -292,14 +290,6 @@ Route::set_trim (gain_t val, Controllable::GroupControlDisposition /* group over
|
|||
// _trim_control->route_set_value (val);
|
||||
}
|
||||
|
||||
void
|
||||
Route::maybe_declick (BufferSet&, samplecnt_t, int)
|
||||
{
|
||||
/* this is the "bus" implementation and they never declick.
|
||||
*/
|
||||
return;
|
||||
}
|
||||
|
||||
/** Process this route for one (sub) cycle (process thread)
|
||||
*
|
||||
* @param bufs Scratch buffers to use for the signal path
|
||||
|
@ -313,7 +303,7 @@ Route::maybe_declick (BufferSet&, samplecnt_t, int)
|
|||
void
|
||||
Route::process_output_buffers (BufferSet& bufs,
|
||||
samplepos_t start_sample, samplepos_t end_sample, pframes_t nframes,
|
||||
int declick, bool gain_automation_ok, bool run_disk_reader)
|
||||
bool gain_automation_ok, bool run_disk_reader)
|
||||
{
|
||||
/* Caller must hold process lock */
|
||||
assert (!AudioEngine::instance()->process_lock().trylock());
|
||||
|
@ -422,15 +412,6 @@ Route::process_output_buffers (BufferSet& bufs,
|
|||
|
||||
_main_outs->no_outs_cuz_we_no_monitor (silence);
|
||||
|
||||
/* -------------------------------------------------------------------------------------------
|
||||
GLOBAL DECLICK (for transport changes etc.)
|
||||
----------------------------------------------------------------------------------------- */
|
||||
|
||||
// XXX not latency compensated. calls Amp::declick, but there may be
|
||||
// plugins between disk and Fader.
|
||||
maybe_declick (bufs, nframes, declick);
|
||||
_pending_declick = 0;
|
||||
|
||||
/* -------------------------------------------------------------------------------------------
|
||||
DENORMAL CONTROL
|
||||
----------------------------------------------------------------------------------------- */
|
||||
|
@ -658,15 +639,15 @@ Route::n_process_buffers ()
|
|||
}
|
||||
|
||||
void
|
||||
Route::monitor_run (samplepos_t start_sample, samplepos_t end_sample, pframes_t nframes, int declick)
|
||||
Route::monitor_run (samplepos_t start_sample, samplepos_t end_sample, pframes_t nframes)
|
||||
{
|
||||
assert (is_monitor());
|
||||
Glib::Threads::RWLock::ReaderLock lm (_processor_lock, Glib::Threads::TRY_LOCK);
|
||||
run_route (start_sample, end_sample, nframes, declick, true, false);
|
||||
run_route (start_sample, end_sample, nframes, true, false);
|
||||
}
|
||||
|
||||
void
|
||||
Route::run_route (samplepos_t start_sample, samplepos_t end_sample, pframes_t nframes, int declick, bool gain_automation_ok, bool run_disk_reader)
|
||||
Route::run_route (samplepos_t start_sample, samplepos_t end_sample, pframes_t nframes, bool gain_automation_ok, bool run_disk_reader)
|
||||
{
|
||||
BufferSet& bufs (_session.get_route_buffers (n_process_buffers()));
|
||||
|
||||
|
@ -692,7 +673,7 @@ Route::run_route (samplepos_t start_sample, samplepos_t end_sample, pframes_t nf
|
|||
|
||||
/* run processor chain */
|
||||
|
||||
process_output_buffers (bufs, start_sample, end_sample, nframes, declick, gain_automation_ok, run_disk_reader);
|
||||
process_output_buffers (bufs, start_sample, end_sample, nframes, gain_automation_ok, run_disk_reader);
|
||||
|
||||
/* map events (e.g. MIDI-CC) back to control-parameters */
|
||||
update_controls (bufs);
|
||||
|
@ -3670,7 +3651,7 @@ Route::latency_preroll (pframes_t nframes, samplepos_t& start_sample, samplepos_
|
|||
}
|
||||
|
||||
int
|
||||
Route::roll (pframes_t nframes, samplepos_t start_sample, samplepos_t end_sample, int declick, bool& need_butler)
|
||||
Route::roll (pframes_t nframes, samplepos_t start_sample, samplepos_t end_sample, bool& need_butler)
|
||||
{
|
||||
Glib::Threads::RWLock::ReaderLock lm (_processor_lock, Glib::Threads::TRY_LOCK);
|
||||
|
||||
|
@ -3688,7 +3669,7 @@ Route::roll (pframes_t nframes, samplepos_t start_sample, samplepos_t end_sample
|
|||
return 0;
|
||||
}
|
||||
|
||||
run_route (start_sample, end_sample, nframes, declick, (!_disk_writer || !_disk_writer->record_enabled()) && _session.transport_rolling(), true);
|
||||
run_route (start_sample, end_sample, nframes, (!_disk_writer || !_disk_writer->record_enabled()) && _session.transport_rolling(), true);
|
||||
|
||||
if ((_disk_reader && _disk_reader->need_butler()) || (_disk_writer && _disk_writer->need_butler())) {
|
||||
need_butler = true;
|
||||
|
@ -3735,7 +3716,7 @@ Route::no_roll_unlocked (pframes_t nframes, samplepos_t start_sample, samplepos_
|
|||
*/
|
||||
}
|
||||
|
||||
run_route (start_sample, end_sample, nframes, 0, false, false);
|
||||
run_route (start_sample, end_sample, nframes, false, false);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -4099,22 +4080,6 @@ Route::protect_automation ()
|
|||
(*i)->protect_automation();
|
||||
}
|
||||
|
||||
/** @param declick 1 to set a pending declick fade-in,
|
||||
* -1 to set a pending declick fade-out
|
||||
*/
|
||||
void
|
||||
Route::set_pending_declick (int declick)
|
||||
{
|
||||
if (_declickable) {
|
||||
/* this call is not allowed to turn off a pending declick */
|
||||
if (declick) {
|
||||
_pending_declick = declick;
|
||||
}
|
||||
} else {
|
||||
_pending_declick = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/** Shift automation forwards from a particular place, thereby inserting time.
|
||||
* Adds undo commands for any shifts that are performed.
|
||||
*
|
||||
|
|
|
@ -243,10 +243,6 @@ Session::Session (AudioEngine &eng,
|
|||
, _last_roll_location (0)
|
||||
, _last_roll_or_reversal_location (0)
|
||||
, _last_record_location (0)
|
||||
, pending_locate_roll (false)
|
||||
, pending_locate_sample (0)
|
||||
, pending_locate_flush (false)
|
||||
, pending_abort (false)
|
||||
, pending_auto_loop (false)
|
||||
, _mempool ("Session", 3145728)
|
||||
, lua (lua_newstate (&PBD::ReallocPool::lalloc, &_mempool))
|
||||
|
|
|
@ -136,7 +136,6 @@ Session::no_roll (pframes_t nframes)
|
|||
|
||||
samplepos_t end_sample = _transport_sample + nframes; // FIXME: varispeed + no_roll ??
|
||||
int ret = 0;
|
||||
int declick = (config.get_use_transport_fades() ? get_transport_declick_required() : false);
|
||||
boost::shared_ptr<RouteList> r = routes.reader ();
|
||||
|
||||
if (_click_io) {
|
||||
|
@ -152,7 +151,7 @@ Session::no_roll (pframes_t nframes)
|
|||
|
||||
if (_process_graph) {
|
||||
DEBUG_TRACE(DEBUG::ProcessThreads,"calling graph/no-roll\n");
|
||||
_process_graph->routes_no_roll( nframes, _transport_sample, end_sample, non_realtime_work_pending(), declick);
|
||||
_process_graph->routes_no_roll( nframes, _transport_sample, end_sample, non_realtime_work_pending());
|
||||
} else {
|
||||
PT_TIMING_CHECK (10);
|
||||
for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
|
||||
|
@ -161,8 +160,6 @@ Session::no_roll (pframes_t nframes)
|
|||
continue;
|
||||
}
|
||||
|
||||
(*i)->set_pending_declick (declick);
|
||||
|
||||
if ((*i)->no_roll (nframes, _transport_sample, end_sample, non_realtime_work_pending())) {
|
||||
error << string_compose(_("Session: error in no roll for %1"), (*i)->name()) << endmsg;
|
||||
ret = -1;
|
||||
|
@ -182,7 +179,6 @@ Session::no_roll (pframes_t nframes)
|
|||
int
|
||||
Session::process_routes (pframes_t nframes, bool& need_butler)
|
||||
{
|
||||
int declick = (config.get_use_transport_fades() ? get_transport_declick_required() : false);
|
||||
boost::shared_ptr<RouteList> r = routes.reader ();
|
||||
|
||||
const samplepos_t start_sample = _transport_sample;
|
||||
|
@ -197,7 +193,7 @@ Session::process_routes (pframes_t nframes, bool& need_butler)
|
|||
|
||||
if (_process_graph) {
|
||||
DEBUG_TRACE(DEBUG::ProcessThreads,"calling graph/process-routes\n");
|
||||
if (_process_graph->process_routes (nframes, start_sample, end_sample, declick, need_butler) < 0) {
|
||||
if (_process_graph->process_routes (nframes, start_sample, end_sample, need_butler) < 0) {
|
||||
stop_transport ();
|
||||
return -1;
|
||||
}
|
||||
|
@ -211,11 +207,9 @@ Session::process_routes (pframes_t nframes, bool& need_butler)
|
|||
continue;
|
||||
}
|
||||
|
||||
(*i)->set_pending_declick (declick);
|
||||
|
||||
bool b = false;
|
||||
|
||||
if ((ret = (*i)->roll (nframes, start_sample, end_sample, declick, b)) < 0) {
|
||||
if ((ret = (*i)->roll (nframes, start_sample, end_sample, b)) < 0) {
|
||||
stop_transport ();
|
||||
return -1;
|
||||
}
|
||||
|
@ -369,8 +363,6 @@ Session::process_with_events (pframes_t nframes)
|
|||
set_next_event ();
|
||||
}
|
||||
|
||||
check_declick_out ();
|
||||
|
||||
if (nframes == 0) {
|
||||
return;
|
||||
} else {
|
||||
|
@ -514,7 +506,6 @@ Session::process_with_events (pframes_t nframes)
|
|||
}
|
||||
|
||||
maybe_stop (stop_limit);
|
||||
check_declick_out ();
|
||||
}
|
||||
|
||||
if (nframes > 0) {
|
||||
|
@ -920,7 +911,6 @@ Session::process_without_events (pframes_t nframes)
|
|||
}
|
||||
|
||||
maybe_stop (stop_limit);
|
||||
check_declick_out ();
|
||||
|
||||
if (session_needs_butler) {
|
||||
DEBUG_TRACE (DEBUG::Butler, "p-without-events: session needs butler, call it\n");
|
||||
|
@ -953,7 +943,7 @@ Session::process_audition (pframes_t nframes)
|
|||
/* if using a monitor section, run it because otherwise we don't hear anything */
|
||||
|
||||
if (_monitor_out && auditioner->needs_monitor()) {
|
||||
_monitor_out->monitor_run (_transport_sample, _transport_sample + nframes, nframes, false);
|
||||
_monitor_out->monitor_run (_transport_sample, _transport_sample + nframes, nframes);
|
||||
}
|
||||
|
||||
/* handle pending events */
|
||||
|
|
|
@ -808,12 +808,6 @@ Session::non_realtime_stop (bool abort, int on_entry, bool& finished)
|
|||
|
||||
boost::shared_ptr<RouteList> r = routes.reader ();
|
||||
|
||||
for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
|
||||
if (!(*i)->is_auditioner()) {
|
||||
(*i)->set_pending_declick (0);
|
||||
}
|
||||
}
|
||||
|
||||
if (did_record) {
|
||||
commit_reversible_command ();
|
||||
/* increase take name */
|
||||
|
@ -827,11 +821,11 @@ Session::non_realtime_stop (bool abort, int on_entry, bool& finished)
|
|||
PostTransportWork ptw = post_transport_work ();
|
||||
|
||||
for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
|
||||
(*i)->non_realtime_transport_stop (_transport_sample, !(ptw & PostTransportLocate) || pending_locate_flush);
|
||||
(*i)->non_realtime_transport_stop (_transport_sample, !(ptw & PostTransportLocate));
|
||||
}
|
||||
VCAList v = _vca_manager->vcas ();
|
||||
for (VCAList::const_iterator i = v.begin(); i != v.end(); ++i) {
|
||||
(*i)->non_realtime_transport_stop (_transport_sample, !(ptw & PostTransportLocate) || pending_locate_flush);
|
||||
(*i)->non_realtime_transport_stop (_transport_sample, !(ptw & PostTransportLocate));
|
||||
}
|
||||
|
||||
update_latency_compensation ();
|
||||
|
@ -844,10 +838,6 @@ Session::non_realtime_stop (bool abort, int on_entry, bool& finished)
|
|||
(_requested_return_sample >= 0) ||
|
||||
synced_to_engine()) {
|
||||
|
||||
if (pending_locate_flush) {
|
||||
flush_all_inserts ();
|
||||
}
|
||||
|
||||
// rg: what is the logic behind this case?
|
||||
// _requested_return_sample should be ignored when synced_to_engine/slaved.
|
||||
// currently worked around in MTC_Slave by forcing _requested_return_sample to -1
|
||||
|
@ -988,44 +978,9 @@ Session::non_realtime_stop (bool abort, int on_entry, bool& finished)
|
|||
|
||||
/* and start it up again if relevant */
|
||||
|
||||
if ((ptw & PostTransportLocate) && !config.get_external_sync() && pending_locate_roll) {
|
||||
if ((ptw & PostTransportLocate) && !config.get_external_sync()) {
|
||||
request_transport_speed (1.0);
|
||||
}
|
||||
|
||||
/* Even if we didn't do a pending locate roll this time, we don't want it hanging
|
||||
around for next time.
|
||||
*/
|
||||
pending_locate_roll = false;
|
||||
}
|
||||
|
||||
void
|
||||
Session::check_declick_out ()
|
||||
{
|
||||
bool locate_required = transport_sub_state & PendingLocate;
|
||||
|
||||
/* this is called after a process() iteration. if PendingDeclickOut was set,
|
||||
it means that we were waiting to declick the output (which has just been
|
||||
done) before maybe doing something else. this is where we do that "something else".
|
||||
|
||||
note: called from the audio thread.
|
||||
*/
|
||||
|
||||
if (transport_sub_state & PendingDeclickOut) {
|
||||
|
||||
if (locate_required) {
|
||||
start_locate (pending_locate_sample, pending_locate_roll, pending_locate_flush);
|
||||
transport_sub_state &= ~(PendingDeclickOut|PendingLocate);
|
||||
} else {
|
||||
if (!(transport_sub_state & StopPendingCapture)) {
|
||||
stop_transport (pending_abort);
|
||||
transport_sub_state &= ~(PendingDeclickOut|PendingLocate);
|
||||
}
|
||||
}
|
||||
|
||||
} else if (transport_sub_state & PendingLoopDeclickOut) {
|
||||
/* Nothing else to do here; we've declicked, and the loop event will be along shortly */
|
||||
transport_sub_state &= ~PendingLoopDeclickOut;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -1259,22 +1214,6 @@ Session::locate (samplepos_t target_sample, bool with_roll, bool with_flush, boo
|
|||
return;
|
||||
}
|
||||
|
||||
if (_transport_speed && !(for_loop_enabled && Config->get_seamless_loop())) {
|
||||
/* Schedule a declick. We'll be called again when its done.
|
||||
We only do it this way for ordinary locates, not those
|
||||
due to **seamless** loops.
|
||||
*/
|
||||
|
||||
if (!(transport_sub_state & PendingDeclickOut)) {
|
||||
transport_sub_state |= (PendingDeclickOut|PendingLocate);
|
||||
pending_locate_sample = target_sample;
|
||||
pending_locate_roll = with_roll;
|
||||
pending_locate_flush = with_flush;
|
||||
cerr << "Declick scheduled ... back soon\n";
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
cerr << "... now doing the actual locate\n";
|
||||
|
||||
// Update Timecode time
|
||||
|
@ -1622,74 +1561,10 @@ Session::stop_transport (bool abort, bool clear_state)
|
|||
return;
|
||||
}
|
||||
|
||||
DEBUG_TRACE (DEBUG::Transport, string_compose ("stop_transport, declick required? %1\n", get_transport_declick_required()));
|
||||
DEBUG_TRACE (DEBUG::Transport, "time to actually stop\n");
|
||||
|
||||
if (!get_transport_declick_required()) {
|
||||
|
||||
/* stop has not yet been scheduled */
|
||||
|
||||
boost::shared_ptr<RouteList> rl = routes.reader();
|
||||
samplepos_t stop_target = audible_sample();
|
||||
|
||||
SubState new_bits;
|
||||
|
||||
if (actively_recording() && /* we are recording */
|
||||
worst_input_latency() > current_block_size) { /* input latency exceeds block size, so simple 1 cycle delay before stop is not enough */
|
||||
|
||||
/* we need to capture the audio that is still somewhere in the pipeline between
|
||||
wherever it was generated and the process callback. This means that even though
|
||||
the user (or something else) has asked us to stop, we have to roll
|
||||
past this point and then reset the playhead/transport location to
|
||||
the position at which the stop was requested.
|
||||
|
||||
we still need playback to "stop" now, however, which is why we schedule
|
||||
a declick below.
|
||||
*/
|
||||
|
||||
DEBUG_TRACE (DEBUG::Transport, string_compose ("stop transport requested @ %1, scheduled for + %2 = %3, abort = %4\n",
|
||||
_transport_sample, _worst_input_latency,
|
||||
_transport_sample + _worst_input_latency,
|
||||
abort));
|
||||
|
||||
SessionEvent *ev = new SessionEvent (SessionEvent::StopOnce, SessionEvent::Replace,
|
||||
_transport_sample + _worst_input_latency,
|
||||
0, 0, abort);
|
||||
|
||||
merge_event (ev);
|
||||
|
||||
/* request a declick at the start of the next process cycle() so that playback ceases.
|
||||
It will remain silent until we actually stop (at the StopOnce event somewhere in
|
||||
the future). The extra flag (StopPendingCapture) is set to ensure that check_declick_out()
|
||||
does not stop the transport too early.
|
||||
*/
|
||||
new_bits = SubState (PendingDeclickOut|StopPendingCapture);
|
||||
|
||||
} else {
|
||||
|
||||
/* Not recording, schedule a declick in the next process() cycle and then stop at its end */
|
||||
|
||||
new_bits = PendingDeclickOut;
|
||||
DEBUG_TRACE (DEBUG::Transport, string_compose ("stop scheduled for next process cycle @ %1\n", _transport_sample));
|
||||
}
|
||||
|
||||
/* we'll be called again after the declick */
|
||||
transport_sub_state = SubState (transport_sub_state|new_bits);
|
||||
pending_abort = abort;
|
||||
|
||||
return;
|
||||
|
||||
} else {
|
||||
|
||||
DEBUG_TRACE (DEBUG::Transport, "time to actually stop\n");
|
||||
|
||||
/* declick was scheduled, but we've been called again, which means it is really time to stop
|
||||
|
||||
XXX: we should probably split this off into its own method and call it explicitly.
|
||||
*/
|
||||
|
||||
realtime_stop (abort, clear_state);
|
||||
_butler->schedule_transport_work ();
|
||||
}
|
||||
realtime_stop (abort, clear_state);
|
||||
_butler->schedule_transport_work ();
|
||||
}
|
||||
|
||||
/** Called from the process thread */
|
||||
|
@ -1732,8 +1607,6 @@ Session::start_transport ()
|
|||
break;
|
||||
}
|
||||
|
||||
transport_sub_state |= PendingDeclickIn;
|
||||
|
||||
_transport_speed = _default_transport_speed;
|
||||
_target_transport_speed = _transport_speed;
|
||||
|
||||
|
|
|
@ -61,8 +61,6 @@ Track::Track (Session& sess, string name, PresentationInfo::Flag flag, TrackMode
|
|||
, _alignment_choice (Automatic)
|
||||
{
|
||||
_freeze_record.state = NoFreeze;
|
||||
_declickable = true;
|
||||
|
||||
}
|
||||
|
||||
Track::~Track ()
|
||||
|
@ -801,29 +799,6 @@ Track::adjust_capture_buffering ()
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
Track::maybe_declick (BufferSet& bufs, samplecnt_t nframes, int declick)
|
||||
{
|
||||
/* never declick if there is an internal generator - we just want it to
|
||||
keep generating sound without interruption.
|
||||
|
||||
ditto if we are monitoring inputs.
|
||||
*/
|
||||
|
||||
if (_have_internal_generator || (_monitoring_control->monitoring_choice() == MonitorInput)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!declick) {
|
||||
declick = _pending_declick;
|
||||
}
|
||||
|
||||
if (declick != 0) {
|
||||
Amp::declick (bufs, nframes, declick);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
Track::monitoring_changed (bool, Controllable::GroupControlDisposition)
|
||||
{
|
||||
|
|
Loading…
Reference in New Issue
Block a user