1 /* 2 * Copyright (C) 2018-2019 Paul Davis <paul@linuxaudiosystems.com> 3 * 4 * This program is free software; you can redistribute it and/or modify 5 * it under the terms of the GNU General Public License as published by 6 * the Free Software Foundation; either version 2 of the License, or 7 * (at your option) any later version. 8 * 9 * This program is distributed in the hope that it will be useful, 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 * GNU General Public License for more details. 13 * 14 * You should have received a copy of the GNU General Public License along 15 * with this program; if not, write to the Free Software Foundation, Inc., 16 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 17 */ 18 19 #ifndef __ardour_transport_master_manager_h__ 20 #define __ardour_transport_master_manager_h__ 21 22 #include <string> 23 24 #include <boost/noncopyable.hpp> 25 26 #include "ardour/transport_master.h" 27 #include "ardour/types.h" 28 29 namespace ARDOUR { 30 31 class UI_TransportMaster; 32 33 class LIBARDOUR_API TransportMasterManager : public boost::noncopyable 34 { 35 public: 36 static TransportMasterManager& create (); 37 ~TransportMasterManager (); 38 39 int set_default_configuration (); 40 void restart (); 41 void engine_stopped (); 42 43 static TransportMasterManager& instance(); 44 static void destroy(); 45 /* this method is not thread-safe and is intended to be used only 46 * very early in application-lifetime to check if the TMM has 47 * been created yet. Do not use in other code. 48 */ exists()49 static bool exists() { return _instance != 0; } 50 51 typedef std::list<boost::shared_ptr<TransportMaster> > TransportMasters; 52 53 int add (SyncSource type, std::string const & name, bool removeable = true); 54 int remove (std::string const & name); 55 void clear (); 56 57 PBD::Signal1<void,boost::shared_ptr<TransportMaster> > Added; 58 PBD::Signal1<void,boost::shared_ptr<TransportMaster> > Removed; // null argument means "clear" 59 60 double pre_process_transport_masters (pframes_t, samplepos_t session_transport_position); 61 get_current_speed_in_process_context()62 double get_current_speed_in_process_context() const { return _master_speed; } get_current_position_in_process_context()63 samplepos_t get_current_position_in_process_context() const { return _master_position; } 64 current()65 boost::shared_ptr<TransportMaster> current() const { return _current_master; } 66 int set_current (boost::shared_ptr<TransportMaster>); 67 int set_current (SyncSource); 68 int set_current (std::string const &); 69 70 PBD::Signal2<void,boost::shared_ptr<TransportMaster>, boost::shared_ptr<TransportMaster> > CurrentChanged; 71 72 int set_state (XMLNode const &, int); 73 XMLNode& get_state(); 74 75 void set_session (Session*); session()76 Session* session() const { return _session; } 77 master_invalid_this_cycle()78 bool master_invalid_this_cycle() const { return _master_invalid_this_cycle; } 79 80 boost::shared_ptr<TransportMaster> master_by_type (SyncSource src) const; 81 boost::shared_ptr<TransportMaster> master_by_name (std::string const &) const; 82 boost::shared_ptr<TransportMaster> master_by_port (boost::shared_ptr<Port> const &p) const; 83 transport_masters()84 TransportMasters const & transport_masters() const { return _transport_masters; } 85 86 static const std::string state_node_name; 87 88 void reconnect_ports (); 89 90 void block_disk_output (); 91 void unblock_disk_output (); 92 void reinit (double speed, samplepos_t pos); 93 94 private: 95 TransportMasterManager(); 96 97 TransportMasters _transport_masters; 98 mutable Glib::Threads::RWLock lock; 99 double _master_speed; 100 samplepos_t _master_position; 101 102 boost::shared_ptr<TransportMaster> _current_master; 103 Session* _session; 104 105 bool _master_invalid_this_cycle; 106 bool disk_output_blocked; 107 108 /* a DLL to chase the transport master, calculate playback speed 109 * by matching Ardour's current playhead position against 110 * the position of the transport-master */ 111 double t0; // PH position at the beginning of this cycle 112 double t1; // expected PH position if next cycle 113 double e2; // second order loop error 114 double bandwidth; // DLL filter bandwidth 115 double b, c, omega; // DLL filter coefficients 116 117 void init_transport_master_dll (double speed, samplepos_t pos); 118 int master_dll_initstate; // play-direction -1, +1, or 0: not initialized 119 120 static TransportMasterManager* _instance; 121 122 /* original TC format in case the slave changed it */ 123 boost::optional<Timecode::TimecodeFormat> _session_tc_format; 124 void maybe_restore_tc_format (); 125 void maybe_set_tc_format (); 126 127 int add_locked (boost::shared_ptr<TransportMaster>); 128 double compute_matching_master_speed (pframes_t nframes, samplepos_t, bool& locate_required); 129 int set_current_locked (boost::shared_ptr<TransportMaster>); 130 131 PBD::ScopedConnection config_connection; 132 void parameter_changed (std::string const & what); 133 }; 134 135 } // namespace ARDOUR 136 137 #endif /* __ardour_transport_master_manager_h__ */ 138