Automatable now requires (and owns) a time domain to be used by automation data

This commit is contained in:
Paul Davis 2021-01-13 09:02:47 -07:00
parent 2131adec9d
commit 7c10cf1d54
39 changed files with 78 additions and 60 deletions

View File

@ -43,7 +43,7 @@ using namespace PBD;
#define GAIN_COEFF_DELTA (1e-5)
Amp::Amp (Session& s, const std::string& name, boost::shared_ptr<GainControl> gc, bool control_midi_also)
: Processor(s, "Amp")
: Processor(s, "Amp", Temporal::AudioTime)
, _apply_gain_automation(false)
, _current_gain(GAIN_COEFF_ZERO)
, _current_automation_sample (INT64_MAX)

View File

@ -50,7 +50,7 @@ class AutomationControl;
class LIBARDOUR_API Automatable : virtual public Evoral::ControlSet, public Slavable
{
public:
Automatable(Session&);
Automatable(Session&, Temporal::TimeDomain);
Automatable (const Automatable& other);
virtual ~Automatable();
@ -114,6 +114,8 @@ public:
PBD::Signal0<void> AutomationStateChanged;
Temporal::TimeDomain time_domain() const { return _time_domain; }
protected:
Session& _a_session;
@ -136,6 +138,7 @@ protected:
private:
PBD::ScopedConnectionList _control_connections; ///< connections to our controls' signals
Temporal::TimeDomain _time_domain;
};

View File

@ -30,9 +30,9 @@ namespace ARDOUR {
template<typename T>
class /*LIBARDOUR_API*/ AutomatableSequence : public Automatable, public Evoral::Sequence<T> {
public:
AutomatableSequence(Session& s)
AutomatableSequence(Session& s, Temporal::TimeDomain td)
: Evoral::ControlSet()
, Automatable(s)
, Automatable(s, td)
, Evoral::Sequence<T>(EventTypeMap::instance())
{}

View File

@ -59,7 +59,8 @@ public:
static const std::string state_node_name;
DiskIOProcessor (Session&, Track&, const std::string& name, Flag f);
DiskIOProcessor (Session&, Track&, const std::string& name, Flag f, Temporal::TimeDomain td);
virtual ~DiskIOProcessor ();
static void set_buffering_parameters (BufferingPreset bp);

View File

@ -41,7 +41,7 @@ template <typename T> class MidiRingBuffer;
class LIBARDOUR_API DiskReader : public DiskIOProcessor
{
public:
DiskReader (Session&, Track&, std::string const& name, DiskIOProcessor::Flag f = DiskIOProcessor::Flag (0));
DiskReader (Session&, Track&, std::string const& name, Temporal::TimeDomain, DiskIOProcessor::Flag f = DiskIOProcessor::Flag (0));
~DiskReader ();
bool set_name (std::string const& str);

View File

@ -49,7 +49,7 @@ public:
ARDOUR::DataType default_type = DataType::AUDIO, bool sendish=false);
IOProcessor (Session&, boost::shared_ptr<IO> input, boost::shared_ptr<IO> output,
const std::string& proc_name, bool sendish=false);
const std::string& proc_name, Temporal::TimeDomain, bool sendish=false);
virtual ~IOProcessor ();

View File

@ -39,7 +39,7 @@ class Panner;
class LIBARDOUR_API Pannable : public PBD::Stateful, public Automatable, public SessionHandleRef
{
public:
Pannable (Session& s);
Pannable (Session& s, Temporal::TimeDomain);
~Pannable ();
boost::shared_ptr<AutomationControl> pan_azimuth_control;

View File

@ -51,7 +51,7 @@ class Pannable;
class LIBARDOUR_API PannerShell : public SessionObject
{
public:
PannerShell (std::string name, Session&, boost::shared_ptr<Pannable>, bool is_send = false);
PannerShell (std::string name, Session&, boost::shared_ptr<Pannable>, Temporal::TimeDomain, bool is_send = false);
virtual ~PannerShell ();
std::string describe_parameter (Evoral::Parameter param);

View File

@ -141,6 +141,7 @@ class LIBARDOUR_API PresentationInfo : public PBD::Stateful
static const Flag Route; /* mask for any route (bus or track */
static const Flag Track; /* mask to use for any track */
static const Flag Bus; /* mask to use for any bus */
static const Flag MidiIndicatingFlags; /* MidiTrack or MidiBus */
typedef uint32_t order_t;
typedef uint32_t color_t;

View File

@ -51,7 +51,7 @@ class LIBARDOUR_API Processor : public SessionObject, public Automatable, public
public:
static const std::string state_node_name;
Processor(Session&, const std::string& name);
Processor(Session&, const std::string& name, Temporal::TimeDomain);
Processor (const Processor& other);
virtual ~Processor();

View File

@ -24,6 +24,8 @@
#include <map>
#include <string>
#include "temporal/types.h"
#include "ardour/libardour_visibility.h"
#include "ardour/types.h"
#include "ardour/utils.h"

View File

@ -34,7 +34,7 @@
DO dump the config using cfgtool to system_config
after modifying this file.
./waf && gtk2_ardour/arcfg system_config
S ./waf && gtk2_ardour/arcfg system_config
*****************************************************/
/* IO connection */
@ -225,6 +225,7 @@ CONFIG_VARIABLE (double, automation_thinning_factor, "automation-thinning-factor
CONFIG_VARIABLE (std::string, freesound_download_dir, "freesound-download-dir", Glib::get_home_dir() + "/Freesound/snd")
CONFIG_VARIABLE (samplecnt_t, range_location_minimum, "range-location-minimum", 128) /* samples */
CONFIG_VARIABLE (EditMode, edit_mode, "edit-mode", Slide)
CONFIG_VARIABLE (Temporal::TimeDomain, default_automation_time_domain, "default-automation-time-domain", Temporal::BeatTime)
/* plugin related */

View File

@ -25,6 +25,7 @@
#endif
#include "pbd/enum_convert.h"
#include "pbd/i18n.h"
#include "ardour/types.h"
#include "ardour/data_type.h"

View File

@ -247,7 +247,7 @@ AudioRegion::AudioRegion (Session& s, timecnt_t const & start, timecnt_t const
: Region (s, start, len, name, DataType::AUDIO)
, AUDIOREGION_STATE_DEFAULT
, _envelope (Properties::envelope, boost::shared_ptr<AutomationList> (new AutomationList (Evoral::Parameter(EnvelopeAutomation), Temporal::AudioTime)))
, _automatable (s)
, _automatable (s, Temporal::AudioTime)
, _fade_in_suspended (0)
, _fade_out_suspended (0)
{
@ -260,7 +260,7 @@ AudioRegion::AudioRegion (const SourceList& srcs)
: Region (srcs)
, AUDIOREGION_STATE_DEFAULT
, _envelope (Properties::envelope, boost::shared_ptr<AutomationList> (new AutomationList (Evoral::Parameter(EnvelopeAutomation), Temporal::AudioTime)))
, _automatable(srcs[0]->session())
, _automatable(srcs[0]->session(), Temporal::AudioTime)
, _fade_in_suspended (0)
, _fade_out_suspended (0)
{
@ -275,7 +275,7 @@ AudioRegion::AudioRegion (boost::shared_ptr<const AudioRegion> other)
* to do with sources (and hence _start). So when we copy the envelope, we just use the supplied offset.
*/
, _envelope (Properties::envelope, boost::shared_ptr<AutomationList> (new AutomationList (*other->_envelope.val(), timepos_t (Temporal::AudioTime), timepos_t (other->_length))))
, _automatable (other->session())
, _automatable (other->session(), Temporal::AudioTime)
, _fade_in_suspended (0)
, _fade_out_suspended (0)
{
@ -297,7 +297,7 @@ AudioRegion::AudioRegion (boost::shared_ptr<const AudioRegion> other, timecnt_t
to do with sources (and hence _start). So when we copy the envelope, we just use the supplied offset.
*/
, _envelope (Properties::envelope, boost::shared_ptr<AutomationList> (new AutomationList (*other->_envelope.val(), timepos_t (offset.samples()), timepos_t (other->_length))))
, _automatable (other->session())
, _automatable (other->session(), Temporal::AudioTime)
, _fade_in_suspended (0)
, _fade_out_suspended (0)
{
@ -316,7 +316,7 @@ AudioRegion::AudioRegion (boost::shared_ptr<const AudioRegion> other, const Sour
: Region (boost::static_pointer_cast<const Region>(other), srcs)
, AUDIOREGION_COPY_STATE (other)
, _envelope (Properties::envelope, boost::shared_ptr<AutomationList> (new AutomationList (*other->_envelope.val())))
, _automatable (other->session())
, _automatable (other->session(), Temporal::AudioTime)
, _fade_in_suspended (0)
, _fade_out_suspended (0)
{
@ -335,7 +335,7 @@ AudioRegion::AudioRegion (SourceList& srcs)
: Region (srcs)
, AUDIOREGION_STATE_DEFAULT
, _envelope (Properties::envelope, boost::shared_ptr<AutomationList> (new AutomationList(Evoral::Parameter(EnvelopeAutomation), Temporal::AudioTime)))
, _automatable(srcs[0]->session())
, _automatable(srcs[0]->session(), Temporal::AudioTime)
, _fade_in_suspended (0)
, _fade_out_suspended (0)
{

View File

@ -59,9 +59,11 @@ bool Automatable::skip_saving_automation = false;
const string Automatable::xml_node_name = X_("Automation");
Automatable::Automatable(Session& session)
: _a_session(session)
, _automated_controls (new ControlList)
Automatable::Automatable(Session& session, Temporal::TimeDomain td)
: ControlSet ()
, _a_session(session)
, _automated_controls (new ControlList ())
, _time_domain (td)
{
}

View File

@ -27,7 +27,7 @@
namespace ARDOUR {
CapturingProcessor::CapturingProcessor (Session & session, samplecnt_t latency)
: Processor (session, X_("capture point"))
: Processor (session, X_("capture point"), Temporal::AudioTime)
, block_size (AudioEngine::instance()->samples_per_cycle())
, _latency (latency)
{

View File

@ -35,13 +35,14 @@ using namespace PBD;
using namespace ARDOUR;
DelayLine::DelayLine (Session& s, const std::string& name)
: Processor (s, string_compose ("latcomp-%1-%2", name, this))
, _bsiz (0)
, _delay (0)
, _pending_delay (0)
, _roff (0)
, _woff (0)
, _pending_flush (false)
#warning NUTEMPO why audio time when this processor can handle MIDI also
: Processor (s, string_compose ("latcomp-%1-%2", name, this), Temporal::AudioTime)
, _bsiz (0)
, _delay (0)
, _pending_delay (0)
, _roff (0)
, _woff (0)
, _pending_flush (false)
{
}

View File

@ -57,7 +57,7 @@ bool Delivery::panners_legal = false;
Delivery::Delivery (Session& s, boost::shared_ptr<IO> io, boost::shared_ptr<Pannable> pannable,
boost::shared_ptr<MuteMaster> mm, const string& name, Role r)
: IOProcessor(s, boost::shared_ptr<IO>(), (role_requires_output_ports (r) ? io : boost::shared_ptr<IO>()), name, (r == Send || r == Aux || r == Foldback))
: IOProcessor(s, boost::shared_ptr<IO>(), (role_requires_output_ports (r) ? io : boost::shared_ptr<IO>()), name, Temporal::AudioTime, (r == Send || r == Aux || r == Foldback))
, _role (r)
, _output_buffers (new BufferSet())
, _current_gain (GAIN_COEFF_ZERO)
@ -68,7 +68,7 @@ Delivery::Delivery (Session& s, boost::shared_ptr<IO> io, boost::shared_ptr<Pann
if (pannable) {
bool is_send = false;
if (r & (Delivery::Send|Delivery::Aux|Delivery::Foldback)) is_send = true;
_panshell = boost::shared_ptr<PannerShell>(new PannerShell (_name, _session, pannable, is_send));
_panshell = boost::shared_ptr<PannerShell>(new PannerShell (_name, _session, pannable, time_domain(), is_send));
}
_display_to_user = false;
@ -92,7 +92,7 @@ Delivery::Delivery (Session& s, boost::shared_ptr<Pannable> pannable, boost::sha
if (pannable) {
bool is_send = false;
if (r & (Delivery::Send|Delivery::Aux|Delivery::Foldback)) is_send = true;
_panshell = boost::shared_ptr<PannerShell>(new PannerShell (_name, _session, pannable, is_send));
_panshell = boost::shared_ptr<PannerShell>(new PannerShell (_name, _session, pannable, time_domain(), is_send));
}
_display_to_user = false;

View File

@ -48,8 +48,8 @@ const string DiskIOProcessor::state_node_name = X_("DiskIOProcessor");
// PBD::Signal0<void> DiskIOProcessor::DiskOverrun;
// PBD::Signal0<void> DiskIOProcessor::DiskUnderrun;
DiskIOProcessor::DiskIOProcessor (Session& s, Track& t, string const & str, Flag f)
: Processor (s, str)
DiskIOProcessor::DiskIOProcessor (Session& s, Track& t, string const & str, Flag f, Temporal::TimeDomain td)
: Processor (s, str, td)
, _flags (f)
, _slaved (false)
, in_set_state (false)

View File

@ -57,8 +57,8 @@ DiskReader::Declicker DiskReader::loop_declick_in;
DiskReader::Declicker DiskReader::loop_declick_out;
samplecnt_t DiskReader::loop_fade_length (0);
DiskReader::DiskReader (Session& s, Track& t, string const& str, DiskIOProcessor::Flag f)
: DiskIOProcessor (s, t, X_("player:") + str, f)
DiskReader::DiskReader (Session& s, Track& t, string const& str, Temporal::TimeDomain td, DiskIOProcessor::Flag f)
: DiskIOProcessor (s, t, X_("player:") + str, f, td)
, overwrite_sample (0)
, run_must_resolve (false)
, _declick_amp (s.nominal_sample_rate ())

View File

@ -47,7 +47,7 @@ ARDOUR::samplecnt_t DiskWriter::_chunk_samples = DiskWriter::default_chunk_sampl
PBD::Signal0<void> DiskWriter::Overrun;
DiskWriter::DiskWriter (Session& s, Track& t, string const & str, DiskIOProcessor::Flag f)
: DiskIOProcessor (s, t, X_("recorder:") + str, f)
: DiskIOProcessor (s, t, X_("recorder:") + str, f, Config->get_default_automation_time_domain())
, _capture_captured (0)
, _was_recording (false)
, _xrun_flag (false)

View File

@ -47,7 +47,7 @@ namespace ARDOUR { class Session; }
IOProcessor::IOProcessor (Session& s, bool with_input, bool with_output,
const string& proc_name, const string io_name, DataType dtype, bool sendish)
: Processor(s, proc_name)
: Processor (s, proc_name, (dtype == DataType::AUDIO ? Temporal::AudioTime : Temporal::BeatTime))
{
/* these are true in this constructor whether we actually create the associated
IO objects or not.
@ -71,8 +71,8 @@ IOProcessor::IOProcessor (Session& s, bool with_input, bool with_output,
/* create an IOProcessor that proxies to an existing IO object */
IOProcessor::IOProcessor (Session& s, boost::shared_ptr<IO> in, boost::shared_ptr<IO> out,
const string& proc_name, bool sendish)
: Processor(s, proc_name)
const string& proc_name, Temporal::TimeDomain td, bool sendish)
: Processor(s, proc_name, td)
, _input (in)
, _output (out)
{

View File

@ -42,7 +42,7 @@ using namespace std;
using namespace ARDOUR;
PeakMeter::PeakMeter (Session& s, const std::string& name)
: Processor (s, string_compose ("meter-%1", name))
: Processor (s, string_compose ("meter-%1", name), Temporal::AudioTime)
{
Kmeterdsp::init (s.nominal_sample_rate ());
Iec1ppmdsp::init (s.nominal_sample_rate ());

View File

@ -59,7 +59,7 @@ using namespace ARDOUR;
using namespace PBD;
MidiModel::MidiModel (boost::shared_ptr<MidiSource> s)
: AutomatableSequence<TimeType>(s->session())
: AutomatableSequence<TimeType> (s->session(), Temporal::BeatTime)
{
set_midi_source (s);
}

View File

@ -48,7 +48,7 @@ namespace ARDOUR {
}
MonitorProcessor::MonitorProcessor (Session& s)
: Processor (s, X_("MonitorOut"))
: Processor (s, X_("MonitorOut"), Temporal::AudioTime)
, solo_cnt (0)
, _monitor_active (false)

View File

@ -39,8 +39,8 @@ using namespace std;
using namespace PBD;
using namespace ARDOUR;
Pannable::Pannable (Session& s)
: Automatable (s)
Pannable::Pannable (Session& s, Temporal::TimeDomain td)
: Automatable (s, td)
, SessionHandleRef (s)
, pan_azimuth_control (new PanControllable (s, "", this, PanAzimuthAutomation))
, pan_elevation_control (new PanControllable (s, "", this, PanElevationAutomation))

View File

@ -66,7 +66,7 @@ using namespace std;
using namespace ARDOUR;
using namespace PBD;
PannerShell::PannerShell (string name, Session& s, boost::shared_ptr<Pannable> p, bool is_send)
PannerShell::PannerShell (string name, Session& s, boost::shared_ptr<Pannable> p, Temporal::TimeDomain td, bool is_send)
: SessionObject (s, name)
, _pannable_route (p)
, _is_send (is_send)
@ -78,7 +78,7 @@ PannerShell::PannerShell (string name, Session& s, boost::shared_ptr<Pannable> p
, _force_reselect (false)
{
if (is_send) {
_pannable_internal.reset(new Pannable (s));
_pannable_internal.reset(new Pannable (s, td));
if (Config->get_link_send_and_route_panner()) {
_panlinked = true;
} else {

View File

@ -76,7 +76,8 @@ using namespace PBD;
const string PluginInsert::port_automation_node_name = "PortAutomation";
PluginInsert::PluginInsert (Session& s, boost::shared_ptr<Plugin> plug)
: Processor (s, (plug ? plug->name() : string ("toBeRenamed")))
#warning NUTEMPO why audio time when this processor can handle MIDI also
: Processor (s, (plug ? plug->name() : string ("toBeRenamed")), Temporal::AudioTime)
, _sc_playback_latency (0)
, _sc_capture_latency (0)
, _plugin_signal_latency (0)

View File

@ -28,7 +28,7 @@ using namespace ARDOUR;
using namespace PBD;
PolarityProcessor::PolarityProcessor (Session& s, boost::shared_ptr<PhaseControl> control)
: Processor(s, "Polarity")
: Processor(s, "Polarity", Temporal::AudioTime)
, _control (control)
{
}

View File

@ -120,6 +120,7 @@ const PresentationInfo::Flag PresentationInfo::AllRoutes = PresentationInfo::Fla
const PresentationInfo::Flag PresentationInfo::MixerRoutes = PresentationInfo::Flag (PresentationInfo::Route|PresentationInfo::MasterOut|PresentationInfo::MonitorOut);
const PresentationInfo::Flag PresentationInfo::AllStripables = PresentationInfo::Flag (PresentationInfo::AllRoutes|PresentationInfo::VCA);
const PresentationInfo::Flag PresentationInfo::MixerStripables = PresentationInfo::Flag (PresentationInfo::MixerRoutes|PresentationInfo::VCA);
const PresentationInfo::Flag PresentationInfo::MidiIndicatingFlags = PresentationInfo::Flag (PresentationInfo::MidiTrack|PresentationInfo::MidiBus);
void
PresentationInfo::make_property_quarks ()

View File

@ -58,9 +58,9 @@ namespace ARDOUR { class Session; }
// Always saved as Processor, but may be IOProcessor or Send in legacy sessions
const string Processor::state_node_name = "Processor";
Processor::Processor(Session& session, const string& name)
Processor::Processor(Session& session, const string& name, Temporal::TimeDomain td)
: SessionObject(session, name)
, Automatable (session)
, Automatable (session, td)
, _pending_active(false)
, _active(false)
, _next_ab_is_active(false)
@ -82,7 +82,7 @@ Processor::Processor(Session& session, const string& name)
Processor::Processor (const Processor& other)
: Evoral::ControlSet (other)
, SessionObject (other.session(), other.name())
, Automatable (other.session())
, Automatable (other.session(), other.time_domain())
, Latent (other)
, _pending_active(other._pending_active)
, _active(other._active)

View File

@ -31,6 +31,8 @@
#include "pbd/file_utils.h"
#include "pbd/replace_all.h"
#include "temporal/types_convert.h"
#include "ardour/audioengine.h"
#include "ardour/disk_reader.h"
#include "ardour/disk_writer.h"

View File

@ -184,7 +184,7 @@ Route::init ()
/* panning */
if (!(_presentation_info.flags() & PresentationInfo::MonitorOut)) {
_pannable.reset (new Pannable (_session));
_pannable.reset (new Pannable (_session, Config->get_default_automation_time_domain()));
}
/* input and output objects */
@ -958,7 +958,7 @@ Route::add_processor_from_xml_2X (const XMLNode& node, int version)
} else if (node.name() == "Send") {
boost::shared_ptr<Pannable> sendpan (new Pannable (_session));
boost::shared_ptr<Pannable> sendpan (new Pannable (_session, Config->get_default_automation_time_domain()));
processor.reset (new Send (_session, sendpan, _mute_master));
} else {

View File

@ -36,7 +36,7 @@ using std::string;
Stripable::Stripable (Session& s, string const & name, PresentationInfo const & pi)
: SessionObject (s, name)
, Automatable (s)
, Automatable (s, (pi.flags() & PresentationInfo::MidiIndicatingFlags) ? Temporal::BeatTime : Temporal::AudioTime)
, _presentation_info (pi)
, _active_color_picker (0)
{

View File

@ -91,7 +91,7 @@ Track::init ()
DiskIOProcessor::Flag dflags = DiskIOProcessor::Recordable;
_disk_reader.reset (new DiskReader (_session, *this, name(), dflags));
_disk_reader.reset (new DiskReader (_session, *this, name(), Config->get_default_automation_time_domain(), dflags));
_disk_reader->set_block_size (_session.get_block_size ());
_disk_reader->set_owner (this);

View File

@ -52,7 +52,7 @@ proc_type_map (std::string const& str)
}
UnknownProcessor::UnknownProcessor (Session& s, XMLNode const & state)
: Processor (s, "")
: Processor (s, "", Temporal::AudioTime)
, _state (state)
, have_ioconfig (false)
, saved_input (0)

View File

@ -30,11 +30,11 @@ using namespace std;
namespace Evoral {
ControlSet::ControlSet()
ControlSet::ControlSet ()
{
}
ControlSet::ControlSet (const ControlSet&)
ControlSet::ControlSet (ControlSet const & other)
: noncopyable ()
{
/* derived class must copy controls */

View File

@ -86,7 +86,7 @@ Sequence<Time>::const_iterator::const_iterator(const Sequence<Time>&
: _seq(&seq)
, _active_patch_change_message (0)
, _type(NIL)
, _is_end((t == DBL_MAX) || seq.empty())
, _is_end((t == std::numeric_limits<Time>::max()) || seq.empty())
, _note_iter(seq.notes().end())
, _sysex_iter(seq.sysexes().end())
, _patch_change_iter(seq.patch_changes().end())

View File

@ -29,6 +29,8 @@
#include <glibmm/threads.h>
#include "pbd/signals.h"
#include "temporal/types.h"
#include "evoral/visibility.h"
#include "evoral/Parameter.h"
#include "evoral/ControlList.h"
@ -40,7 +42,7 @@ class ControlEvent;
class LIBEVORAL_API ControlSet : public boost::noncopyable {
public:
ControlSet();
ControlSet ();
ControlSet (const ControlSet&);
virtual ~ControlSet() {}