summaryrefslogtreecommitdiff
path: root/libs/ardour/ardour/transport_master_manager.h
blob: 0aaf1bf00c743d4b60a3d5f79ea731027bc68061 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
/*
 * Copyright (C) 2018-2019 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 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.,
 * 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:
	static TransportMasterManager& create ();
	~TransportMasterManager ();

	int set_default_configuration ();
	void restart ();
	void engine_stopped ();

	static TransportMasterManager& instance();
	/* this method is not thread-safe and is intended to be used only
	 * very early in application-lifetime to check if the TMM has
	 * been created yet. Do not use in other code.
	 */
	static bool exists() { return _instance != 0; }

	typedef std::list<boost::shared_ptr<TransportMaster> > TransportMasters;

	int add (SyncSource type, std::string const & name, bool removeable = true);
	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;

	void reconnect_ports ();

	void block_disk_output ();
	void unblock_disk_output ();
	void reinit (double speed, samplepos_t pos);

  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;
	bool disk_output_blocked;

	// 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__ */