summaryrefslogtreecommitdiff
path: root/libs/ardour/ardour
diff options
context:
space:
mode:
authorPaul Davis <paul@linuxaudiosystems.com>2018-09-18 18:51:59 -0400
committerPaul Davis <paul@linuxaudiosystems.com>2018-09-18 19:06:04 -0400
commite6915e01de2e2167c3384c6c8f2408f763971616 (patch)
treec67200eda4cf4c595503a850fe6ae72d89032a6f /libs/ardour/ardour
parent7390b88c2bb29b1b34624f441adec1e71c74bad8 (diff)
new transport slave/master implementation, libs/ edition
Diffstat (limited to 'libs/ardour/ardour')
-rw-r--r--libs/ardour/ardour/debug.h1
-rw-r--r--libs/ardour/ardour/disk_io.h4
-rw-r--r--libs/ardour/ardour/midi_buffer.h2
-rw-r--r--libs/ardour/ardour/midi_port.h32
-rw-r--r--libs/ardour/ardour/midiport_manager.h6
-rw-r--r--libs/ardour/ardour/port.h6
-rw-r--r--libs/ardour/ardour/rc_configuration.h2
-rw-r--r--libs/ardour/ardour/rc_configuration_vars.h13
-rw-r--r--libs/ardour/ardour/session.h81
-rw-r--r--libs/ardour/ardour/session_event.h14
-rw-r--r--libs/ardour/ardour/slave.h24
-rw-r--r--libs/ardour/ardour/track.h2
-rw-r--r--libs/ardour/ardour/transport_master.h546
-rw-r--r--libs/ardour/ardour/transport_master_manager.h114
-rw-r--r--libs/ardour/ardour/types.h1356
15 files changed, 1417 insertions, 786 deletions
diff --git a/libs/ardour/ardour/debug.h b/libs/ardour/ardour/debug.h
index e91e0edf51..069840a149 100644
--- a/libs/ardour/ardour/debug.h
+++ b/libs/ardour/ardour/debug.h
@@ -44,6 +44,7 @@ namespace PBD {
LIBARDOUR_API extern DebugBits Destruction;
LIBARDOUR_API extern DebugBits MTC;
LIBARDOUR_API extern DebugBits LTC;
+ LIBARDOUR_API extern DebugBits TXLTC;
LIBARDOUR_API extern DebugBits Transport;
LIBARDOUR_API extern DebugBits Slave;
LIBARDOUR_API extern DebugBits SessionEvents;
diff --git a/libs/ardour/ardour/disk_io.h b/libs/ardour/ardour/disk_io.h
index 4f9eb2257e..0f79930654 100644
--- a/libs/ardour/ardour/disk_io.h
+++ b/libs/ardour/ardour/disk_io.h
@@ -81,9 +81,6 @@ public:
virtual void non_realtime_locate (samplepos_t);
- void non_realtime_speed_change ();
- bool realtime_speed_change ();
-
virtual void punch_in() {}
virtual void punch_out() {}
@@ -118,7 +115,6 @@ protected:
uint32_t i_am_the_modifier;
double _actual_speed;
double _target_speed;
- bool _seek_required;
bool _slaved;
bool in_set_state;
samplepos_t playback_sample;
diff --git a/libs/ardour/ardour/midi_buffer.h b/libs/ardour/ardour/midi_buffer.h
index 509b60f12d..7793f7e0bd 100644
--- a/libs/ardour/ardour/midi_buffer.h
+++ b/libs/ardour/ardour/midi_buffer.h
@@ -48,6 +48,8 @@ public:
void copy(const MidiBuffer& copy);
void copy(MidiBuffer const * const);
+ void skip_to (TimeType when);
+
bool push_back(const Evoral::Event<TimeType>& event);
bool push_back(TimeType time, size_t size, const uint8_t* data);
diff --git a/libs/ardour/ardour/midi_port.h b/libs/ardour/ardour/midi_port.h
index e23914c4ce..4b453b80bc 100644
--- a/libs/ardour/ardour/midi_port.h
+++ b/libs/ardour/ardour/midi_port.h
@@ -24,6 +24,7 @@
#include "midi++/parser.h"
#include "ardour/port.h"
+#include "ardour/midi_buffer.h"
namespace ARDOUR {
@@ -51,19 +52,20 @@ class LIBARDOUR_API MidiPort : public Port {
bool input_active() const { return _input_active; }
void set_input_active (bool yn);
- Buffer& get_buffer (pframes_t nframes);
+ Buffer& get_buffer (pframes_t nframes) {
+ return get_midi_buffer (nframes);
+ }
MidiBuffer& get_midi_buffer (pframes_t nframes);
- void set_always_parse (bool yn);
- void set_trace_on (bool yn);
+ void set_trace (MIDI::Parser* trace_parser);
typedef boost::function<bool(MidiBuffer&,MidiBuffer&)> MidiFilter;
void set_inbound_filter (MidiFilter);
int add_shadow_port (std::string const &, MidiFilter);
boost::shared_ptr<MidiPort> shadow_port() const { return _shadow_port; }
- MIDI::Parser& self_parser() { return _self_parser; }
+ void read_and_parse_entire_midi_buffer_with_no_speed_adjustment (pframes_t nframes, MIDI::Parser& parser, samplepos_t now);
protected:
friend class PortManager;
@@ -72,29 +74,17 @@ class LIBARDOUR_API MidiPort : public Port {
private:
MidiBuffer* _buffer;
- bool _has_been_mixed_down;
bool _resolve_required;
bool _input_active;
- bool _always_parse;
- bool _trace_on;
MidiFilter inbound_midi_filter;
boost::shared_ptr<MidiPort> _shadow_port;
MidiFilter shadow_midi_filter;
-
- /* Naming this is tricky. AsyncMIDIPort inherits (for now, aug 2013) from
- * both MIDI::Port, which has _parser, and this (ARDOUR::MidiPort). We
- * need parsing support in this object, independently of what the
- * MIDI::Port/AsyncMIDIPort stuff does. Rather than risk errors coming
- * from not explicitly naming which _parser we want, we will call this
- * _self_parser for now.
- *
- * Ultimately, MIDI::Port should probably go away or be fully integrated
- * into this object, somehow.
- */
-
- MIDI::Parser _self_parser;
-
+ MIDI::Parser* _trace_parser;
+ bool _data_fetched_for_cycle;
+
void resolve_notes (void* buffer, samplepos_t when);
+ void pull_input (pframes_t nframes, bool adjust_speed);
+ void parse_input (pframes_t nframes, MIDI::Parser& parser);
};
} // namespace ARDOUR
diff --git a/libs/ardour/ardour/midiport_manager.h b/libs/ardour/ardour/midiport_manager.h
index 2fb5d5a57a..69b603723f 100644
--- a/libs/ardour/ardour/midiport_manager.h
+++ b/libs/ardour/ardour/midiport_manager.h
@@ -62,13 +62,11 @@ class LIBARDOUR_API MidiPortManager {
boost::shared_ptr<ARDOUR::Port> scene_input_port() const { return boost::dynamic_pointer_cast<MidiPort>(_scene_in); }
boost::shared_ptr<ARDOUR::Port> scene_output_port() const { return boost::dynamic_pointer_cast<MidiPort>(_scene_out); }
- /* Ports used for synchronization. These have their I/O handled inside the
+ /* Ports used to send synchronization. These have their output handled inside the
* process callback.
*/
- boost::shared_ptr<MidiPort> mtc_input_port() const { return _mtc_input_port; }
boost::shared_ptr<MidiPort> mtc_output_port() const { return _mtc_output_port; }
- boost::shared_ptr<MidiPort> midi_clock_input_port() const { return _midi_clock_input_port; }
boost::shared_ptr<MidiPort> midi_clock_output_port() const { return _midi_clock_output_port; }
void set_midi_port_states (const XMLNodeList&);
@@ -86,9 +84,7 @@ class LIBARDOUR_API MidiPortManager {
boost::shared_ptr<Port> _scene_out;
/* synchronously handled ports: ARDOUR::MidiPort */
- boost::shared_ptr<MidiPort> _mtc_input_port;
boost::shared_ptr<MidiPort> _mtc_output_port;
- boost::shared_ptr<MidiPort> _midi_clock_input_port;
boost::shared_ptr<MidiPort> _midi_clock_output_port;
void create_ports ();
diff --git a/libs/ardour/ardour/port.h b/libs/ardour/ardour/port.h
index 99a2b60cc3..9ab850c86b 100644
--- a/libs/ardour/ardour/port.h
+++ b/libs/ardour/ardour/port.h
@@ -123,7 +123,10 @@ public:
virtual void realtime_locate () {}
bool physically_connected () const;
- bool externally_connected () const;
+ uint32_t externally_connected () const { return _externally_connected; }
+
+ void increment_external_connections() { _externally_connected++; }
+ void decrement_external_connections() { if (_externally_connected) _externally_connected--; }
PBD::Signal1<void,bool> MonitorInputChanged;
static PBD::Signal2<void,boost::shared_ptr<Port>,boost::shared_ptr<Port> > PostDisconnect;
@@ -170,6 +173,7 @@ private:
std::string _name; ///< port short name
PortFlags _flags; ///< flags
bool _last_monitor;
+ uint32_t _externally_connected;
/** ports that we are connected to, kept so that we can
reconnect to the backend when required
diff --git a/libs/ardour/ardour/rc_configuration.h b/libs/ardour/ardour/rc_configuration.h
index a644d76250..f3b98c7774 100644
--- a/libs/ardour/ardour/rc_configuration.h
+++ b/libs/ardour/ardour/rc_configuration.h
@@ -55,6 +55,7 @@ class LIBARDOUR_API RCConfiguration : public PBD::Configuration
XMLNode * instant_xml (const std::string& str);
XMLNode* control_protocol_state () { return _control_protocol_state; }
+ XMLNode* transport_master_state () { return _transport_master_state; }
/* define accessor methods */
@@ -83,6 +84,7 @@ class LIBARDOUR_API RCConfiguration : public PBD::Configuration
#undef CONFIG_VARIABLE_SPECIAL
XMLNode* _control_protocol_state;
+ XMLNode* _transport_master_state;
};
/* XXX: rename this */
diff --git a/libs/ardour/ardour/rc_configuration_vars.h b/libs/ardour/ardour/rc_configuration_vars.h
index b7ee95e9e5..7ffc8879e2 100644
--- a/libs/ardour/ardour/rc_configuration_vars.h
+++ b/libs/ardour/ardour/rc_configuration_vars.h
@@ -45,6 +45,11 @@ CONFIG_VARIABLE (bool, strict_io, "strict-io", true)
/* Naming */
CONFIG_VARIABLE (TracksAutoNamingRule, tracks_auto_naming, "tracks-auto-naming", UseDefaultNames)
+/* Transport Masters (all) */
+
+CONFIG_VARIABLE (bool, transport_masters_just_roll_when_sync_lost, "transport-masters-just-roll-when-sync-lost", false)
+CONFIG_VARIABLE (bool, midi_clock_sets_tempo, "midi-clock-sets-tempo", true)
+
/* MIDI and MIDI related */
CONFIG_VARIABLE (bool, trace_midi_input, "trace-midi-input", false)
@@ -63,15 +68,11 @@ CONFIG_VARIABLE (bool, midi_input_follows_selection, "midi-input-follows-selecti
/* Timecode and related */
+CONFIG_VARIABLE (bool, run_all_transport_masters_always, "run-all-transport-masters-always", true)
+CONFIG_VARIABLE (bool, use_session_timecode_format, "use-session-timecode-format", true)
CONFIG_VARIABLE (int, mtc_qf_speed_tolerance, "mtc-qf-speed-tolerance", 5)
CONFIG_VARIABLE (bool, timecode_sync_frame_rate, "timecode-sync-frame-rate", true)
#ifdef USE_TRACKS_CODE_FEATURES
-CONFIG_VARIABLE (bool, timecode_source_is_synced, "timecode-source-is-synced", true)
-#else
-CONFIG_VARIABLE (bool, timecode_source_is_synced, "timecode-source-is-synced", false)
-#endif
-CONFIG_VARIABLE (bool, timecode_source_2997, "timecode-source-2997", false)
-#ifdef USE_TRACKS_CODE_FEATURES
CONFIG_VARIABLE (SyncSource, sync_source, "sync-source", MTC)
#else
CONFIG_VARIABLE (SyncSource, sync_source, "sync-source", Engine)
diff --git a/libs/ardour/ardour/session.h b/libs/ardour/ardour/session.h
index c4c7458670..6e7ec93dec 100644
--- a/libs/ardour/ardour/session.h
+++ b/libs/ardour/ardour/session.h
@@ -149,11 +149,12 @@ class SceneChanger;
class SessionDirectory;
class SessionMetadata;
class SessionPlaylists;
-class Slave;
class Source;
class Speakers;
class TempoMap;
+class TransportMaster;
class Track;
+class UI_TransportMaster;
class VCAManager;
class WindowsVSTPlugin;
@@ -358,10 +359,6 @@ public:
PBD::Signal0<void> IOConnectionsComplete;
- /* Timecode status signals */
- PBD::Signal1<void, bool> MTCSyncStateChanged;
- PBD::Signal1<void, bool> LTCSyncStateChanged;
-
/* Record status signals */
PBD::Signal0<void> RecordStateChanged; /* signals changes in recording state (i.e. are we recording) */
@@ -415,8 +412,8 @@ public:
void request_roll_at_and_return (samplepos_t start, samplepos_t return_to);
void request_bounded_roll (samplepos_t start, samplepos_t end);
- void request_stop (bool abort = false, bool clear_state = false);
- void request_locate (samplepos_t sample, bool with_roll = false);
+ void request_stop (bool abort = false, bool clear_state = false, TransportRequestSource origin = TRS_UI);
+ void request_locate (samplepos_t sample, bool with_roll = false, TransportRequestSource origin = TRS_UI);
void request_play_loop (bool yn, bool leave_rolling = false);
bool get_play_loop () const { return play_loop; }
@@ -426,8 +423,8 @@ public:
void goto_start (bool and_roll = false);
void use_rf_shuttle_speed ();
void allow_auto_play (bool yn);
- void request_transport_speed (double speed, bool as_default = true);
- void request_transport_speed_nonzero (double, bool as_default = true);
+ void request_transport_speed (double speed, bool as_default = true, TransportRequestSource origin = TRS_UI);
+ void request_transport_speed_nonzero (double, bool as_default = true, TransportRequestSource origin = TRS_UI);
void request_overwrite_buffer (boost::shared_ptr<Route>);
void adjust_playback_buffering();
void adjust_capture_buffering();
@@ -687,6 +684,7 @@ public:
samplepos_t requested_return_sample() const { return _requested_return_sample; }
void set_requested_return_sample(samplepos_t return_to);
+ bool compute_audible_delta (samplepos_t& pos_and_delta) const;
samplecnt_t remaining_latency_preroll () const { return _remaining_latency_preroll; }
enum PullupFormat {
@@ -719,10 +717,8 @@ public:
static PBD::Signal1<void, samplepos_t> StartTimeChanged;
static PBD::Signal1<void, samplepos_t> EndTimeChanged;
- void request_sync_source (Slave*);
- bool synced_to_engine() const { return _slave && config.get_external_sync() && Config->get_sync_source() == Engine; }
- bool synced_to_mtc () const { return config.get_external_sync() && Config->get_sync_source() == MTC && g_atomic_int_get (const_cast<gint*>(&_mtc_active)); }
- bool synced_to_ltc () const { return config.get_external_sync() && Config->get_sync_source() == LTC && g_atomic_int_get (const_cast<gint*>(&_ltc_active)); }
+ void request_sync_source (boost::shared_ptr<TransportMaster>);
+ bool synced_to_engine() const { return config.get_external_sync() && Config->get_sync_source() == Engine; }
double engine_speed() const { return _engine_speed; }
double actual_speed() const {
@@ -1104,7 +1100,7 @@ public:
PostTransportRoll = 0x8,
PostTransportAbort = 0x10,
PostTransportOverWrite = 0x20,
- PostTransportSpeed = 0x40,
+ /* was ... PostTransportSpeed = 0x40, */
PostTransportAudition = 0x80,
PostTransportReverse = 0x100,
PostTransportInputChange = 0x200,
@@ -1114,15 +1110,6 @@ public:
PostTransportAdjustCaptureBuffering = 0x2000
};
- enum SlaveState {
- Stopped,
- Waiting,
- Running
- };
-
- SlaveState slave_state() const { return _slave_state; }
- Slave* slave() const { return _slave; }
-
boost::shared_ptr<SessionPlaylists> playlists;
void send_mmc_locate (samplepos_t);
@@ -1189,22 +1176,16 @@ public:
/* synchronous MIDI ports used for synchronization */
boost::shared_ptr<MidiPort> midi_clock_output_port () const;
- boost::shared_ptr<MidiPort> midi_clock_input_port () const;
boost::shared_ptr<MidiPort> mtc_output_port () const;
- boost::shared_ptr<MidiPort> mtc_input_port () const;
- boost::shared_ptr<Port> ltc_input_port() const;
boost::shared_ptr<Port> ltc_output_port() const;
- boost::shared_ptr<IO> ltc_input_io() { return _ltc_input; }
boost::shared_ptr<IO> ltc_output_io() { return _ltc_output; }
MIDI::MachineControl& mmc() { return *_mmc; }
void reconnect_midi_scene_ports (bool);
- void reconnect_mtc_ports ();
void reconnect_mmc_ports (bool);
- void reconnect_ltc_input ();
void reconnect_ltc_output ();
VCAManager& vca_manager() { return *_vca_manager; }
@@ -1212,6 +1193,9 @@ public:
void auto_connect_thread_wakeup ();
+ double compute_speed_from_master (pframes_t nframes);
+ bool transport_master_is_external() const;
+ boost::shared_ptr<TransportMaster> transport_master() const;
protected:
friend class AudioEngine;
@@ -1254,7 +1238,6 @@ private:
gint _seek_counter;
Location* _session_range_location; ///< session range, or 0 if there is nothing in the session yet
bool _session_range_end_is_free;
- Slave* _slave;
bool _silent;
samplecnt_t _remaining_latency_preroll;
@@ -1267,7 +1250,6 @@ private:
double _target_transport_speed;
bool auto_play_legal;
- samplepos_t _last_slave_transport_sample;
samplepos_t _requested_return_sample;
pframes_t current_block_size;
samplecnt_t _worst_output_latency;
@@ -1286,11 +1268,6 @@ private:
std::string _missing_file_replacement;
- void mtc_status_changed (bool);
- PBD::ScopedConnection mtc_status_connection;
- void ltc_status_changed (bool);
- PBD::ScopedConnection ltc_status_connection;
-
void initialize_latencies ();
void update_latency (bool playback);
bool update_route_latency (bool reverse, bool apply_to_delayline);
@@ -1317,28 +1294,21 @@ private:
static const samplecnt_t bounce_chunk_size;
- /* slave tracking */
+ /* Transport master DLL */
- static const int delta_accumulator_size = 25;
- int delta_accumulator_cnt;
- int32_t delta_accumulator[delta_accumulator_size];
- int32_t average_slave_delta;
- int average_dir;
- bool have_first_delta_accumulator;
+ enum TransportMasterState {
+ Stopped, /* no incoming or invalid signal/data for master to run with */
+ Waiting, /* waiting to get full lock on incoming signal/data */
+ Running /* lock achieved, master is generating meaningful speed & position */
+ };
- SlaveState _slave_state;
- gint _mtc_active;
- gint _ltc_active;
- samplepos_t slave_wait_end;
+ TransportMasterState transport_master_tracking_state;
+ samplepos_t master_wait_end;
+ void track_transport_master (float slave_speed, samplepos_t slave_transport_sample);
+ bool follow_transport_master (pframes_t nframes);
+ void sync_source_changed (SyncSource, samplepos_t pos, pframes_t cycle_nframes);
void reset_slave_state ();
- bool follow_slave (pframes_t);
- void calculate_moving_average_of_slave_delta (int dir, samplecnt_t this_delta);
- void track_slave_state (float slave_speed, samplepos_t slave_transport_sample, samplecnt_t this_delta);
-
- void switch_to_sync_source (SyncSource); /* !RT context */
- void drop_sync_source (); /* !RT context */
- void use_sync_source (Slave*); /* RT context */
bool post_export_sync;
samplepos_t post_export_position;
@@ -1673,6 +1643,8 @@ private:
int start_midi_thread ();
+ bool should_ignore_transport_request (TransportRequestSource, TransportRequestType) const;
+
void set_play_loop (bool yn, double speed);
void unset_play_loop ();
void overwrite_some_buffers (Track *);
@@ -2048,7 +2020,6 @@ private:
MidiClockTicker* midi_clock;
- boost::shared_ptr<IO> _ltc_input;
boost::shared_ptr<IO> _ltc_output;
boost::shared_ptr<RTTaskList> _rt_tasklist;
diff --git a/libs/ardour/ardour/session_event.h b/libs/ardour/ardour/session_event.h
index aaa254e003..37e229acfb 100644
--- a/libs/ardour/ardour/session_event.h
+++ b/libs/ardour/ardour/session_event.h
@@ -33,7 +33,7 @@
namespace ARDOUR {
-class Slave;
+class TransportMaster;
class Region;
class LIBARDOUR_API SessionEvent {
@@ -49,7 +49,6 @@ public:
RangeStop,
RangeLocate,
Overwrite,
- SetSyncSource,
Audition,
SetPlayAudioRange,
CancelPlayAudioRange,
@@ -58,6 +57,7 @@ public:
AdjustCaptureBuffering,
SetTimecodeTransmission,
Skip,
+ SetTransportMaster,
/* only one of each of these events can be queued at any one time */
@@ -79,11 +79,10 @@ public:
double speed;
union {
- void* ptr;
- bool yes_or_no;
- samplepos_t target2_sample;
- Slave* slave;
- Route* route;
+ void* ptr;
+ bool yes_or_no;
+ samplepos_t target2_sample;
+ Route* route;
};
union {
@@ -109,6 +108,7 @@ public:
std::list<MusicRange> music_range;
boost::shared_ptr<Region> region;
+ boost::shared_ptr<TransportMaster> transport_master;
SessionEvent (Type t, Action a, samplepos_t when, samplepos_t where, double spd, bool yn = false, bool yn2 = false, bool yn3 = false);
diff --git a/libs/ardour/ardour/slave.h b/libs/ardour/ardour/slave.h
index 155e295cbf..2a05268c77 100644
--- a/libs/ardour/ardour/slave.h
+++ b/libs/ardour/ardour/slave.h
@@ -36,7 +36,7 @@
#include "midi++/types.h"
-/* used for approximate_current_delta(): */
+/* used for delta_string(): */
#define PLUSMINUS(A) ( ((A)<0) ? "-" : (((A)>0) ? "+" : "\u00B1") )
#define LEADINGZERO(A) ( (A)<10 ? " " : (A)<100 ? " " : (A)<1000 ? " " : "" )
@@ -175,7 +175,7 @@ class LIBARDOUR_API Slave {
/**
* @return - current time-delta between engine and sync-source
*/
- virtual std::string approximate_current_delta() const { return ""; }
+ virtual std::string delta_string () const { return ""; }
};
@@ -191,11 +191,6 @@ class LIBARDOUR_API ISlaveSessionProxy {
virtual pframes_t samples_since_cycle_start () const { return 0; }
virtual samplepos_t sample_time_at_cycle_start() const { return 0; }
virtual samplepos_t sample_time () const { return 0; }
-
- virtual void request_locate (samplepos_t /*sample*/, bool with_roll = false) {
- (void) with_roll;
- }
- virtual void request_transport_speed (double /*speed*/) {}
};
@@ -214,9 +209,6 @@ class LIBARDOUR_API SlaveSessionProxy : public ISlaveSessionProxy {
pframes_t samples_since_cycle_start () const;
samplepos_t sample_time_at_cycle_start() const;
samplepos_t sample_time () const;
-
- void request_locate (samplepos_t sample, bool with_roll = false);
- void request_transport_speed (double speed);
};
struct LIBARDOUR_API SafeTime {
@@ -246,7 +238,7 @@ class LIBARDOUR_API TimecodeSlave : public Slave {
should NOT do any computation, but should use a cached value
of the TC source position.
*/
- virtual std::string approximate_current_position() const = 0;
+ virtual std::string position_string () const = 0;
samplepos_t timecode_offset;
bool timecode_negative_offset;
@@ -272,8 +264,8 @@ class LIBARDOUR_API MTC_Slave : public TimecodeSlave {
bool give_slave_full_control_over_transport_speed() const;
Timecode::TimecodeFormat apparent_timecode_format() const;
- std::string approximate_current_position() const;
- std::string approximate_current_delta() const;
+ std::string position_string () const;
+ std::string delta_string () const;
private:
Session& session;
@@ -354,8 +346,8 @@ public:
bool give_slave_full_control_over_transport_speed() const { return true; }
Timecode::TimecodeFormat apparent_timecode_format() const;
- std::string approximate_current_position() const;
- std::string approximate_current_delta() const;
+ std::string position_string() const;
+ std::string delta_string() const;
private:
void parse_ltc(const pframes_t, const Sample* const, const samplecnt_t);
@@ -427,7 +419,7 @@ class LIBARDOUR_API MIDIClock_Slave : public Slave {
bool give_slave_full_control_over_transport_speed() const { return true; }
void set_bandwidth (double a_bandwith) { bandwidth = a_bandwith; }
- std::string approximate_current_delta() const;
+ std::string delta_string () const;
protected:
ISlaveSessionProxy* session;
diff --git a/libs/ardour/ardour/track.h b/libs/ardour/ardour/track.h
index 2ec5a0f4aa..b6abece1f0 100644
--- a/libs/ardour/ardour/track.h
+++ b/libs/ardour/ardour/track.h
@@ -140,7 +140,7 @@ public:
int can_internal_playback_seek (samplecnt_t);
int internal_playback_seek (samplecnt_t);
void non_realtime_locate (samplepos_t);
- void non_realtime_speed_change ();
+ void realtime_handle_transport_stopped ();
int overwrite_existing_buffers ();
samplecnt_t get_captured_samples (uint32_t n = 0) const;
void transport_looped (samplepos_t);
diff --git a/libs/ardour/ardour/transport_master.h b/libs/ardour/ardour/transport_master.h
new file mode 100644
index 0000000000..9da0378fb1
--- /dev/null
+++ b/libs/ardour/ardour/transport_master.h
@@ -0,0 +1,546 @@
+/*
+ Copyright (C) 2002 Paul Davis
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+*/
+
+#ifndef __ardour_transport_master_h__
+#define __ardour_transport_master_h__
+
+#include <vector>
+
+#include <boost/atomic.hpp>
+#include <boost/optional.hpp>
+
+#include <glibmm/threads.h>
+
+#include <ltc.h>
+
+#include "pbd/signals.h"
+
+#include "temporal/time.h"
+
+#include "ardour/libardour_visibility.h"
+#include "ardour/types.h"
+#include "midi++/parser.h"
+#include "midi++/types.h"
+
+
+/* used for delta_string(): */
+#define PLUSMINUS(A) ( ((A)<0) ? "-" : (((A)>0) ? "+" : "\u00B1") )
+#define LEADINGZERO(A) ( (A)<10 ? " " : (A)<100 ? " " : (A)<1000 ? " " : "" )
+
+namespace ARDOUR {
+
+class TempoMap;
+class Session;
+class AudioEngine;
+class Location;
+class MidiPort;
+class AudioPort;
+class Port;
+
+
+/**
+ * @class TransportMaster
+ *
+ * @brief The TransportMaster interface can be used to sync ARDOURs tempo to an external source
+ * like MTC, MIDI Clock, etc. as well as a single internal pseudo master we
+ * call "UI" because it is controlled from any of the user interfaces for
+ * Ardour (GUI, control surfaces, OSC, etc.)
+ *
+ */
+class LIBARDOUR_API TransportMaster {
+ public:
+
+ TransportMaster (SyncSource t, std::string const & name);
+ virtual ~TransportMaster();
+
+ static boost::shared_ptr<TransportMaster> factory (SyncSource, std::string const &);
+ static boost::shared_ptr<TransportMaster> factory (XMLNode const &);
+
+ virtual void pre_process (pframes_t nframes, samplepos_t now, boost::optional<samplepos_t>) = 0;
+
+ /**
+ * This is the most important function to implement:
+ * Each process cycle, Session::follow_slave will call this method.
+ * and after the method call they should
+ *
+ * Session::follow_slave will then try to follow the given
+ * <em>position</em> using a delay locked loop (DLL),
+ * starting with the first given transport speed.
+ * If the values of speed and position contradict each other,
+ * ARDOUR will always follow the position and disregard the speed.
+ * Although, a correct speed is important so that ARDOUR
+ * can sync to the master time source quickly.
+ *
+ * For background information on delay locked loops,
+ * see http://www.kokkinizita.net/papers/usingdll.pdf
+ *
+ * The method has the following precondition:
+ * <ul>
+ * <li>
+ * TransportMaster::ok() should return true, otherwise playback will stop
+ * immediately and the method will not be called
+ * </li>
+ * <li>
+ * when the references speed and position are passed into the TransportMaster
+ * they are uninitialized
+ * </li>
+ * </ul>
+ *
+ * After the method call the following postconditions should be met:
+ * <ul>
+ * <li>
+ * The first position value on transport start should be 0,
+ * otherwise ARDOUR will try to locate to the new position
+ * rather than move to it
+ * </li>
+ * <li>
+ * the references speed and position should be assigned
+ * to the TransportMasters current requested transport speed
+ * and transport position.
+ * </li>
+ * <li>
+ * TransportMaster::resolution() should be greater than the maximum distance of
+ * ARDOURs transport position to the slaves requested transport position.
+ * </li>
+ * <li>TransportMaster::locked() should return true, otherwise Session::no_roll will be called</li>
+ * <li>TransportMaster::starting() should be false, otherwise the transport will not move until it becomes true</li> *
+ * </ul>
+ *
+ * @param speed - The transport speed requested
+ * @param position - The transport position requested
+ * @return - The return value is currently ignored (see Session::follow_slave)
+ */
+ virtual bool speed_and_position (double& speed, samplepos_t& position, samplepos_t now) = 0;
+
+ /**
+ * reports to ARDOUR whether the TransportMaster is currently synced to its external
+ * time source.
+ *
+ * @return - when returning false, the transport will stop rolling
+ */
+ virtual bool locked() const = 0;
+
+ /**
+ * reports to ARDOUR whether the slave is in a sane state
+ *
+ * @return - when returning false, the transport will be stopped and the slave
+ * disconnected from ARDOUR.
+ */
+ virtual bool ok() const = 0;
+
+ /**
+ * reports to ARDOUR whether the slave is in the process of starting
+ * to roll
+ *
+ * @return - when returning false, transport will not move until this method returns true
+ */
+ virtual bool starting() const { return false; }
+
+ /**
+ * @return - the timing resolution of the TransportMaster - If the distance of ARDOURs transport
+ * to the slave becomes greater than the resolution, sound will stop
+ */
+ virtual samplecnt_t resolution() const = 0;
+
+ /**
+ * @return - when returning true, ARDOUR will wait for seekahead_distance() before transport
+ * starts rolling
+ */
+ virtual bool requires_seekahead () const = 0;
+
+ /**
+ * @return the number of samples that this slave wants to seek ahead. Relevant
+ * only if requires_seekahead() returns true.
+ */
+
+ virtual samplecnt_t seekahead_distance() const { return 0; }
+
+ /**
+ * @return - when returning true, ARDOUR will use transport speed 1.0 no matter what
+ * the slave returns
+ */
+ virtual bool sample_clock_synced() const { return _sclock_synced; }
+ virtual void set_sample_clock_synced (bool);
+
+ /**
+ * @return - current time-delta between engine and sync-source
+ */
+ virtual std::string delta_string() const { return ""; }
+
+ sampleoffset_t current_delta() const { return _current_delta; }
+
+ /* this is intended to be used by a UI and polled from a timeout. it should
+ return a string describing the current position of the TC source. it
+ should NOT do any computation, but should use a cached value
+ of the TC source position.
+ */
+ virtual std::string position_string() const = 0;
+
+ virtual bool can_loop() const { return false; }
+
+ virtual Location* loop_location() const { return 0; }
+ bool has_loop() const { return loop_location() != 0; }
+
+ SyncSource type() const { return _type; }
+ TransportRequestSource request_type() const {
+ switch (_type) {
+ case Engine: /* also JACK */
+ return TRS_Engine;
+ case MTC:
+ return TRS_MTC;
+ case LTC:
+ return TRS_LTC;
+ case MIDIClock:
+ break;
+ }
+ return TRS_MIDIClock;
+ }
+
+ std::string name() const { return _name; }
+ void set_name (std::string const &);
+
+ int set_state (XMLNode const &, int);
+ XMLNode& get_state();
+
+ static const std::string state_node_name;
+
+ virtual void set_session (Session*);
+
+ boost::shared_ptr<Port> port() const { return _port; }
+
+ bool check_collect();
+ virtual void set_collect (bool);
+ bool collect() const { return _collect; }
+
+ /* called whenever the manager starts collecting (processing) this
+ transport master. Typically will re-initialize any state used to
+ deal with incoming data.
+ */
+ virtual void init() = 0;
+
+ virtual void check_backend() {}
+ virtual bool allow_request (TransportRequestSource, TransportRequestType) const;
+
+ TransportRequestType request_mask() const { return _request_mask; }
+ void set_request_mask (TransportRequestType);
+ protected:
+ SyncSource _type;
+ std::string _name;
+ Session* _session;
+ bool _connected;
+ sampleoffset_t _current_delta;
+ bool _collect;
+ bool _pending_collect;
+ TransportRequestType _request_mask; /* lists transport requests still accepted when we're in control */
+ bool _sclock_synced;
+
+ /* DLL - chase incoming data */
+
+ int transport_direction;
+ int dll_initstate;
+
+ double t0;
+ double t1;
+ double e2;
+ double b, c;
+
+ boost::shared_ptr<Port> _port;
+
+ PBD::ScopedConnection port_connection;
+ bool connection_handler (boost::weak_ptr<ARDOUR::Port>, std::string name1, boost::weak_ptr<ARDOUR::Port>, std::string name2, bool yn);
+
+ PBD::ScopedConnection backend_connection;
+};
+
+struct LIBARDOUR_API SafeTime {
+ volatile int guard1;
+ samplepos_t position;
+ samplepos_t timestamp;
+ double speed;
+ volatile int guard2;
+
+ SafeTime() {
+ guard1 = 0;
+ position = 0;
+ timestamp = 0;
+ speed = 0;
+ guard2 = 0;
+ }
+};
+
+/** a helper class for any TransportMaster that receives its input via a MIDI
+ * port
+ */
+class LIBARDOUR_API TransportMasterViaMIDI {
+ public:
+ boost::shared_ptr<MidiPort> midi_port() const { return _midi_port; }
+ boost::shared_ptr<Port> create_midi_port (std::string const & port_name);
+
+ protected:
+ TransportMasterViaMIDI () {};
+
+ MIDI::Parser parser;
+ boost::shared_ptr<MidiPort> _midi_port;
+};
+
+class LIBARDOUR_API TimecodeTransportMaster : public TransportMaster {
+ public:
+ TimecodeTransportMaster (std::string const & name, SyncSource type) : TransportMaster (type, name) {}
+
+ virtual Timecode::TimecodeFormat apparent_timecode_format() const = 0;
+ samplepos_t timecode_offset;
+ bool timecode_negative_offset;
+
+ bool fr2997() const { return _fr2997; }
+ void set_fr2997 (bool);
+
+ private:
+ bool _fr2997;
+
+};
+
+class LIBARDOUR_API MTC_TransportMaster : public TimecodeTransportMaster, public TransportMasterViaMIDI {
+ public:
+ MTC_TransportMaster (std::string const &);
+ ~MTC_TransportMaster ();
+
+ void set_session (Session*);
+
+ void pre_process (pframes_t nframes, samplepos_t now, boost::optional<samplepos_t>);
+
+ bool speed_and_position (double&, samplepos_t&, samplepos_t);
+
+ bool locked() const;
+ bool ok() const;
+ void handle_locate (const MIDI::byte*);
+
+ samplecnt_t resolution () const;
+ bool requires_seekahead () const { return false; }
+ samplecnt_t seekahead_distance() const;
+ void init ();
+
+ Timecode::TimecodeFormat apparent_timecode_format() const;
+ std::string position_string() const;
+ std::string delta_string() const;
+
+ private:
+ PBD::ScopedConnectionList port_connections;
+ PBD::ScopedConnection config_connection;
+ bool can_notify_on_unknown_rate;
+
+ static const int sample_tolerance;
+
+ SafeTime current;
+ samplepos_t mtc_frame; /* current time */
+ double mtc_frame_dll;
+ samplepos_t last_inbound_frame; /* when we got it; audio clocked */
+ MIDI::byte last_mtc_fps_byte;
+ samplepos_t window_begin;
+ samplepos_t window_end;
+ samplepos_t first_mtc_timestamp;
+ bool did_reset_tc_format;
+ Timecode::TimecodeFormat saved_tc_format;
+ Glib::Threads::Mutex reset_lock;
+ uint32_t reset_pending;
+ bool reset_position;
+ int transport_direction;
+ int busy_guard1;
+ int busy_guard2;
+
+ double speedup_due_to_tc_mismatch;
+ double quarter_frame_duration;
+ Timecode::TimecodeFormat mtc_timecode;
+ Timecode::TimecodeFormat a3e_timecode;
+ Timecode::Time timecode;
+ bool printed_timecode_warning;
+
+ void reset (bool with_pos);
+ void queue_reset (bool with_pos);
+ void maybe_reset ();
+
+ void update_mtc_qtr (MIDI::Parser&, int, samplepos_t);
+ void update_mtc_time (const MIDI::byte *, bool, samplepos_t);
+ void update_mtc_status (MIDI::MTC_Status);
+ void read_current (SafeTime *) const;
+ void reset_window (samplepos_t);
+ bool outside_window (samplepos_t) const;
+ void init_mtc_dll(samplepos_t, double);
+ void parse_timecode_offset();
+ void parameter_changed(std::string const & p);
+};
+
+class LIBARDOUR_API LTC_TransportMaster : public TimecodeTransportMaster {
+public:
+ LTC_TransportMaster (std::string const &);
+ ~LTC_TransportMaster ();
+
+ void set_session (Session*);
+
+ void pre_process (pframes_t nframes, samplepos_t now, boost::optional<samplepos_t>);
+ bool speed_and_position (double&, samplepos_t&, samplepos_t);
+
+ bool locked() const;
+ bool ok() const;
+
+ samplecnt_t resolution () const;
+ bool requires_seekahead () const { return false; }
+ samplecnt_t seekahead_distance () const { return 0; }
+ void init ();
+
+ Timecode::TimecodeFormat apparent_timecode_format() const;
+ std::string position_string() const;
+ std::string delta_string() const;
+
+ private:
+ void parse_ltc(const pframes_t, const Sample* const, const samplecnt_t);
+ void process_ltc(samplepos_t const);
+ void init_dll (samplepos_t, int32_t);
+ bool detect_discontinuity(LTCFrameExt *, int, bool);
+ bool detect_ltc_fps(int, bool);
+ bool equal_ltc_sample_time(LTCFrame *a, LTCFrame *b);
+ void reset (bool with_ts = true);
+ void resync_xrun();
+ void resync_latency();
+ void parse_timecode_offset();
+ void parameter_changed(std::string const & p);
+
+ bool did_reset_tc_format;
+ Timecode::TimecodeFormat saved_tc_format;
+
+ LTCDecoder * decoder;
+ double samples_per_ltc_frame;
+ Timecode::Time timecode;
+ LTCFrameExt prev_sample;
+ bool fps_detected;
+
+ samplecnt_t monotonic_cnt;
+ samplecnt_t last_timestamp;
+ samplecnt_t last_ltc_sample;
+ double ltc_speed;
+ int delayedlocked;
+
+ int ltc_detect_fps_cnt;
+ int ltc_detect_fps_max;
+ bool printed_timecode_warning;
+ bool sync_lock_broken;
+ Timecode::TimecodeFormat ltc_timecode;
+ Timecode::TimecodeFormat a3e_timecode;
+ double samples_per_timecode_frame;
+
+ PBD::ScopedConnectionList port_connections;
+ PBD::ScopedConnection config_connection;
+ LatencyRange ltc_slave_latency;
+};
+
+class LIBARDOUR_API MIDIClock_TransportMaster : public TransportMaster, public TransportMasterViaMIDI {
+ public:
+ MIDIClock_TransportMaster (std::string const & name, int ppqn = 24);
+
+ /// Constructor for unit tests
+ ~MIDIClock_TransportMaster ();
+
+ void set_session (Session*);
+
+ void pre_process (pframes_t nframes, samplepos_t now, boost::optional<samplepos_t>);
+
+ void rebind (MidiPort&);
+ bool speed_and_position (double&, samplepos_t&, samplepos_t);
+
+ bool locked() const;
+ bool ok() const;
+ bool starting() const;
+
+ samplecnt_t resolution () const;
+ bool requires_seekahead () const { return false; }
+ void init ();
+
+ std::string position_string() const;
+ std::string delta_string() const;
+
+ float bpm() const { return _bpm; }
+
+ protected:
+ PBD::ScopedConnectionList port_connections;
+
+ /// pulses per quarter note for one MIDI clock sample (default 24)
+ int ppqn;
+
+ /// the duration of one ppqn in sample time
+ double one_ppqn_in_samples;
+
+ /// the timestamp of the first MIDI clock message
+ samplepos_t first_timestamp;
+
+ /// the time stamp and should-be transport position of the last inbound MIDI clock message
+ samplepos_t last_timestamp;
+ double should_be_position;
+
+ /// the number of midi clock messages received (zero-based)
+ /// since start
+ long midi_clock_count;
+
+ /// a DLL to track MIDI clock
+
+ double _speed;
+ bool _running;
+ double _bpm;
+
+ void reset ();
+ void start (MIDI::Parser& parser, samplepos_t timestamp);
+ void contineu (MIDI::Parser& parser, samplepos_t timestamp);
+ void stop (MIDI::Parser& parser, samplepos_t timestamp);
+ void position (MIDI::Parser& parser, MIDI::byte* message, size_t size);
+ // we can't use continue because it is a C++ keyword
+ void calculate_one_ppqn_in_samples_at(samplepos_t time);
+ samplepos_t calculate_song_position(uint16_t song_position_in_sixteenth_notes);
+ void calculate_filter_coefficients (double qpm);
+ void update_midi_clock (MIDI::Parser& parser, samplepos_t timestamp);
+ void read_current (SafeTime *) const;
+};
+
+class LIBARDOUR_API Engine_TransportMaster : public TransportMaster
+{
+ public:
+ Engine_TransportMaster (AudioEngine&);
+ ~Engine_TransportMaster ();
+
+ void pre_process (pframes_t nframes, samplepos_t now, boost::optional<samplepos_t>);
+ bool speed_and_position (double& speed, samplepos_t& pos, samplepos_t);
+
+ bool starting() const { return _starting; }
+ bool locked() const;
+ bool ok() const;
+ samplecnt_t resolution () const { return 1; }
+ bool requires_seekahead () const { return false; }
+ bool sample_clock_synced() const { return true; }
+ void init ();
+ void check_backend();
+ bool allow_request (TransportRequestSource, TransportRequestType) const;
+
+ std::string position_string() const;
+ std::string delta_string() const;
+
+ private:
+ AudioEngine& engine;
+ bool _starting;
+};
+
+} /* namespace */
+
+#endif /* __ardour_transport_master_h__ */
diff --git a/libs/ardour/ardour/transport_master_manager.h b/libs/ardour/ardour/transport_master_manager.h
new file mode 100644
index 0000000000..4c4159cb6f
--- /dev/null
+++ b/libs/ardour/ardour/transport_master_manager.h
@@ -0,0 +1,114 @@
+/*
+ * Copyright (C) 2018 Paul Davis (paul@linuxaudiosystems.com)
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#ifndef __ardour_transport_master_manager_h__
+#define __ardour_transport_master_manager_h__
+
+#include <string>
+
+#include <boost/noncopyable.hpp>
+
+#include "ardour/transport_master.h"
+#include "ardour/types.h"
+
+namespace ARDOUR {
+
+class UI_TransportMaster;
+
+class LIBARDOUR_API TransportMasterManager : public boost::noncopyable
+{
+ public:
+ ~TransportMasterManager ();
+
+ int init ();
+
+ static TransportMasterManager& instance();
+
+ typedef std::list<boost::shared_ptr<TransportMaster> > TransportMasters;
+
+ int add (SyncSource type, std::string const & name);
+ int remove (std::string const & name);
+ void clear ();
+
+ PBD::Signal1<void,boost::shared_ptr<TransportMaster> > Added;
+ PBD::Signal1<void,boost::shared_ptr<TransportMaster> > Removed; // null argument means "clear"
+
+ double pre_process_transport_masters (pframes_t, samplepos_t session_transport_position);
+
+ double get_current_speed_in_process_context() const { return _master_speed; }
+ samplepos_t get_current_position_in_process_context() const { return _master_position; }
+
+ boost::shared_ptr<TransportMaster> current() const { return _current_master; }
+ int set_current (boost::shared_ptr<TransportMaster>);
+ int set_current (SyncSource);
+ int set_current (std::string const &);
+
+ PBD::Signal2<void,boost::shared_ptr<TransportMaster>, boost::shared_ptr<TransportMaster> > CurrentChanged;
+
+ int set_state (XMLNode const &, int);
+ XMLNode& get_state();
+
+ void set_session (Session*);
+ Session* session() const { return _session; }
+
+ bool master_invalid_this_cycle() const { return _master_invalid_this_cycle; }
+
+ boost::shared_ptr<TransportMaster> master_by_type (SyncSource src) const;
+ boost::shared_ptr<TransportMaster> master_by_name (std::string const &) const;
+
+ TransportMasters const & transport_masters() const { return _transport_masters; }
+
+ static const std::string state_node_name;
+
+ private:
+ TransportMasterManager();
+
+ TransportMasters _transport_masters;
+ mutable Glib::Threads::RWLock lock;
+ double _master_speed;
+ samplepos_t _master_position;
+ boost::shared_ptr<TransportMaster> _current_master;
+ Session* _session;
+
+ bool _master_invalid_this_cycle;
+
+ // a DLL to chase the transport master
+
+ int transport_dll_initstate;
+ double t0; /// time at the beginning of ???
+ double t1; /// calculated end of the ???
+ double e2; /// second order loop error
+ double bandwidth; /// DLL filter bandwidth
+ double b, c, omega; /// DLL filter coefficients
+
+ void init_transport_master_dll (double speed, samplepos_t pos);
+ int master_dll_initstate;
+
+ static TransportMasterManager* _instance;
+
+ int add_locked (boost::shared_ptr<TransportMaster>);
+ double compute_matching_master_speed (pframes_t nframes, samplepos_t, bool& locate_required);
+ int set_current_locked (boost::shared_ptr<TransportMaster>);
+
+ PBD::ScopedConnection config_connection;
+ void parameter_changed (std::string const & what);
+};
+
+} // namespace ARDOUR
+
+#endif /* __ardour_transport_master_manager_h__ */
diff --git a/libs/ardour/ardour/types.h b/libs/ardour/ardour/types.h
index 366e303186..635b78334b 100644
--- a/libs/ardour/ardour/types.h
+++ b/libs/ardour/ardour/types.h
@@ -53,696 +53,712 @@ typedef int intptr_t;
namespace ARDOUR {
- class Source;
- class AudioSource;
- class Route;
- class Region;
- class Stripable;
- class VCA;
- class AutomationControl;
- class SlavableAutomationControl;
-
- typedef float Sample;
- typedef float pan_t;
- typedef float gain_t;
- typedef uint32_t layer_t;
- typedef uint64_t microseconds_t;
- typedef uint32_t pframes_t;
-
- /* rebind Temporal position types into ARDOUR namespace */
- typedef Temporal::samplecnt_t samplecnt_t;
- typedef Temporal::samplepos_t samplepos_t;
- typedef Temporal::sampleoffset_t sampleoffset_t;
-
- static const layer_t max_layer = UINT32_MAX;
-
- // a set of (time) intervals: first of pair is the offset of the start within the region, second is the offset of the end
- typedef std::list<std::pair<sampleoffset_t, sampleoffset_t> > AudioIntervalResult;
- // associate a set of intervals with regions (e.g. for silence detection)
- typedef std::map<boost::shared_ptr<ARDOUR::Region>,AudioIntervalResult> AudioIntervalMap;
-
- typedef std::list<boost::shared_ptr<Region> > RegionList;
-
- struct IOChange {
-
- enum Type {
- NoChange = 0,
- ConfigurationChanged = 0x1,
- ConnectionsChanged = 0x2
- } type;
-
- IOChange () : type (NoChange) {}
- IOChange (Type t) : type (t) {}
-
- /** channel count of IO before a ConfigurationChanged, if appropriate */
- ARDOUR::ChanCount before;
- /** channel count of IO after a ConfigurationChanged, if appropriate */
- ARDOUR::ChanCount after;
- };
-
- /* policies for inserting/pasting material where overlaps
- might be an issue.
- */
-
- enum InsertMergePolicy {
- InsertMergeReject, ///< no overlaps allowed
- InsertMergeRelax, ///< we just don't care about overlaps
- InsertMergeReplace, ///< replace old with new
- InsertMergeTruncateExisting, ///< shorten existing to avoid overlap
- InsertMergeTruncateAddition, ///< shorten new to avoid overlap
- InsertMergeExtend ///< extend new (or old) to the range of old+new
- };
-
- /** See evoral/Parameter.hpp
- *
- * When you add things here, you REALLY SHOULD add a case clause to
- * the constructor of ParameterDescriptor, unless the Controllables
- * that the enum refers to are completely standard (0-1.0 range, 0.0 as
- * normal, non-toggled, non-enumerated). Anything else needs to be
- * added there so that things that try to represent them can do so
- * with as much information as possible.
- */
- enum AutomationType {
- NullAutomation,
- GainAutomation,
- PanAzimuthAutomation,
- PanElevationAutomation,
- PanWidthAutomation,
- PanFrontBackAutomation,
- PanLFEAutomation,
- PluginAutomation,
- PluginPropertyAutomation,
- SoloAutomation,
- SoloIsolateAutomation,
- SoloSafeAutomation,
- MuteAutomation,
- MidiCCAutomation,
- MidiPgmChangeAutomation,
- MidiPitchBenderAutomation,
- MidiChannelPressureAutomation,
- MidiNotePressureAutomation,
- MidiSystemExclusiveAutomation,
- FadeInAutomation,
- FadeOutAutomation,
- EnvelopeAutomation,
- RecEnableAutomation,
- RecSafeAutomation,
- TrimAutomation,
- PhaseAutomation,
- MonitoringAutomation,
- BusSendLevel,
- BusSendEnable,
-
- /* used only by Controllable Descriptor to access send parameters */
-
- SendLevelAutomation,
- SendEnableAutomation,
- SendAzimuthAutomation,
- };
-
- enum AutoState {
- Off = 0x00,
- Write = 0x01,
- Touch = 0x02,
- Play = 0x04,
- Latch = 0x08
- };
-
- std::string auto_state_to_string (AutoState);
- AutoState string_to_auto_state (std::string);
-
- enum AlignStyle {
- CaptureTime,
- ExistingMaterial
- };
-
- enum AlignChoice {
- UseCaptureTime,
- UseExistingMaterial,
- Automatic
- };
-
- enum MeterPoint {
- MeterInput,
- MeterPreFader,
- MeterPostFader,
- MeterOutput,
- MeterCustom
- };
-
- enum DiskIOPoint {
- DiskIOPreFader, /* after the trim control, but before other processors */
- DiskIOPostFader, /* before the main outs, after other processors */
- DiskIOCustom, /* up to the user. Caveat Emptor! */
- };
-
- enum MeterType {
- MeterMaxSignal = 0x0001,
- MeterMaxPeak = 0x0002,
- MeterPeak = 0x0004,
- MeterKrms = 0x0008,
- MeterK20 = 0x0010,
- MeterK14 = 0x0020,
- MeterIEC1DIN = 0x0040,
- MeterIEC1NOR = 0x0080,
- MeterIEC2BBC = 0x0100,
- MeterIEC2EBU = 0x0200,
- MeterVU = 0x0400,
- MeterK12 = 0x0800,
- MeterPeak0dB = 0x1000,
- MeterMCP = 0x2000
- };
-
- enum TrackMode {
- Normal,
- NonLayered,
- Destructive
- };
-
- enum NoteMode {
- Sustained,
- Percussive
- };
-
- enum ChannelMode {
- AllChannels = 0, ///< Pass through all channel information unmodified
- FilterChannels, ///< Ignore events on certain channels
- ForceChannel ///< Force all events to a certain channel
- };
-
- enum ColorMode {
- MeterColors = 0,
- ChannelColors,
- TrackColor
- };
-
- enum RoundMode {
- RoundDownMaybe = -2, ///< Round down only if necessary
- RoundDownAlways = -1, ///< Always round down, even if on a division
- RoundNearest = 0, ///< Round to nearest
- RoundUpAlways = 1, ///< Always round up, even if on a division
- RoundUpMaybe = 2 ///< Round up only if necessary
- };
-
- enum SnapPref {
- SnapToAny_Visual = 0, /**< Snap to the editor's visual snap
- * (incoprorating snap prefs and the current zoom scaling)
- * this defines the behavior for visual mouse drags, for example */
-
- SnapToGrid_Scaled = 1, /**< Snap to the selected grid quantization with visual scaling.
- * Ignores other snap preferences (markers, regions, etc)
- * this defines the behavior for nudging the playhead to next/prev grid, for example */
-
- SnapToGrid_Unscaled = 2, /**< Snap to the selected grid quantization.
- * If one is selected, and ignore any visual scaling
- * this is the behavior for automated processes like "snap regions to grid"
- * but note that midi quantization uses its own mechanism, not the grid */
- };
-
- class AnyTime {
- public:
- enum Type {
- Timecode,
- BBT,
- Samples,
- Seconds
- };
-
- Type type;
-
- Timecode::Time timecode;
- Timecode::BBT_Time bbt;
-
- union {
- samplecnt_t samples;
- double seconds;
- };
-
- AnyTime() { type = Samples; samples = 0; }
-
- bool operator== (AnyTime const & other) const {
- if (type != other.type) { return false; }
-
- switch (type) {
- case Timecode:
- return timecode == other.timecode;
- case BBT:
- return bbt == other.bbt;
- case Samples:
- return samples == other.samples;
- case Seconds:
- return seconds == other.seconds;
- }
- return false; // get rid of warning
- }
-
- bool not_zero() const
- {
- switch (type) {
- case Timecode:
- return timecode.hours != 0 || timecode.minutes != 0 ||
- timecode.seconds != 0 || timecode.frames != 0;
- case BBT:
- return bbt.bars != 0 || bbt.beats != 0 || bbt.ticks != 0;
- case Samples:
- return samples != 0;
- case Seconds:
- return seconds != 0;
- }
-
- abort(); /* NOTREACHED */
- return false;
- }
- };
-
- /* used for translating audio samples to an exact musical position using a note divisor.
- an exact musical position almost never falls exactly on an audio sample, but for sub-sample
- musical accuracy we need to derive exact musical locations from a sample position
- the division follows TempoMap::exact_beat_at_sample().
- division
- -1 musical location is the bar closest to sample
- 0 musical location is the musical position of the sample
- 1 musical location is the BBT beat closest to sample
- n musical location is the quarter-note division n closest to sample
- */
- struct MusicSample {
- samplepos_t sample;
- int32_t division;
-
- MusicSample (samplepos_t f, int32_t d) : sample (f), division (d) {}
-
- void set (samplepos_t f, int32_t d) {sample = f; division = d; }
-
- MusicSample operator- (MusicSample other) { return MusicSample (sample - other.sample, 0); }
- };
-
- /* XXX: slightly unfortunate that there is this and Evoral::Range<>,
- but this has a uint32_t id which Evoral::Range<> does not.
- */
- struct AudioRange {
- samplepos_t start;
- samplepos_t end;
- uint32_t id;
-
- AudioRange (samplepos_t s, samplepos_t e, uint32_t i) : start (s), end (e) , id (i) {}
-
- samplecnt_t length() const { return end - start + 1; }
-
- bool operator== (const AudioRange& other) const {
- return start == other.start && end == other.end && id == other.id;
- }
-
- bool equal (const AudioRange& other) const {
- return start == other.start && end == other.end;
- }
+class Source;
+class AudioSource;
+class Route;
+class Region;
+class Stripable;
+class VCA;
+class AutomationControl;
+class SlavableAutomationControl;
+
+typedef float Sample;
+typedef float pan_t;
+typedef float gain_t;
+typedef uint32_t layer_t;
+typedef uint64_t microseconds_t;
+typedef uint32_t pframes_t;
+
+/* rebind Temporal position types into ARDOUR namespace */
+typedef Temporal::samplecnt_t samplecnt_t;
+typedef Temporal::samplepos_t samplepos_t;
+typedef Temporal::sampleoffset_t sampleoffset_t;
+
+static const layer_t max_layer = UINT32_MAX;
+
+// a set of (time) intervals: first of pair is the offset of the start within the region, second is the offset of the end
+typedef std::list<std::pair<sampleoffset_t, sampleoffset_t> > AudioIntervalResult;
+// associate a set of intervals with regions (e.g. for silence detection)
+typedef std::map<boost::shared_ptr<ARDOUR::Region>,AudioIntervalResult> AudioIntervalMap;
+
+typedef std::list<boost::shared_ptr<Region> > RegionList;
+
+struct IOChange {
+
+ enum Type {
+ NoChange = 0,
+ ConfigurationChanged = 0x1,
+ ConnectionsChanged = 0x2
+ } type;
+
+ IOChange () : type (NoChange) {}
+ IOChange (Type t) : type (t) {}
+
+ /** channel count of IO before a ConfigurationChanged, if appropriate */
+ ARDOUR::ChanCount before;
+ /** channel count of IO after a ConfigurationChanged, if appropriate */
+ ARDOUR::ChanCount after;
+};
+
+/* policies for inserting/pasting material where overlaps
+ might be an issue.
+*/
- Evoral::OverlapType coverage (samplepos_t s, samplepos_t e) const {
- return Evoral::coverage (start, end, s, e);
+enum InsertMergePolicy {
+ InsertMergeReject, ///< no overlaps allowed
+ InsertMergeRelax, ///< we just don't care about overlaps
+ InsertMergeReplace, ///< replace old with new
+ InsertMergeTruncateExisting, ///< shorten existing to avoid overlap
+ InsertMergeTruncateAddition, ///< shorten new to avoid overlap
+ InsertMergeExtend ///< extend new (or old) to the range of old+new
+};
+
+/** See evoral/Parameter.hpp
+ *
+ * When you add things here, you REALLY SHOULD add a case clause to
+ * the constructor of ParameterDescriptor, unless the Controllables
+ * that the enum refers to are completely standard (0-1.0 range, 0.0 as
+ * normal, non-toggled, non-enumerated). Anything else needs to be
+ * added there so that things that try to represent them can do so
+ * with as much information as possible.
+ */
+enum AutomationType {
+ NullAutomation,
+ GainAutomation,
+ PanAzimuthAutomation,
+ PanElevationAutomation,
+ PanWidthAutomation,
+ PanFrontBackAutomation,
+ PanLFEAutomation,
+ PluginAutomation,
+ PluginPropertyAutomation,
+ SoloAutomation,
+ SoloIsolateAutomation,
+ SoloSafeAutomation,
+ MuteAutomation,
+ MidiCCAutomation,
+ MidiPgmChangeAutomation,
+ MidiPitchBenderAutomation,
+ MidiChannelPressureAutomation,
+ MidiNotePressureAutomation,
+ MidiSystemExclusiveAutomation,
+ FadeInAutomation,
+ FadeOutAutomation,
+ EnvelopeAutomation,
+ RecEnableAutomation,
+ RecSafeAutomation,
+ TrimAutomation,
+ PhaseAutomation,
+ MonitoringAutomation,
+ BusSendLevel,
+ BusSendEnable,
+
+ /* used only by Controllable Descriptor to access send parameters */
+
+ SendLevelAutomation,
+ SendEnableAutomation,
+ SendAzimuthAutomation,
+};
+
+enum AutoState {
+ Off = 0x00,
+ Write = 0x01,
+ Touch = 0x02,
+ Play = 0x04,
+ Latch = 0x08
+};
+
+std::string auto_state_to_string (AutoState);
+AutoState string_to_auto_state (std::string);
+
+enum AlignStyle {
+ CaptureTime,
+ ExistingMaterial
+};
+
+enum AlignChoice {
+ UseCaptureTime,
+ UseExistingMaterial,
+ Automatic
+};
+
+enum MeterPoint {
+ MeterInput,
+ MeterPreFader,
+ MeterPostFader,
+ MeterOutput,
+ MeterCustom
+};
+
+enum DiskIOPoint {
+ DiskIOPreFader, /* after the trim control, but before other processors */
+ DiskIOPostFader, /* before the main outs, after other processors */
+ DiskIOCustom, /* up to the user. Caveat Emptor! */
+};
+
+enum MeterType {
+ MeterMaxSignal = 0x0001,
+ MeterMaxPeak = 0x0002,
+ MeterPeak = 0x0004,
+ MeterKrms = 0x0008,
+ MeterK20 = 0x0010,
+ MeterK14 = 0x0020,
+ MeterIEC1DIN = 0x0040,
+ MeterIEC1NOR = 0x0080,
+ MeterIEC2BBC = 0x0100,
+ MeterIEC2EBU = 0x0200,
+ MeterVU = 0x0400,
+ MeterK12 = 0x0800,
+ MeterPeak0dB = 0x1000,
+ MeterMCP = 0x2000
+};
+
+enum TrackMode {
+ Normal,
+ NonLayered,
+ Destructive
+};
+
+enum NoteMode {
+ Sustained,
+ Percussive
+};
+
+enum ChannelMode {
+ AllChannels = 0, ///< Pass through all channel information unmodified
+ FilterChannels, ///< Ignore events on certain channels
+ ForceChannel ///< Force all events to a certain channel
+};
+
+enum ColorMode {
+ MeterColors = 0,
+ ChannelColors,
+ TrackColor
+};
+
+enum RoundMode {
+ RoundDownMaybe = -2, ///< Round down only if necessary
+ RoundDownAlways = -1, ///< Always round down, even if on a division
+ RoundNearest = 0, ///< Round to nearest
+ RoundUpAlways = 1, ///< Always round up, even if on a division
+ RoundUpMaybe = 2 ///< Round up only if necessary
+};
+
+enum SnapPref {
+ SnapToAny_Visual = 0, /**< Snap to the editor's visual snap
+ * (incoprorating snap prefs and the current zoom scaling)
+ * this defines the behavior for visual mouse drags, for example */
+
+ SnapToGrid_Scaled = 1, /**< Snap to the selected grid quantization with visual scaling.
+ * Ignores other snap preferences (markers, regions, etc)
+ * this defines the behavior for nudging the playhead to next/prev grid, for example */
+
+ SnapToGrid_Unscaled = 2, /**< Snap to the selected grid quantization.
+ * If one is selected, and ignore any visual scaling
+ * this is the behavior for automated processes like "snap regions to grid"
+ * but note that midi quantization uses its own mechanism, not the grid */
+};
+
+class AnyTime {
+ public:
+ enum Type {
+ Timecode,
+ BBT,
+ Samples,
+ Seconds
+ };
+
+ Type type;
+
+ Timecode::Time timecode;
+ Timecode::BBT_Time bbt;
+
+ union {
+ samplecnt_t samples;
+ double seconds;
+ };
+
+ AnyTime() { type = Samples; samples = 0; }
+
+ bool operator== (AnyTime const & other) const {
+ if (type != other.type) { return false; }
+
+ switch (type) {
+ case Timecode:
+ return timecode == other.timecode;
+ case BBT:
+ return bbt == other.bbt;
+ case Samples:
+ return samples == other.samples;
+ case Seconds:
+ return seconds == other.seconds;
}
- };
-
- struct MusicRange {
- Timecode::BBT_Time start;
- Timecode::BBT_Time end;
- uint32_t id;
-
- MusicRange (Timecode::BBT_Time& s, Timecode::BBT_Time& e, uint32_t i)
- : start (s), end (e), id (i) {}
-
- bool operator== (const MusicRange& other) const {
- return start == other.start && end == other.end && id == other.id;
+ return false; // get rid of warning
+ }
+
+ bool not_zero() const
+ {
+ switch (type) {
+ case Timecode:
+ return timecode.hours != 0 || timecode.minutes != 0 ||
+ timecode.seconds != 0 || timecode.frames != 0;
+ case BBT:
+ return bbt.bars != 0 || bbt.beats != 0 || bbt.ticks != 0;
+ case Samples:
+ return samples != 0;
+ case Seconds:
+ return seconds != 0;
}
- bool equal (const MusicRange& other) const {
- return start == other.start && end == other.end;
- }
- };
-
- /*
- Slowest = 6.6dB/sec falloff at update rate of 40ms
- Slow = 6.8dB/sec falloff at update rate of 40ms
- */
-
- enum MeterFalloff {
- MeterFalloffOff = 0,
- MeterFalloffSlowest = 1,
- MeterFalloffSlow = 2,
- MeterFalloffSlowish = 3,
- MeterFalloffModerate = 4,
- MeterFalloffMedium = 5,
- MeterFalloffFast = 6,
- MeterFalloffFaster = 7,
- MeterFalloffFastest = 8,
- };
-
- enum MeterHold {
- MeterHoldOff = 0,
- MeterHoldShort = 40,
- MeterHoldMedium = 100,
- MeterHoldLong = 200
- };
-
- enum EditMode {
- Slide,
- Splice,
- Ripple,
- Lock
- };
-
- enum RegionSelectionAfterSplit {
- None = 0,
- NewlyCreatedLeft = 1, // bit 0
- NewlyCreatedRight = 2, // bit 1
- NewlyCreatedBoth = 3,
- Existing = 4, // bit 2
- ExistingNewlyCreatedLeft = 5,
- ExistingNewlyCreatedRight = 6,
- ExistingNewlyCreatedBoth = 7
- };
-
- enum RegionPoint {
- Start,
- End,
- SyncPoint
- };
-
- enum Placement {
- PreFader,
- PostFader
- };
-
- enum MonitorModel {
- HardwareMonitoring, ///< JACK does monitoring
- SoftwareMonitoring, ///< Ardour does monitoring
- ExternalMonitoring ///< we leave monitoring to the audio hardware
- };
-
- enum MonitorChoice {
- MonitorAuto = 0,
- MonitorInput = 0x1,
- MonitorDisk = 0x2,
- MonitorCue = 0x3,
- };
-
- enum MonitorState {
- MonitoringSilence = 0x1,
- MonitoringInput = 0x2,
- MonitoringDisk = 0x4,
- MonitoringCue = 0x6,
- };
-
- enum MeterState {
- MeteringInput, ///< meter the input IO, regardless of what is going through the route
- MeteringRoute ///< meter what is going through the route
- };
-
- enum VUMeterStandard {
- MeteringVUfrench, // 0VU = -2dBu
- MeteringVUamerican, // 0VU = 0dBu
- MeteringVUstandard, // 0VU = +4dBu
- MeteringVUeight // 0VU = +8dBu
- };
-
- enum MeterLineUp {
- MeteringLineUp24,
- MeteringLineUp20,
- MeteringLineUp18,
- MeteringLineUp15
- };
-
- enum PFLPosition {
- /** PFL signals come from before pre-fader processors */
- PFLFromBeforeProcessors,
- /** PFL signals come pre-fader but after pre-fader processors */
- PFLFromAfterProcessors
- };
-
- enum AFLPosition {
- /** AFL signals come post-fader and before post-fader processors */
- AFLFromBeforeProcessors,
- /** AFL signals come post-fader but after post-fader processors */
- AFLFromAfterProcessors
- };
-
- enum ClockDeltaMode {
- NoDelta,
- DeltaEditPoint,
- DeltaOriginMarker
- };
-
- enum DenormalModel {
- DenormalNone,
- DenormalFTZ,
- DenormalDAZ,
- DenormalFTZDAZ
- };
-
- enum LayerModel {
- LaterHigher,
- Manual
- };
-
- enum ListenPosition {
- AfterFaderListen,
- PreFaderListen
- };
-
- enum AutoConnectOption {
- ManualConnect = 0x0,
- AutoConnectPhysical = 0x1,
- AutoConnectMaster = 0x2
- };
-
- enum TracksAutoNamingRule {
- UseDefaultNames = 0x1,
- NameAfterDriver = 0x2
- };
-
- enum SampleFormat {
- FormatFloat = 0,
- FormatInt24,
- FormatInt16
- };
-
- int format_data_width (ARDOUR::SampleFormat);
-
- enum CDMarkerFormat {
- CDMarkerNone,
- CDMarkerCUE,
- CDMarkerTOC,
- MP4Chaps
- };
-
- enum HeaderFormat {
- BWF,
- WAVE,
- WAVE64,
- CAF,
- AIFF,
- iXML,
- RF64,
- RF64_WAV,
- MBWF,
- };
+ abort(); /* NOTREACHED */
+ return false;
+ }
+};
+
+/* used for translating audio samples to an exact musical position using a note divisor.
+ an exact musical position almost never falls exactly on an audio sample, but for sub-sample
+ musical accuracy we need to derive exact musical locations from a sample position
+ the division follows TempoMap::exact_beat_at_sample().
+ division
+ -1 musical location is the bar closest to sample
+ 0 musical location is the musical position of the sample
+ 1 musical location is the BBT beat closest to sample
+ n musical location is the quarter-note division n closest to sample
+*/
+struct MusicSample {
+ samplepos_t sample;
+ int32_t division;
- struct PeakData {
- typedef Sample PeakDatum;
+ MusicSample (samplepos_t f, int32_t d) : sample (f), division (d) {}
- PeakDatum min;
- PeakDatum max;
- };
+ void set (samplepos_t f, int32_t d) {sample = f; division = d; }
- enum RunContext {
- ButlerContext = 0,
- TransportContext,
- ExportContext
- };
+ MusicSample operator- (MusicSample other) { return MusicSample (sample - other.sample, 0); }
+};
- enum SyncSource {
- /* These are "synonyms". It is important for JACK to be first
- both here and in enums.cc, so that the string "JACK" is
- correctly recognized in older session and preference files.
- */
- JACK = 0,
- Engine = 0,
- MTC,
- MIDIClock,
- LTC
- };
-
- enum ShuttleBehaviour {
- Sprung,
- Wheel
- };
-
- enum ShuttleUnits {
- Percentage,
- Semitones
- };
+/* XXX: slightly unfortunate that there is this and Evoral::Range<>,
+ but this has a uint32_t id which Evoral::Range<> does not.
+*/
+struct AudioRange {
+ samplepos_t start;
+ samplepos_t end;
+ uint32_t id;
- typedef std::vector<boost::shared_ptr<Source> > SourceList;
+ AudioRange (samplepos_t s, samplepos_t e, uint32_t i) : start (s), end (e) , id (i) {}
- enum SrcQuality {
- SrcBest,
- SrcGood,
- SrcQuick,
- SrcFast,
- SrcFastest
- };
+ samplecnt_t length() const { return end - start + 1; }
- typedef std::list<samplepos_t> AnalysisFeatureList;
+ bool operator== (const AudioRange& other) const {
+ return start == other.start && end == other.end && id == other.id;
+ }
- typedef std::list<boost::shared_ptr<Route> > RouteList;
- typedef std::list<boost::shared_ptr<Stripable> > StripableList;
- typedef std::list<boost::weak_ptr <Route> > WeakRouteList;
- typedef std::list<boost::weak_ptr <Stripable> > WeakStripableList;
- typedef std::list<boost::shared_ptr<AutomationControl> > ControlList;
- typedef std::list<boost::shared_ptr<SlavableAutomationControl> > SlavableControlList;
- typedef std::set <boost::shared_ptr<AutomationControl> > AutomationControlSet;
+ bool equal (const AudioRange& other) const {
+ return start == other.start && end == other.end;
+ }
- typedef std::list<boost::shared_ptr<VCA> > VCAList;
+ Evoral::OverlapType coverage (samplepos_t s, samplepos_t e) const {
+ return Evoral::coverage (start, end, s, e);
+ }
+};
- class Bundle;
- typedef std::vector<boost::shared_ptr<Bundle> > BundleList;
+struct MusicRange {
+ Timecode::BBT_Time start;
+ Timecode::BBT_Time end;
+ uint32_t id;
- enum RegionEquivalence {
- Exact,
- Enclosed,
- Overlap
- };
-
- enum WaveformScale {
- Linear,
- Logarithmic
- };
+ MusicRange (Timecode::BBT_Time& s, Timecode::BBT_Time& e, uint32_t i)
+ : start (s), end (e), id (i) {}
- enum WaveformShape {
- Traditional,
- Rectified
- };
+ bool operator== (const MusicRange& other) const {
+ return start == other.start && end == other.end && id == other.id;
+ }
- struct CleanupReport {
- std::vector<std::string> paths;
- size_t space;
- };
+ bool equal (const MusicRange& other) const {
+ return start == other.start && end == other.end;
+ }
+};
- enum PositionLockStyle {
- AudioTime,
- MusicTime
- };
+/*
+ Slowest = 6.6dB/sec falloff at update rate of 40ms
+ Slow = 6.8dB/sec falloff at update rate of 40ms
+*/
- /** A struct used to describe changes to processors in a route.
- * This is useful because objects that respond to a change in processors
- * can optimise what work they do based on details of what has changed.
+enum MeterFalloff {
+ MeterFalloffOff = 0,
+ MeterFalloffSlowest = 1,
+ MeterFalloffSlow = 2,
+ MeterFalloffSlowish = 3,
+ MeterFalloffModerate = 4,
+ MeterFalloffMedium = 5,
+ MeterFalloffFast = 6,
+ MeterFalloffFaster = 7,
+ MeterFalloffFastest = 8,
+};
+
+enum MeterHold {
+ MeterHoldOff = 0,
+ MeterHoldShort = 40,
+ MeterHoldMedium = 100,
+ MeterHoldLong = 200
+};
+
+enum EditMode {
+ Slide,
+ Splice,
+ Ripple,
+ Lock
+};
+
+enum RegionSelectionAfterSplit {
+ None = 0,
+ NewlyCreatedLeft = 1, // bit 0
+ NewlyCreatedRight = 2, // bit 1
+ NewlyCreatedBoth = 3,
+ Existing = 4, // bit 2
+ ExistingNewlyCreatedLeft = 5,
+ ExistingNewlyCreatedRight = 6,
+ ExistingNewlyCreatedBoth = 7
+};
+
+enum RegionPoint {
+ Start,
+ End,
+ SyncPoint
+};
+
+enum Placement {
+ PreFader,
+ PostFader
+};
+
+enum MonitorModel {
+ HardwareMonitoring, ///< JACK does monitoring
+ SoftwareMonitoring, ///< Ardour does monitoring
+ ExternalMonitoring ///< we leave monitoring to the audio hardware
+};
+
+enum MonitorChoice {
+ MonitorAuto = 0,
+ MonitorInput = 0x1,
+ MonitorDisk = 0x2,
+ MonitorCue = 0x3,
+};
+
+enum MonitorState {
+ MonitoringSilence = 0x1,
+ MonitoringInput = 0x2,
+ MonitoringDisk = 0x4,
+ MonitoringCue = 0x6,
+};
+
+enum MeterState {
+ MeteringInput, ///< meter the input IO, regardless of what is going through the route
+ MeteringRoute ///< meter what is going through the route
+};
+
+enum VUMeterStandard {
+ MeteringVUfrench, // 0VU = -2dBu
+ MeteringVUamerican, // 0VU = 0dBu
+ MeteringVUstandard, // 0VU = +4dBu
+ MeteringVUeight // 0VU = +8dBu
+};
+
+enum MeterLineUp {
+ MeteringLineUp24,
+ MeteringLineUp20,
+ MeteringLineUp18,
+ MeteringLineUp15
+};
+
+enum PFLPosition {
+ /** PFL signals come from before pre-fader processors */
+ PFLFromBeforeProcessors,
+ /** PFL signals come pre-fader but after pre-fader processors */
+ PFLFromAfterProcessors
+};
+
+enum AFLPosition {
+ /** AFL signals come post-fader and before post-fader processors */
+ AFLFromBeforeProcessors,
+ /** AFL signals come post-fader but after post-fader processors */
+ AFLFromAfterProcessors
+};
+
+enum ClockDeltaMode {
+ NoDelta,
+ DeltaEditPoint,
+ DeltaOriginMarker
+};
+
+enum DenormalModel {
+ DenormalNone,
+ DenormalFTZ,
+ DenormalDAZ,
+ DenormalFTZDAZ
+};
+
+enum LayerModel {
+ LaterHigher,
+ Manual
+};
+
+enum ListenPosition {
+ AfterFaderListen,
+ PreFaderListen
+};
+
+enum AutoConnectOption {
+ ManualConnect = 0x0,
+ AutoConnectPhysical = 0x1,
+ AutoConnectMaster = 0x2
+};
+
+enum TracksAutoNamingRule {
+ UseDefaultNames = 0x1,
+ NameAfterDriver = 0x2
+};
+
+enum SampleFormat {
+ FormatFloat = 0,
+ FormatInt24,
+ FormatInt16
+};
+
+int format_data_width (ARDOUR::SampleFormat);
+
+enum CDMarkerFormat {
+ CDMarkerNone,
+ CDMarkerCUE,
+ CDMarkerTOC,
+ MP4Chaps
+};
+
+enum HeaderFormat {
+ BWF,
+ WAVE,
+ WAVE64,
+ CAF,
+ AIFF,
+ iXML,
+ RF64,
+ RF64_WAV,
+ MBWF,
+};
+
+struct PeakData {
+ typedef Sample PeakDatum;
+
+ PeakDatum min;
+ PeakDatum max;
+};
+
+enum RunContext {
+ ButlerContext = 0,
+ TransportContext,
+ ExportContext
+};
+
+enum SyncSource {
+ /* The first two are "synonyms". It is important for JACK to be first
+ both here and in enums.cc, so that the string "JACK" is
+ correctly recognized in older session and preference files.
*/
- struct RouteProcessorChange {
- enum Type {
- GeneralChange = 0x0,
- MeterPointChange = 0x1,
- RealTimeChange = 0x2
- };
-
- RouteProcessorChange () : type (GeneralChange), meter_visibly_changed (true)
- {}
-
- RouteProcessorChange (Type t) : type (t), meter_visibly_changed (true)
- {}
-
- RouteProcessorChange (Type t, bool m) : type (t), meter_visibly_changed (m)
- {}
-
- /** type of change; "GeneralChange" means anything could have changed */
- Type type;
- /** true if, when a MeterPointChange has occurred, the change is visible to the user */
- bool meter_visibly_changed;
- };
-
- struct BusProfile {
- uint32_t master_out_channels; /* how many channels for the master bus, 0: no master bus */
- };
-
- enum FadeShape {
- FadeLinear,
- FadeFast,
- FadeSlow,
- FadeConstantPower,
- FadeSymmetric,
- };
-
- enum TransportState {
- /* these values happen to match the constants used by JACK but
- this equality cannot be assumed.
- */
- TransportStopped = 0,
- TransportRolling = 1,
- TransportLooping = 2,
- TransportStarting = 3,
- };
-
- enum PortFlags {
- /* these values happen to match the constants used by JACK but
- this equality cannot be assumed.
- */
- IsInput = 0x1,
- IsOutput = 0x2,
- IsPhysical = 0x4,
- CanMonitor = 0x8,
- IsTerminal = 0x10,
-
- /* non-JACK related flags */
- Hidden = 0x20,
- Shadow = 0x40
- };
-
- enum MidiPortFlags {
- MidiPortMusic = 0x1,
- MidiPortControl = 0x2,
- MidiPortSelection = 0x4,
- MidiPortVirtual = 0x8
- };
-
- struct LatencyRange {
- uint32_t min; //< samples
- uint32_t max; //< samples
- };
-
- enum BufferingPreset {
- Small,
- Medium,
- Large,
- Custom,
- };
-
- enum AutoReturnTarget {
- LastLocate = 0x1,
- RangeSelectionStart = 0x2,
- Loop = 0x4,
- RegionSelectionStart = 0x8,
- };
-
- enum PlaylistDisposition {
- CopyPlaylist,
- NewPlaylist,
- SharePlaylist
- };
-
- enum MidiTrackNameSource {
- SMFTrackNumber,
- SMFTrackName,
- SMFInstrumentName
- };
-
- enum MidiTempoMapDisposition {
- SMFTempoIgnore,
- SMFTempoUse,
- };
-
- struct CaptureInfo {
- samplepos_t start;
- samplecnt_t samples;
- };
-
- typedef std::vector<CaptureInfo*> CaptureInfos;
+ JACK = 0,
+ Engine = 0,
+ MTC,
+ MIDIClock,
+ LTC,
+};
+
+enum TransportRequestSource {
+ TRS_Engine,
+ TRS_MTC,
+ TRS_MIDIClock,
+ TRS_LTC,
+ TRS_MMC,
+ TRS_UI,
+};
+
+enum TransportRequestType {
+ TR_Stop = 0x1,
+ TR_Start = 0x2,
+ TR_Speed = 0x4,
+ TR_Locate = 0x8
+};
+
+enum ShuttleBehaviour {
+ Sprung,
+ Wheel
+};
+
+enum ShuttleUnits {
+ Percentage,
+ Semitones
+};
+
+typedef std::vector<boost::shared_ptr<Source> > SourceList;
+
+enum SrcQuality {
+ SrcBest,
+ SrcGood,
+ SrcQuick,
+ SrcFast,
+ SrcFastest
+};
+
+typedef std::list<samplepos_t> AnalysisFeatureList;
+
+typedef std::list<boost::shared_ptr<Route> > RouteList;
+typedef std::list<boost::shared_ptr<Stripable> > StripableList;
+typedef std::list<boost::weak_ptr <Route> > WeakRouteList;
+typedef std::list<boost::weak_ptr <Stripable> > WeakStripableList;
+typedef std::list<boost::shared_ptr<AutomationControl> > ControlList;
+typedef std::list<boost::shared_ptr<SlavableAutomationControl> > SlavableControlList;
+typedef std::set <boost::shared_ptr<AutomationControl> > AutomationControlSet;
+
+typedef std::list<boost::shared_ptr<VCA> > VCAList;
+
+class Bundle;
+typedef std::vector<boost::shared_ptr<Bundle> > BundleList;
+
+enum RegionEquivalence {
+ Exact,
+ Enclosed,
+ Overlap
+};
+
+enum WaveformScale {
+ Linear,
+ Logarithmic
+};
+
+enum WaveformShape {
+ Traditional,
+ Rectified
+};
+
+struct CleanupReport {
+ std::vector<std::string> paths;
+ size_t space;
+};
+
+enum PositionLockStyle {
+ AudioTime,
+ MusicTime
+};
+
+/** A struct used to describe changes to processors in a route.
+ * This is useful because objects that respond to a change in processors
+ * can optimise what work they do based on details of what has changed.
+ */
+struct RouteProcessorChange {
+ enum Type {
+ GeneralChange = 0x0,
+ MeterPointChange = 0x1,
+ RealTimeChange = 0x2
+ };
+
+ RouteProcessorChange () : type (GeneralChange), meter_visibly_changed (true)
+ {}
+
+ RouteProcessorChange (Type t) : type (t), meter_visibly_changed (true)
+ {}
+
+ RouteProcessorChange (Type t, bool m) : type (t), meter_visibly_changed (m)
+ {}
+
+ /** type of change; "GeneralChange" means anything could have changed */
+ Type type;
+ /** true if, when a MeterPointChange has occurred, the change is visible to the user */
+ bool meter_visibly_changed;
+};
+
+struct BusProfile {
+ uint32_t master_out_channels; /* how many channels for the master bus, 0: no master bus */
+};
+
+enum FadeShape {
+ FadeLinear,
+ FadeFast,
+ FadeSlow,
+ FadeConstantPower,
+ FadeSymmetric,
+};
+
+enum TransportState {
+ /* these values happen to match the constants used by JACK but
+ this equality cannot be assumed.
+ */
+ TransportStopped = 0,
+ TransportRolling = 1,
+ TransportLooping = 2,
+ TransportStarting = 3,
+};
+
+enum PortFlags {
+ /* these values happen to match the constants used by JACK but
+ this equality cannot be assumed.
+ */
+ IsInput = 0x1,
+ IsOutput = 0x2,
+ IsPhysical = 0x4,
+ CanMonitor = 0x8,
+ IsTerminal = 0x10,
+
+ /* non-JACK related flags */
+ Hidden = 0x20,
+ Shadow = 0x40
+};
+
+enum MidiPortFlags {
+ MidiPortMusic = 0x1,
+ MidiPortControl = 0x2,
+ MidiPortSelection = 0x4,
+ MidiPortVirtual = 0x8
+};
+
+struct LatencyRange {
+ uint32_t min; //< samples
+ uint32_t max; //< samples
+};
+
+enum BufferingPreset {
+ Small,
+ Medium,
+ Large,
+ Custom,
+};
+
+enum AutoReturnTarget {
+ LastLocate = 0x1,
+ RangeSelectionStart = 0x2,
+ Loop = 0x4,
+ RegionSelectionStart = 0x8,
+};
+
+enum PlaylistDisposition {
+ CopyPlaylist,
+ NewPlaylist,
+ SharePlaylist
+};
+
+enum MidiTrackNameSource {
+ SMFTrackNumber,
+ SMFTrackName,
+ SMFInstrumentName
+};
+
+enum MidiTempoMapDisposition {
+ SMFTempoIgnore,
+ SMFTempoUse,
+};
+
+struct CaptureInfo {
+ samplepos_t start;
+ samplecnt_t samples;
+};
+
+typedef std::vector<CaptureInfo*> CaptureInfos;
} // namespace ARDOUR