diff options
author | Paul Davis <paul@linuxaudiosystems.com> | 2018-09-18 18:51:59 -0400 |
---|---|---|
committer | Paul Davis <paul@linuxaudiosystems.com> | 2018-09-18 19:06:04 -0400 |
commit | e6915e01de2e2167c3384c6c8f2408f763971616 (patch) | |
tree | c67200eda4cf4c595503a850fe6ae72d89032a6f /libs/ardour/ardour | |
parent | 7390b88c2bb29b1b34624f441adec1e71c74bad8 (diff) |
new transport slave/master implementation, libs/ edition
Diffstat (limited to 'libs/ardour/ardour')
-rw-r--r-- | libs/ardour/ardour/debug.h | 1 | ||||
-rw-r--r-- | libs/ardour/ardour/disk_io.h | 4 | ||||
-rw-r--r-- | libs/ardour/ardour/midi_buffer.h | 2 | ||||
-rw-r--r-- | libs/ardour/ardour/midi_port.h | 32 | ||||
-rw-r--r-- | libs/ardour/ardour/midiport_manager.h | 6 | ||||
-rw-r--r-- | libs/ardour/ardour/port.h | 6 | ||||
-rw-r--r-- | libs/ardour/ardour/rc_configuration.h | 2 | ||||
-rw-r--r-- | libs/ardour/ardour/rc_configuration_vars.h | 13 | ||||
-rw-r--r-- | libs/ardour/ardour/session.h | 81 | ||||
-rw-r--r-- | libs/ardour/ardour/session_event.h | 14 | ||||
-rw-r--r-- | libs/ardour/ardour/slave.h | 24 | ||||
-rw-r--r-- | libs/ardour/ardour/track.h | 2 | ||||
-rw-r--r-- | libs/ardour/ardour/transport_master.h | 546 | ||||
-rw-r--r-- | libs/ardour/ardour/transport_master_manager.h | 114 | ||||
-rw-r--r-- | libs/ardour/ardour/types.h | 1356 |
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 |