1 /*
2  * Copyright (C) 2006-2012 David Robillard <d@drobilla.net>
3  * Copyright (C) 2006-2017 Paul Davis <paul@linuxaudiosystems.com>
4  * Copyright (C) 2009-2010 Carl Hetherington <carl@carlh.net>
5  * Copyright (C) 2013-2017 John Emmas <john@creativepost.co.uk>
6  *
7  * This program is free software; you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License as published by
9  * the Free Software Foundation; either version 2 of the License, or
10  * (at your option) any later version.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License along
18  * with this program; if not, write to the Free Software Foundation, Inc.,
19  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
20  */
21 
22 #ifndef ardour_control_protocols_h
23 #define ardour_control_protocols_h
24 
25 #include <list>
26 #include <string>
27 #include <vector>
28 
29 #include <boost/shared_ptr.hpp>
30 
31 #include "pbd/signals.h"
32 #include "pbd/stateful.h"
33 
34 #include "control_protocol/basic_ui.h"
35 #include "control_protocol/types.h"
36 #include "control_protocol/visibility.h"
37 
38 namespace ARDOUR {
39 
40 class Route;
41 class Session;
42 class Bundle;
43 class Stripable;
44 
45 class LIBCONTROLCP_API ControlProtocol : public PBD::Stateful, public PBD::ScopedConnectionList, public BasicUI
46 {
47 public:
48 	ControlProtocol (Session&, std::string name);
49 	virtual ~ControlProtocol ();
50 
name()51 	virtual std::string name () const { return _name; }
52 
53 	virtual int set_active (bool yn);
active()54 	virtual bool active () const { return _active; }
55 
set_feedback(bool)56 	virtual int set_feedback (bool /*yn*/) { return 0; }
get_feedback()57 	virtual bool get_feedback () const { return false; }
58 
midi_connectivity_established()59 	virtual void midi_connectivity_established () {}
60 
61 	virtual void stripable_selection_changed () = 0;
62 
63 	PBD::Signal0<void> ActiveChanged;
64 
65 	/* signals that a control protocol can emit and other (presumably graphical)
66 	 * user interfaces can respond to
67 	 */
68 
69 	static PBD::Signal0<void> ZoomToSession;
70 	static PBD::Signal0<void> ZoomIn;
71 	static PBD::Signal0<void> ZoomOut;
72 	static PBD::Signal0<void> Enter;
73 	static PBD::Signal0<void> Undo;
74 	static PBD::Signal0<void> Redo;
75 	static PBD::Signal1<void, float> ScrollTimeline;
76 	static PBD::Signal1<void, uint32_t> GotoView;
77 	static PBD::Signal0<void> CloseDialog;
78 	static PBD::Signal0<void> VerticalZoomInAll;
79 	static PBD::Signal0<void> VerticalZoomOutAll;
80 	static PBD::Signal0<void> VerticalZoomInSelected;
81 	static PBD::Signal0<void> VerticalZoomOutSelected;
82 	static PBD::Signal0<void> StepTracksDown;
83 	static PBD::Signal0<void> StepTracksUp;
84 
85 	void add_stripable_to_selection (boost::shared_ptr<ARDOUR::Stripable>);
86 	void set_stripable_selection (boost::shared_ptr<ARDOUR::Stripable>);
87 	void toggle_stripable_selection (boost::shared_ptr<ARDOUR::Stripable>);
88 	void remove_stripable_from_selection (boost::shared_ptr<ARDOUR::Stripable>);
89 	void clear_stripable_selection ();
90 
91 	boost::shared_ptr<ARDOUR::Stripable> first_selected_stripable () const;
92 
93 	/* the model here is as follows:
94 
95 	   we imagine most control surfaces being able to control
96 	   from 1 to N tracks at a time, with a session that may
97 	   contain 1 to M tracks, where M may be smaller, larger or
98 	   equal to N.
99 
100 	   the control surface has a fixed set of physical controllers
101 	   which can potentially be mapped onto different tracks/busses
102 	   via some mechanism.
103 
104 	   therefore, the control protocol object maintains
105 	   a table that reflects the current mapping between
106 	   the controls and route object.
107 	*/
108 
109 	void set_route_table_size (uint32_t size);
110 	void set_route_table (uint32_t table_index, boost::shared_ptr<ARDOUR::Route>);
111 	bool set_route_table (uint32_t table_index, uint32_t remote_control_id);
112 
113 	void route_set_rec_enable (uint32_t table_index, bool yn);
114 	bool route_get_rec_enable (uint32_t table_index);
115 
116 	float route_get_gain (uint32_t table_index);
117 	void  route_set_gain (uint32_t table_index, float);
118 	float route_get_effective_gain (uint32_t table_index);
119 
120 	float route_get_peak_input_power (uint32_t table_index, uint32_t which_input);
121 
122 	bool route_get_muted (uint32_t table_index);
123 	void route_set_muted (uint32_t table_index, bool);
124 
125 	bool route_get_soloed (uint32_t table_index);
126 	void route_set_soloed (uint32_t table_index, bool);
127 
128 	std::string route_get_name (uint32_t table_index);
129 
130 	virtual std::list<boost::shared_ptr<ARDOUR::Bundle> > bundles ();
131 
has_editor()132 	virtual bool has_editor () const { return false; }
get_gui()133 	virtual void* get_gui () const { return 0; }
tear_down_gui()134 	virtual void tear_down_gui () {}
135 
136 	XMLNode& get_state ();
137 	int set_state (XMLNode const&, int version);
138 
139 	static const std::string state_node_name;
140 
last_selected()141 	static StripableNotificationList const& last_selected () { return _last_selected; }
142 	static void notify_stripable_selection_changed (StripableNotificationListPtr);
143 
144 protected:
145 	void next_track (uint32_t initial_id);
146 	void prev_track (uint32_t initial_id);
147 
148 	std::vector<boost::shared_ptr<ARDOUR::Route> > route_table;
149 	std::string _name;
150 
151 private:
152 	LIBCONTROLCP_LOCAL ControlProtocol (const ControlProtocol&); /* noncopyable */
153 
154 	bool _active;
155 
156 	static StripableNotificationList          _last_selected;
157 	static PBD::ScopedConnection              selection_connection;
158 	static bool                               selection_connected;
159 };
160 
161 extern "C" {
162 class ControlProtocolDescriptor
163 {
164 public:
165 	const char* name;              /* descriptive */
166 	const char* id;                /* unique and version-specific */
167 	void*       ptr;               /* protocol can store a value here */
168 	void*       module;            /* not for public access */
169 	int         mandatory;         /* if non-zero, always load and do not make optional */
170 	bool        supports_feedback; /* if true, protocol has toggleable feedback mechanism */
171 	bool (*probe) (ControlProtocolDescriptor*);
172 	ControlProtocol* (*initialize) (ControlProtocolDescriptor*, Session*);
173 	void (*destroy) (ControlProtocolDescriptor*, ControlProtocol*);
174 	/* this is required if the control protocol connects to signals
175 	 * from libardour. they all do. It should allocate a
176 	 * type-specific request buffer for the calling thread, and
177 	 * store it in a thread-local location that will be used to
178 	 * find it when sending the event loop a message
179 	 * (e.g. call_slot()). It should also return the allocated
180 	 * buffer as a void*.
181 	 */
182 	void* (*request_buffer_factory) (uint32_t);
183 };
184 }
185 }
186 
187 #endif // ardour_control_protocols_h
188