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