e64a7a6975ab084b3e415290da951eaf4ccbfc36
[ardour.git] / libs / ardour / ardour / engine_state_controller.h
1 /*
2  * Copyright (C) 2015-2017 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 __gtk2_ardour__engine_state_controller__
20 #define __gtk2_ardour__engine_state_controller__
21
22 #include <vector>
23 #include <list>
24
25 #include "ardour/types.h"
26 #include "ardour/audio_backend.h"
27
28 namespace ARDOUR {
29
30 class AudioBackendInfo;
31
32 /**
33  * @class EngineStateController
34  * @brief EngineStateController class.
35  *
36  * Implements usecases for Audio devices and Audio/Midi ports.
37  * Persistantly saves to the config device configuration settings and audio/midi port states
38  */
39 class EngineStateController
40 {
41                                         public:
42
43         // public data types:
44
45         /**
46          * @struct PortState
47          * Structure which represents AudioPort state
48          */
49         struct PortState {
50                 std::string name; ///< Audio Port name
51                 bool active;      ///< Audio Port state
52
53                 PortState ()
54                         : name("")
55                         , active(false)
56                 {
57                 }
58
59                 PortState (const std::string& name)
60                         : name(name)
61                         , active(false)
62                 {
63                 }
64
65                 bool operator==(const PortState& rhs) {return rhs.name == name; }
66
67         };
68
69         /// @typedef Type for the list of all available audio ports
70         typedef std::list<PortState> PortStateList;
71
72         /**
73          * @struct MidiPortState
74          * Structure which represents MidiPort state.
75          */
76         struct MidiPortState
77         {
78                 std::string name;     ///< Midi Port name
79                 bool active;          ///< Midi Port state
80                 bool available;       ///< Midi Port availability - if it is physicaly available or not
81                 bool scene_connected; ///< Is midi port used for scene MIDI marker in/out
82                 bool mtc_in;          ///< Is midi port used as MTC in
83
84                 MidiPortState(const std::string& name)
85                         : name(name)
86                         , active(false)
87                         , available(false)
88                         , scene_connected(false)
89                         , mtc_in(false)
90                 {}
91
92                 bool operator==(const MidiPortState& rhs)
93                 {
94                         return name == rhs.name;
95                 }
96         };
97
98         /// @typedef Type for the list of MidiPorts ever registered in the system
99         typedef std::list<MidiPortState> MidiPortStateList;
100
101
102         //Interfaces
103
104         /** Get an instance of EngineStateController singleton.
105          * @return EngineStateController instance pointer
106          */
107         static EngineStateController* instance ();
108
109         /** Associate session with EngineStateController instance.
110          */
111         void set_session (Session* session);
112
113         /** Remove link to the associated session.
114          */
115         void remove_session ();
116
117         //////////////////////////////////////////////////////////////////////////////////////////////////////////
118         // General backend/device information methods
119
120         /** Provides names of all available backends.
121          *
122          * @param[out] available_backends - vector of available backends
123          */
124         void available_backends (std::vector<const AudioBackendInfo*>& available_backends);
125
126         /** Provides the name of currently used backend.
127          *
128          * @return the name of currently used backend
129          */
130         const std::string& get_current_backend_name() const;
131
132         /** Provides the name of currently used device.
133          *
134          * @return the name of currently used device
135          */
136         const std::string& get_current_device_name () const;
137
138         /** Provides names for all available devices.
139          *
140          * @param[out] device_vector - vector of available devices
141          */
142         void enumerate_devices (std::vector<ARDOUR::AudioBackend::DeviceStatus>& device_vector) const;
143
144         /** Get sample rate used by current device.
145          *
146          * @return current sample rate
147          */
148         ARDOUR::samplecnt_t get_current_sample_rate () const;
149
150         /** Get default sample rate for current backend.
151          *
152          * @return default sample rate for current backend
153          */
154         ARDOUR::samplecnt_t get_default_sample_rate () const;
155
156         /** Get sample rates which are supported by current device and current backend.
157          *
158          * @param[out] sample_rates - vector of supported sample rates
159          */
160         void available_sample_rates_for_current_device (std::vector<float>& sample_rates) const;
161
162         /** Get buffer size used by current device.
163          *
164          * @return current buffer size
165          */
166         ARDOUR::pframes_t get_current_buffer_size () const;
167
168         /** Get default buffer size for current backend.
169          *
170          * @return default buffer size for current backend
171          */
172         ARDOUR::pframes_t get_default_buffer_size () const;
173
174         /** Get buffer sizes which are supported by current device and current backend.
175          *
176          * @param[out] buffer_sizes - vector of supported buffer_sizes
177          */
178         void available_buffer_sizes_for_current_device (std::vector<ARDOUR::pframes_t>& buffer_sizes) const;
179
180         /////////////////////////////////////////////////////////////////////////////////////////////////////////////////
181         // device state control methods
182
183         /** Get the number of all enabled Audio inputs.
184          *
185          * @return number of all enabled Audio inputs
186          */
187         uint32_t            get_available_inputs_count() const;
188         /** Get the number of all enabled Audio outputs.
189          *
190          * @return number of all enabled Audio outputs
191          */
192         uint32_t            get_available_outputs_count () const;
193
194         /** Get vector of all enabled physical Audio input port names.
195          *
196          * @param[out] port_names - vector of all enabled Audio input names
197          */
198         void                get_physical_audio_inputs (std::vector<std::string>& port_names);
199         /** Get vector of all enabled physical Audio input port names.
200          *
201          * @param[out] port_names - vector of all enabled Audio input names
202          */
203         void                get_physical_audio_outputs (std::vector<std::string>& port_names);
204
205         /** Get vector of all enabled physical MIDI input port names.
206          *
207          * @param[out] port_names - vector of all enabled MIDI input names
208          */
209         void                get_physical_midi_inputs (std::vector<std::string>& port_names);
210         /** Get vector of all enabled physical MIDI output port names.
211          *
212          * @param[out] port_names - vector of all enabled MIDI output names
213          */
214         void                get_physical_midi_outputs (std::vector<std::string>& port_names);
215
216         /** Sets new state to all Audio inputs.
217          *
218          * @param[in] state - new state
219          */
220         void                set_state_to_all_inputs(bool state);
221         /** Sets new state to all Audio outputs.
222          * @note Does nothing in Stereo Out mode
223          * @param[in] state - new state
224          */
225         void                set_state_to_all_outputs(bool state);
226
227         /** Get vector of states for all physical Audio input ports.
228          *
229          * @param[out] channel_states - vector of input port states
230          */
231         void                get_physical_audio_input_states(std::vector<PortState>& channel_states);
232         /** Get vector of states for all physical Audio output ports.
233          *
234          * @param[out] channel_states - vector of output port states
235          */
236         void                get_physical_audio_output_states(std::vector<PortState>& channel_states);
237
238         /** Set state of the specified Audio input port.
239          *
240          * @param[in] port_name - input name
241          * @param[in] state - new state
242          */
243         void                set_physical_audio_input_state(const std::string& port_name, bool state);
244         /** Set state of the specified Audio output port.
245          *
246          * @param[in] port_name - output name
247          * @param[in] state - new state
248          */
249         void                set_physical_audio_output_state(const std::string& port_name, bool state);
250
251         /** Get state of the specified Audio input port.
252          *
253          * @param[in] port_name - input name
254          * @return input state
255          */
256         bool                get_physical_audio_input_state(const std::string& port_name);
257         /** Get state of the specified Audi output port.
258          *
259          * @param[in] port_name - output name
260          * @return output state
261          */
262         bool                get_physical_audio_output_state(const std::string& port_name);
263
264
265         /** Get vector of all enabled MIDI input port names.
266          *
267          * @param[out] channel_states - vector of enabled inputs
268          */
269         void                get_physical_midi_input_states (std::vector<MidiPortState>& channel_states);
270         /** Get vector of all enabled MIDI output port names.
271          *
272          * @param[out] channel_states - vector of enabled outputs
273          */
274         void                get_physical_midi_output_states (std::vector<MidiPortState>& channel_states);
275
276         /** Get name of mtc source port
277          *
278          * return name of mtc source port
279          */
280         std::string          get_mtc_source_port ();
281
282         /** Set ltc source port
283          *
284          * @param[in] port - name of ltc source port
285          */
286         void                set_ltc_source_port (const std::string& port);
287         /** Get name of ltc source port
288          *
289          * return name of ltc source port
290          */
291         std::string          get_ltc_source_port ();
292
293         /** Set ltc output port
294          *
295          * @param[in] port - name of ltc output port
296          */
297         void                set_ltc_output_port (const std::string&);
298         /** Get name of ltc output port
299          *
300          * return name of ltc output port
301          */
302         std::string         get_ltc_output_port ();
303
304         /** Set state of the specified MIDI input port.
305          *
306          * @param[in] port_name - input name
307          * @param[in] state - new state
308          */
309         void                set_physical_midi_input_state(const std::string& port_name, bool state);
310         /** Set state of the specified MIDI output port.
311          *
312          * @param[in] port_name - output name
313          * @param[in] state - new state
314          */
315         void                set_physical_midi_output_state(const std::string& port_name, bool state);
316         /** Get state of the specified MIDI input port.
317          *
318          * @param[in] port_name - input name
319          * @param[out] scene_connected - is port used as Scene In or not
320          * @return input state
321          */
322         bool                get_physical_midi_input_state(const std::string& port_name, bool& scene_connected);
323         /** Get state of the specified MIDI output port.
324          *
325          * @param[in] port_name - output name
326          * @param[out] scene_connected - is port used as Scene Out or not
327          * @return output state
328          */
329         bool                get_physical_midi_output_state(const std::string& port_name, bool& scene_connected);
330
331         /** Set state of Scene In connection for the specified MIDI input port.
332          *
333          * @param[in] port_name - input name
334          * @param[in] state - new state
335          */
336         void                set_physical_midi_scene_in_connection_state(const std::string& port_name, bool state);
337         /** Set state of Scene Out connection for the specified MIDI output port.
338          *
339          * @param[in] port_name - input name
340          * @param[in] state - new state
341          */
342         void                set_physical_midi_scenen_out_connection_state(const std::string&, bool);
343
344         /** Disocnnect all MIDI input ports from Scene In.
345          */
346         void                set_all_midi_scene_inputs_disconnected();
347         /** Disocnnect all MIDI output ports from Scene Out.
348          */
349         void                set_all_midi_scene_outputs_disconnected();
350
351         /** Set MIDI TimeCode input port
352          * @note There is a sense to choose MIDI TimeCode input only because
353          * our MIDI TimeCode is propagated to all midi output ports.
354          */
355         void                set_mtc_source_port (const std::string&);
356
357         /** Check if AudioEngine setup is required
358          * @return true if setup is required, otherwise - false
359          */
360         bool                is_setup_required() const {return ARDOUR::AudioEngine::instance()->setup_required (); }
361
362         ////////////////////////////////////////////////////////////////////////////////////////////////////
363         // Methods set parameters inside the controller
364         // the state of engine won't change untill we make a "push" of this state to the backend
365         // NOTE: Use push_state_to_backend() method to update backend with the most recent controller state
366
367         /** Set new sample rate for current device in EngineStateController database
368          * @note Use push_state_to_backend() method to update backend/device state with the most recent controller state
369          * @param sample_rate - new sample rate
370          */
371         bool        set_new_sample_rate_in_controller(samplecnt_t sample_rate);
372         /** Set new buffer size for current device in EngineStateController database
373          * @note Use push_state_to_backend() method to update backend/device state with the most recent controller state
374          * @param buffer_size - new buffer size
375          */
376         bool        set_new_buffer_size_in_controller(pframes_t buffer_size);
377
378         /** @brief push current controller state to backend.
379          * Propagate and set all current EngineStateController parameters to the backend
380          * @note Engine will be restarted if it's running when this method is called.
381          * @note If an attempt ot set parameters is unsuccessful current device will be switched to "None".
382          * @param start - start the Engine if it was not running when this function was called.
383          * @return true on success, otherwise - false
384          */
385         bool        push_current_state_to_backend(bool start);
386         /** Switch to new backend
387          * @note The change will be propagated emmidiatelly as if push_current_state_to_backend () was called.
388          * @param backend_name - new backend name.
389          * @return true on success, otherwise - false
390          */
391         bool        set_new_backend_as_current(const std::string& backend_name);
392         /** Switch to new device
393          * @note The change will be propagated emmidiatelly as if push_current_state_to_backend () was called.
394          * @param device_name - new device name.
395          * @return true on success, otherwise - false
396          */
397         bool        set_new_device_as_current(const std::string& device_name);
398
399
400         ////////////////////////////////////////////////////////////////////////////////////////////////////
401         // Methods to save/serialize setting states
402
403         /** Serialize Audio/Midi settings (entire EngineStateController database) to XML
404          * @return XML note with serialized states
405          */
406         XMLNode&    serialize_audio_midi_settings();
407         /** Save Audio/Midi settings (entire EngineStateController database) to config persistently
408          */
409         void        save_audio_midi_settings();
410
411         ////////////////////////////////////////////////////////////////////////////////////////////////////
412         //UPDATE SIGNALS
413         /** This signal is emitted if the sample rate changes */
414         PBD::Signal0<void> SampleRateChanged;
415         /** This signal is emitted if the buffer size changes */
416         PBD::Signal0<void> BufferSizeChanged;
417         /** This signal is emitted if the device list changes */
418         PBD::Signal1<void, bool> DeviceListChanged;
419         /** This signal is emitted if the device cannot operate properly */
420         PBD::Signal0<void> DeviceError;
421
422         ////////////////////////////////////////////////////////////////////////////////////////////////////
423         //ENGINE STATE SIGNALS
424         /** This signal is emitted when the engine is started */
425         PBD::Signal0<void> EngineRunning;
426         /** This signal is emitted when the engine is stopped */
427         PBD::Signal0<void> EngineStopped;
428         /** This signal is emitted if Engine processing is terminated */
429         PBD::Signal0<void> EngineHalted;
430
431         /** This signal is emitted if the AUDIO input channel configuration changes */
432         PBD::Signal0<void> InputConfigChanged;
433         /** This signal is emitted if the AUDIO output channel configuration changes */
434         PBD::Signal0<void> OutputConfigChanged;
435         /** This signal is emitted if the AUDIO output connection mode changes
436          * @note By output connection mode "Stereo Out" or "Multi Out" is meant
437          */
438         PBD::Signal0<void> OutputConnectionModeChanged;
439
440         /** This signals is emitted if the MIDI input channel configuration changes */
441         PBD::Signal0<void> MIDIInputConfigChanged;
442         /** This signals is emitted if the MIDI output channel configuration changes */
443         PBD::Signal0<void> MIDIOutputConfigChanged;
444         /** This signals is emitted if the MIDI Scene In connection changes */
445         PBD::Signal2<void, const std::vector<std::string>&, bool> MIDISceneInputConnectionChanged;
446         /** This signals is emitted if the MIDI Scene Out connection changes */
447         PBD::Signal2<void, const std::vector<std::string>&, bool> MIDISceneOutputConnectionChanged;
448
449         /** This signal is emitted if the MTC Input channel is changed */
450         PBD::Signal1<void, const std::string&> MTCInputChanged;
451
452         /** This signal is emitted if new Audio/MIDI ports are registered or unregistered */
453         PBD::Signal0<void> PortRegistrationChanged;
454
455                                         private:
456
457         EngineStateController(); /// singleton
458         ~EngineStateController(); /// singleton
459         EngineStateController(const EngineStateController& ); /// prohibited
460         EngineStateController& operator=(const EngineStateController&); /// prohibited
461
462         ////////////////////////////////////////////////////////////////////////////////////////////
463         // private data structures
464
465         /** @struct Engine state
466          * @brief State structure.
467          * Contains information about single device/backend state
468          */
469         struct State {
470                 std::string backend_name; ///< state backend name
471                 std::string device_name; ///< state device name
472                 ARDOUR::samplecnt_t sample_rate; ///< sample rate used by the device in this state
473                 ARDOUR::pframes_t buffer_size; ///< buffer size used by the device in this state
474
475                 PortStateList input_channel_states; ///< states of device Audio inputs
476                 PortStateList multi_out_channel_states; ///< states of device Audio inputs in Multi Out mode
477                 PortStateList stereo_out_channel_states; ///< states of device Audio inputs in Stereo Out mode
478                 bool active; ///< was this state the most recent active one
479
480                 State()
481                         : sample_rate(0)
482                         , buffer_size(0)
483                         , input_channel_states (0)
484                         , multi_out_channel_states (0)
485                         , stereo_out_channel_states (0)
486                         , active (false)
487                 {
488                 }
489
490                 bool operator==(const State& rhs)
491                 {
492                         return (backend_name == rhs.backend_name) && (device_name == rhs.device_name);
493                 }
494
495                 /** Forms string name for the state
496                  * @return name string
497                  */
498                 std::string form_state_name() {
499                         return std::string("State:" + backend_name + ":" + device_name);
500                 }
501
502                 /** @struct StatepPredicate
503                  * This predicate is used to identify a state during search in the list of states
504                  */
505                 struct StatePredicate
506                 {
507                         StatePredicate(const std::string& backend_name, const std::string& device_name)
508                                 : _backend_name (backend_name)
509                                 , _device_name (device_name)
510                         {}
511
512                         bool operator()(boost::shared_ptr<ARDOUR::EngineStateController::State> rhs)
513                         {
514                                 return (_backend_name == rhs->backend_name) && (_device_name == rhs->device_name);
515                         }
516
517                                                         private:
518                         std::string _backend_name;
519                         std::string _device_name;
520                 };
521         };
522
523         /// @typedef Type for the state pointer
524         typedef boost::shared_ptr<State> StatePtr;
525         /// @typedef Type for the list of states
526         typedef std::list<StatePtr> StateList;
527
528         ////////////////////////////////////////////////////////////////////////////////////////////////////
529         // methods to manage setting states
530
531         /** Deserializes and loads Engine and Audio port states from the config to EngineStateController
532          */
533         void _deserialize_and_load_engine_states();
534         /** Deserializes and loads MIDI port states from the config to EngineStateController
535          */
536         void _deserialize_and_load_midi_port_states();
537         /** Serializes Engine and Audio port states from EngineStateController to XML node
538          * @param[in,out] audio_midi_settings_node - node to serialize the satets to
539          */
540         void _serialize_engine_states(XMLNode* audio_midi_settings_node);
541         /** Serializes MIDI port states from EngineStateController to XML node
542          * @param[in,out] audio_midi_settings_node - node to serialize the satets to
543          */
544         void _serialize_midi_port_states(XMLNode* audio_midi_settings_node);
545
546         /** Provides initial state configuration.
547          * It loades the last active state if there is one and it is aplicable.
548          * Otherwise default state (None device with default sample rate and buffer size) is loaded.
549          */
550         void _do_initial_engine_setup();
551
552         /** Loades provided state.
553          * @note It's possible that provided state can't be loaded
554          * (device disconnected or reqested parameters are not supported anymore).
555          * @param state - state to apply
556          * @return true on success, otherwise - false
557          */
558         bool _apply_state(const StatePtr& state);
559
560         /** Gets available device channels from engine and updates internal controller state
561          */
562         void _update_device_channels_state();
563
564         /** Check "Stereo Out" mode channels state configuration and make it correspond Stereo Out mode requirements
565          */
566         void _refresh_stereo_out_channel_states();
567
568         ////////////////////////////////////////////////////////////////////////////////////////////////////////////
569         // internal helper functions
570         /** make sure that current device parameters are supported and fit session requirements
571          * @return true if current state is valid and all parameters are supported, otherwise - false
572          */
573         bool _validate_current_device_state();
574
575         /** change ltc source port in case of the input ports list change
576          */
577         void _update_ltc_source_port ();
578         /** change ltc source port in case of the output ports list change
579          */
580         void _update_ltc_output_port ();
581
582         /** check that port is still existed in the list of input ports
583             @param[in] port - port name
584             @return true if current port is existed, otherwise - false
585         */
586         bool _audio_input_port_exists (const std::string& port);
587         /** check that port is still existed in the list of output ports
588             @param[in] port - port name
589             @return true if current port is existed, otherwise - false
590         */
591         bool _audio_output_port_exists (const std::string& port);
592
593
594
595         ////////////////////////////////////////
596         // callbacks
597         /** Invoked when Engine starts running
598          */
599         void _on_engine_running();
600         /** Invoked when Engine is halted
601          */
602         void _on_engine_halted();
603         /** Invoked when Engine processing is terminated
604          */
605         void _on_engine_stopped();
606         /** Invoked when Device error accured, it failed to start or didn't accept the change which should
607          */
608         void _on_device_error();
609         /** Invoked when current device changes sample rate
610          */
611         void _on_sample_rate_change(ARDOUR::samplecnt_t);
612         /** Invoked when current device changes buffer size
613          */
614         void _on_buffer_size_change(ARDOUR::pframes_t);
615         /** Invoked when the list of available devices is changed
616          */
617         void _on_device_list_change();
618         /** Invoked when the config parameter is changed
619          */
620         void _on_parameter_changed (const std::string&);
621         /** Invoked when Audio/MIDI ports are registered or unregistered
622          */
623         void _on_ports_registration_update ();
624         /** Invoked when session loading process is complete
625          */
626         void _on_session_loaded();
627         ////////////////////////////////////////
628
629         ////////////////////////////////////////
630         // attributes
631         StatePtr _current_state; ///< current state pointer
632         // list of system states
633         StateList _states; ///< list of all available states
634
635         MidiPortStateList _midi_inputs; ///< midi input states
636         MidiPortStateList _midi_outputs; ///< midi output states
637
638         std::string _last_used_real_device; ///< last active non-default (real) device
639
640         Session* _session; ///< current session
641
642         // Engine connections stuff
643         PBD::ScopedConnectionList update_connections; ///< connection container for update signals
644         PBD::ScopedConnectionList session_connections; ///< connection container for session signals
645         PBD::ScopedConnection running_connection; ///< connection container for EngineRunning signal
646         PBD::ScopedConnection halt_connection; ///< connection container for EngineHalted signal
647         PBD::ScopedConnection stopped_connection; ///< connection container for EngineStopped signal
648 };
649
650 } // namespace ARDOUR
651
652 #endif /* defined(__gtk2_ardour__engine_state_controller__) */