forward propagate solo-isolated status to everything fed by a route by something...
[ardour.git] / libs / ardour / ardour / audioengine.h
1 /*
2     Copyright (C) 2002-2004 Paul Davis
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
15     along with this program; if not, write to the Free Software
16     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
17
18 */
19
20 #ifndef __ardour_audioengine_h__
21 #define __ardour_audioengine_h__
22
23 #include <list>
24 #include <set>
25 #include <cmath>
26 #include <exception>
27 #include <string>
28
29 #include <sigc++/signal.h>
30
31 #include <glibmm/thread.h>
32
33 #include "pbd/rcu.h"
34
35 #include "ardour/ardour.h"
36 #include <jack/jack.h>
37 #include <jack/transport.h>
38 #include "ardour/types.h"
39 #include "ardour/data_type.h"
40
41 namespace ARDOUR {
42
43 class InternalPort;
44 class MidiPort;
45 class Port;
46 class Session;
47
48 class AudioEngine : public sigc::trackable
49 {
50    public:
51         typedef std::set<Port*> Ports;
52
53         AudioEngine (std::string client_name);
54         virtual ~AudioEngine ();
55
56         jack_client_t* jack() const;
57         bool connected() const { return _jack != 0; }
58
59         bool is_realtime () const;
60
61         std::string client_name() const { return jack_client_name; }
62
63         int reconnect_to_jack ();
64         int disconnect_from_jack();
65
66         bool will_reconnect_at_halt ();
67         void set_reconnect_at_halt (bool);
68
69         int stop (bool forever = false);
70         int start ();
71         bool running() const { return _running; }
72
73         Glib::Mutex& process_lock() { return _process_lock; }
74
75         nframes_t frame_rate();
76         nframes_t frames_per_cycle();
77
78         size_t raw_buffer_size(DataType t);
79
80         int usecs_per_cycle () const { return _usecs_per_cycle; }
81
82         bool get_sync_offset (nframes_t& offset) const;
83
84         nframes_t frames_since_cycle_start () {
85                 jack_client_t* _priv_jack = _jack;
86                 if (!_running || !_priv_jack) return 0;
87                 return jack_frames_since_cycle_start (_priv_jack);
88         }
89         nframes_t frame_time () {
90                 jack_client_t* _priv_jack = _jack;
91                 if (!_running || !_priv_jack) return 0;
92                 return jack_frame_time (_priv_jack);
93         }
94
95         nframes_t transport_frame () const {
96                 const jack_client_t* _priv_jack = _jack;
97                 if (!_running || !_priv_jack) return 0;
98                 return jack_get_current_transport_frame (_priv_jack);
99         }
100
101         int request_buffer_size (nframes_t);
102
103         nframes_t set_monitor_check_interval (nframes_t);
104         nframes_t processed_frames() const { return _processed_frames; }
105
106         float get_cpu_load() {
107                 jack_client_t* _priv_jack = _jack;
108                 if (!_running || !_priv_jack) return 0;
109                 return jack_cpu_load (_priv_jack);
110         }
111
112         void set_session (Session *);
113         void remove_session ();
114
115         class PortRegistrationFailure : public std::exception {
116         public:
117                 PortRegistrationFailure (const char* why = "") {
118                         reason = why;
119                 }
120                 virtual const char *what() const throw() { return reason; }
121
122         private:
123                 const char* reason;
124         };
125
126         class NoBackendAvailable : public std::exception {
127         public:
128                 virtual const char *what() const throw() { return "could not connect to engine backend"; }
129         };
130
131         Port *register_input_port (DataType, const std::string& portname);
132         Port *register_output_port (DataType, const std::string& portname);
133         int   unregister_port (Port &);
134
135         void split_cycle (nframes_t offset);
136
137         int connect (const std::string& source, const std::string& destination);
138         int disconnect (const std::string& source, const std::string& destination);
139         int disconnect (Port &);
140
141         const char ** get_ports (const std::string& port_name_pattern, const std::string& type_name_pattern, uint32_t flags);
142
143         bool can_request_hardware_monitoring ();
144
145         uint32_t n_physical_outputs (DataType type) const;
146         uint32_t n_physical_inputs (DataType type) const;
147
148         void get_physical_outputs (DataType type, std::vector<std::string>&);
149         void get_physical_inputs (DataType type, std::vector<std::string>&);
150
151         std::string get_nth_physical_output (DataType type, uint32_t n) {
152                 return get_nth_physical (type, n, JackPortIsInput);
153         }
154
155         std::string get_nth_physical_input (DataType type, uint32_t n) {
156                 return get_nth_physical (type, n, JackPortIsOutput);
157         }
158
159         void update_total_latencies ();
160         void update_total_latency (const Port&);
161
162         Port *get_port_by_name (const std::string &);
163         Port *get_port_by_name_locked (const std::string &);
164
165         enum TransportState {
166                 TransportStopped = JackTransportStopped,
167                 TransportRolling = JackTransportRolling,
168                 TransportLooping = JackTransportLooping,
169                 TransportStarting = JackTransportStarting
170         };
171
172         void transport_start ();
173         void transport_stop ();
174         void transport_locate (nframes_t);
175         TransportState transport_state ();
176
177         int  reset_timebase ();
178
179         /* start/stop freewheeling */
180
181         int freewheel (bool onoff);
182         bool freewheeling() const { return _freewheeling; }
183
184         /* this signal is sent for every process() cycle while freewheeling.
185 _          the regular process() call to session->process() is not made.
186         */
187
188         sigc::signal<int,nframes_t> Freewheel;
189
190         sigc::signal<void> Xrun;
191
192         /* this signal is if JACK notifies us of a graph order event */
193
194         sigc::signal<void> GraphReordered;
195
196         /* this signal is emitted if the sample rate changes */
197
198         sigc::signal<void,nframes_t> SampleRateChanged;
199
200         /* this signal is sent if JACK ever disconnects us */
201
202         sigc::signal<void> Halted;
203
204         /* these two are emitted when the engine itself is
205            started and stopped
206         */
207
208         sigc::signal<void> Running;
209         sigc::signal<void> Stopped;
210
211         /* this signal is emitted if a JACK port is registered or unregistered */
212
213         sigc::signal<void> PortRegisteredOrUnregistered;
214
215         std::string make_port_name_relative (std::string);
216         std::string make_port_name_non_relative (std::string);
217
218         static AudioEngine* instance() { return _instance; }
219         void died ();
220
221   private:
222         static AudioEngine*       _instance;
223
224         ARDOUR::Session*           session;
225         jack_client_t* volatile   _jack; /* could be reset to null by SIGPIPE or another thread */
226         std::string                jack_client_name;
227         Glib::Mutex               _process_lock;
228         Glib::Cond                 session_removed;
229         bool                       session_remove_pending;
230         bool                      _running;
231         bool                      _has_run;
232         nframes_t                 _buffer_size;
233         std::map<DataType,size_t> _raw_buffer_sizes;
234         nframes_t                 _frame_rate;
235         /// number of frames between each check for changes in monitor input
236         nframes_t                  monitor_check_interval;
237         /// time of the last monitor check in frames
238         nframes_t                  last_monitor_check;
239         /// the number of frames processed since start() was called
240         nframes_t                 _processed_frames;
241         bool                      _freewheeling;
242         bool                      _freewheel_pending;
243         bool                      _freewheel_thread_registered;
244         sigc::slot<int,nframes_t>  freewheel_action;
245         bool                       reconnect_on_halt;
246         int                       _usecs_per_cycle;
247
248         SerializedRCUManager<Ports> ports;
249
250         Port *register_port (DataType type, const std::string& portname, bool input);
251
252         int    process_callback (nframes_t nframes);
253         void   remove_all_ports ();
254
255         std::string get_nth_physical (DataType type, uint32_t n, int flags);
256
257         void port_registration_failure (const std::string& portname);
258
259         static int  _xrun_callback (void *arg);
260         static int  _graph_order_callback (void *arg);
261         static int  _process_callback (nframes_t nframes, void *arg);
262         static int  _sample_rate_callback (nframes_t nframes, void *arg);
263         static int  _bufsize_callback (nframes_t nframes, void *arg);
264         static void _jack_timebase_callback (jack_transport_state_t, nframes_t, jack_position_t*, int, void*);
265         static int  _jack_sync_callback (jack_transport_state_t, jack_position_t*, void *arg);
266         static void _freewheel_callback (int , void *arg);
267         static void _registration_callback (jack_port_id_t, int, void *);
268
269         void jack_timebase_callback (jack_transport_state_t, nframes_t, jack_position_t*, int);
270         int  jack_sync_callback (jack_transport_state_t, jack_position_t*);
271         int  jack_bufsize_callback (nframes_t);
272         int  jack_sample_rate_callback (nframes_t);
273
274         int connect_to_jack (std::string client_name);
275
276         static void halted (void *);
277
278         void meter_thread ();
279         void start_metering_thread ();
280         void stop_metering_thread ();
281
282         Glib::Thread*    m_meter_thread;
283         static gint      m_meter_exit;
284 };
285
286 } // namespace ARDOUR
287
288 #endif /* __ardour_audioengine_h__ */