Remove frame conversion for MidiRegionView::note_in_region_range(), speed up tempo...
[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__) */