fix crash when copy'ing latent plugins
[ardour.git] / libs / ardour / engine_state_controller.cc
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 #include "ardour/engine_state_controller.h"
21
22 #include "ardour/audioengine.h"
23 #include "ardour/session.h"
24 #include "ardour/rc_configuration.h"
25 #include "ardour/data_type.h"
26
27 #include "pbd/pthread_utils.h"
28 #include "pbd/error.h"
29 #include "pbd/i18n.h"
30
31
32 using namespace ARDOUR;
33 using namespace PBD;
34
35 namespace {
36
37 struct DevicePredicate
38 {
39         DevicePredicate (const std::string& device_name)
40                 : _device_name (device_name)
41         {}
42
43         bool operator ()(const AudioBackend::DeviceStatus& rhs)
44         {
45                 return _device_name == rhs.name;
46         }
47
48                                         private:
49         std::string _device_name;
50 };
51 }
52
53 EngineStateController*
54 EngineStateController::instance ()
55 {
56         static EngineStateController instance;
57         return &instance;
58 }
59
60
61 EngineStateController::EngineStateController ()
62         : _current_state ()
63         , _last_used_real_device ("")
64
65 {
66         AudioEngine::instance ()->Running.connect_same_thread (running_connection, boost::bind (&EngineStateController::_on_engine_running, this));
67         AudioEngine::instance ()->Stopped.connect_same_thread (stopped_connection, boost::bind (&EngineStateController::_on_engine_stopped, this));
68         AudioEngine::instance ()->Halted.connect_same_thread (stopped_connection, boost::bind (&EngineStateController::_on_engine_stopped, this));
69
70         /* Subscribe for udpates from AudioEngine */
71         AudioEngine::instance ()->PortRegisteredOrUnregistered.connect_same_thread (update_connections, boost::bind (&EngineStateController::_on_ports_registration_update, this));
72         AudioEngine::instance ()->SampleRateChanged.connect_same_thread (update_connections, boost::bind (&EngineStateController::_on_sample_rate_change, this, _1));
73         AudioEngine::instance ()->BufferSizeChanged.connect_same_thread (update_connections, boost::bind (&EngineStateController::_on_buffer_size_change, this, _1));
74         AudioEngine::instance ()->DeviceListChanged.connect_same_thread (update_connections, boost::bind (&EngineStateController::_on_device_list_change, this));
75         AudioEngine::instance ()->DeviceError.connect_same_thread (update_connections, boost::bind (&EngineStateController::_on_device_error, this));
76
77         /* Global configuration parameters update */
78         Config->ParameterChanged.connect_same_thread (update_connections, boost::bind (&EngineStateController::_on_parameter_changed, this, _1));
79
80         _deserialize_and_load_engine_states ();
81         _deserialize_and_load_midi_port_states ();
82         _do_initial_engine_setup ();
83
84         // now push the sate to the backend
85         push_current_state_to_backend (false);
86 }
87
88
89 EngineStateController::~EngineStateController ()
90 {
91 }
92
93
94 void
95 EngineStateController::set_session (Session* session)
96 {
97         _session = session;
98         _session->SessionLoaded.connect_same_thread (session_connections, boost::bind (&EngineStateController::_on_session_loaded, this));
99 }
100
101
102 void
103 EngineStateController::remove_session ()
104 {
105         session_connections.drop_connections ();
106         _session = 0;
107 }
108
109
110 XMLNode&
111 EngineStateController::serialize_audio_midi_settings ()
112 {
113
114         XMLNode* root = new XMLNode ("AudioMidiSettings");
115
116         _serialize_engine_states (root);
117         _serialize_midi_port_states (root);
118
119         return *root;
120 }
121
122
123 void
124 EngineStateController::save_audio_midi_settings ()
125 {
126         Config->add_extra_xml (serialize_audio_midi_settings ());
127         Config->save_state ();
128 }
129
130
131 void
132 EngineStateController::_deserialize_and_load_engine_states ()
133 {
134         XMLNode* audio_midi_settings_root = ARDOUR::Config->extra_xml ("AudioMidiSettings");
135
136         if (!audio_midi_settings_root) {
137                 return;
138         }
139
140         XMLNode* engine_states = audio_midi_settings_root->child ("EngineStates");
141
142         if (!engine_states) {
143                 return;
144         }
145
146         XMLNodeList state_nodes_list = engine_states->children ();
147         XMLNodeConstIterator state_node_iter = state_nodes_list.begin ();
148
149         for (; state_node_iter != state_nodes_list.end (); ++state_node_iter) {
150
151                 XMLNode* state_node = *state_node_iter;
152                 StatePtr engine_state (new State);
153                 XMLProperty const * prop = NULL;
154
155                 if ((prop = state_node->property ("backend-name")) == 0) {
156                         continue;
157                 }
158                 engine_state->backend_name = prop->value ();
159
160                 if ((prop = state_node->property ("device-name")) == 0) {
161                         continue;
162                 }
163                 engine_state->device_name = prop->value ();
164
165                 if ((prop = state_node->property ("sample-rate")) == 0) {
166                         continue;
167                 }
168                 engine_state->sample_rate = atoi (prop->value ());
169
170                 if ((prop = state_node->property ("buffer-size")) == 0) {
171                         continue;
172                 }
173                 engine_state->buffer_size = atoi (prop->value ());
174
175                 if ((prop = state_node->property ("active")) == 0) {
176                         continue;
177                 }
178                 engine_state->active = string_is_affirmative (prop->value ());
179
180                 XMLNodeList state_children_list = state_node->children ();
181                 XMLNodeConstIterator state_child_iter = state_children_list.begin ();
182
183                 for (; state_child_iter != state_children_list.end (); ++state_child_iter) {
184                         XMLNode* state_child = *state_child_iter;
185
186                         if (state_child->name () == "InputConfiguration") {
187
188                                 XMLNodeList input_states_nodes = state_child->children ();
189                                 XMLNodeConstIterator input_state_node_iter = input_states_nodes.begin ();
190                                 PortStateList& input_states = engine_state->input_channel_states;
191
192                                 for (; input_state_node_iter != input_states_nodes.end (); ++input_state_node_iter) {
193
194                                         XMLNode* input_state_node = *input_state_node_iter;
195
196                                         if (input_state_node->name () != "input") {
197                                                 continue;
198                                         }
199                                         PortState input_state (input_state_node->name ());
200
201                                         if ((prop = input_state_node->property ("name")) == 0) {
202                                                 continue;
203                                         }
204                                         input_state.name = prop->value ();
205
206                                         if ((prop = input_state_node->property ("active")) == 0) {
207                                                 continue;
208                                         }
209                                         input_state.active = string_is_affirmative (prop->value ());
210
211                                         input_states.push_back (input_state);
212                                 }
213
214                         } else if (state_child->name () == "MultiOutConfiguration") {
215
216                                 XMLNodeList multi_out_state_nodes = state_child->children ();
217                                 XMLNodeConstIterator multi_out_state_node_iter = multi_out_state_nodes.begin ();
218                                 PortStateList& multi_out_states = engine_state->multi_out_channel_states;
219
220                                 for (; multi_out_state_node_iter != multi_out_state_nodes.end (); ++multi_out_state_node_iter) {
221
222                                         XMLNode* multi_out_state_node = *multi_out_state_node_iter;
223
224                                         if (multi_out_state_node->name () != "output") {
225                                                 continue;
226                                         }
227                                         PortState multi_out_state (multi_out_state_node->name ());
228
229                                         if ((prop = multi_out_state_node->property ("name")) == 0) {
230                                                 continue;
231                                         }
232                                         multi_out_state.name = prop->value ();
233
234                                         if ((prop = multi_out_state_node->property ("active")) == 0) {
235                                                 continue;
236                                         }
237                                         multi_out_state.active = string_is_affirmative (prop->value ());
238
239                                         multi_out_states.push_back (multi_out_state);
240                                 }
241                         } else if (state_child->name () == "StereoOutConfiguration") {
242
243                                 XMLNodeList stereo_out_state_nodes = state_child->children ();
244                                 XMLNodeConstIterator stereo_out_state_node_iter = stereo_out_state_nodes.begin ();
245                                 PortStateList& stereo_out_states = engine_state->stereo_out_channel_states;
246
247                                 for (; stereo_out_state_node_iter != stereo_out_state_nodes.end (); ++stereo_out_state_node_iter) {
248
249                                         XMLNode* stereo_out_state_node = *stereo_out_state_node_iter;
250
251                                         if (stereo_out_state_node->name () != "output") {
252                                                 continue;
253                                         }
254                                         PortState stereo_out_state (stereo_out_state_node->name ());
255
256                                         if ((prop = stereo_out_state_node->property ("name")) == 0) {
257                                                 continue;
258                                         }
259                                         stereo_out_state.name = prop->value ();
260
261                                         if ((prop = stereo_out_state_node->property ("active")) == 0) {
262                                                 continue;
263                                         }
264                                         stereo_out_state.active = string_is_affirmative (prop->value ());
265
266                                         stereo_out_states.push_back (stereo_out_state);
267                                 }
268                         }
269                 }
270
271                 _states.push_back (engine_state);
272         }
273 }
274
275
276 void
277 EngineStateController::_deserialize_and_load_midi_port_states ()
278 {
279         XMLNode* audio_midi_settings_root = ARDOUR::Config->extra_xml ("AudioMidiSettings");
280
281         if (!audio_midi_settings_root) {
282                 return;
283         }
284
285         XMLNode* midi_states = audio_midi_settings_root->child ("MidiStates");
286
287         if (!midi_states) {
288                 return;
289         }
290
291         XMLNodeList state_nodes_list = midi_states->children ();
292         XMLNodeConstIterator state_node_iter = state_nodes_list.begin ();
293         for (; state_node_iter != state_nodes_list.end (); ++state_node_iter) {
294
295                 XMLNode* state_node = *state_node_iter;
296                 if (state_node->name () == "MidiInputs") {
297
298                         XMLNodeList input_state_nodes = state_node->children ();
299                         XMLNodeConstIterator input_state_node_iter = input_state_nodes.begin ();
300                         _midi_inputs.clear ();
301
302                         for (; input_state_node_iter != input_state_nodes.end (); ++input_state_node_iter) {
303
304                                 XMLNode* input_state_node = *input_state_node_iter;
305                                 XMLProperty const * prop = NULL;
306
307                                 if (input_state_node->name () != "input") {
308                                         continue;
309                                 }
310                                 MidiPortState input_state (input_state_node->name ());
311
312                                 if ((prop = input_state_node->property ("name")) == 0) {
313                                         continue;
314                                 }
315                                 input_state.name = prop->value ();
316
317                                 if ((prop = input_state_node->property ("active")) == 0) {
318                                         continue;
319                                 }
320                                 input_state.active = string_is_affirmative (prop->value ());
321
322                                 if ((prop = input_state_node->property ("scene-connected")) == 0) {
323                                         continue;
324                                 }
325                                 input_state.scene_connected = string_is_affirmative (prop->value ());
326
327                                 if ((prop = input_state_node->property ("mtc-in")) == 0) {
328                                         continue;
329                                 }
330                                 input_state.mtc_in = string_is_affirmative (prop->value ());
331
332                                 _midi_inputs.push_back (input_state);
333                         }
334
335                 } else if (state_node->name () == "MidiOutputs") {
336
337                         XMLNodeList output_state_nodes = state_node->children ();
338                         XMLNodeConstIterator output_state_node_iter = output_state_nodes.begin ();
339                         _midi_outputs.clear ();
340
341                         for (; output_state_node_iter != output_state_nodes.end (); ++output_state_node_iter) {
342
343                                 XMLNode* output_state_node = *output_state_node_iter;
344                                 XMLProperty const * prop = NULL;
345
346                                 if (output_state_node->name () != "output") {
347                                         continue;
348                                 }
349                                 MidiPortState output_state (output_state_node->name ());
350
351                                 if ((prop = output_state_node->property ("name")) == 0) {
352                                         continue;
353                                 }
354                                 output_state.name = prop->value ();
355
356                                 if ((prop = output_state_node->property ("active")) == 0) {
357                                         continue;
358                                 }
359                                 output_state.active = string_is_affirmative (prop->value ());
360
361                                 if ((prop = output_state_node->property ("scene-connected")) == 0) {
362                                         continue;
363                                 }
364                                 output_state.scene_connected = string_is_affirmative (prop->value ());
365
366                                 if ((prop = output_state_node->property ("mtc-in")) == 0) {
367                                         continue;
368                                 }
369                                 output_state.mtc_in = string_is_affirmative (prop->value ());
370
371                                 _midi_outputs.push_back (output_state);
372                         }
373                 }
374         }
375 }
376
377
378 void
379 EngineStateController::_serialize_engine_states (XMLNode* audio_midi_settings_node)
380 {
381         if (!audio_midi_settings_node) {
382                 return;
383         }
384
385         // clean up state data first
386         audio_midi_settings_node->remove_nodes_and_delete ("EngineStates" );
387
388         XMLNode* engine_states = new XMLNode ("EngineStates" );
389
390         StateList::const_iterator state_iter = _states.begin ();
391         for (; state_iter != _states.end (); ++state_iter) {
392
393                 StatePtr state_ptr = *state_iter;
394
395                 // create new node for the state
396                 XMLNode* state_node = new XMLNode ("State");
397
398                 state_node->add_property ("backend-name", state_ptr->backend_name);
399                 state_node->add_property ("device-name", state_ptr->device_name);
400                 state_node->add_property ("sample-rate", state_ptr->sample_rate);
401                 state_node->add_property ("buffer-size", state_ptr->buffer_size);
402                 state_node->add_property ("active", state_ptr->active ? "yes" : "no");
403
404                 // store channel states:
405                 // inputs
406                 XMLNode* input_config_node = new XMLNode ("InputConfiguration");
407                 PortStateList& input_channels = state_ptr->input_channel_states;
408                 PortStateList::const_iterator input_state_iter = input_channels.begin ();
409                 for (; input_state_iter != input_channels.end (); ++input_state_iter) {
410                         XMLNode* input_state_node = new XMLNode ("input");
411                         input_state_node->add_property ("name", input_state_iter->name);
412                         input_state_node->add_property ("active", input_state_iter->active ? "yes" : "no");
413                         input_config_node->add_child_nocopy (*input_state_node);
414                 }
415                 state_node->add_child_nocopy (*input_config_node);
416
417                 // multi out outputs
418                 XMLNode* multi_out_config_node = new XMLNode ("MultiOutConfiguration");
419                 PortStateList& multi_out_channels = state_ptr->multi_out_channel_states;
420                 PortStateList::const_iterator multi_out_state_iter = multi_out_channels.begin ();
421                 for (; multi_out_state_iter != multi_out_channels.end (); ++multi_out_state_iter) {
422                         XMLNode* multi_out_state_node = new XMLNode ("output" );
423                         multi_out_state_node->add_property ("name", multi_out_state_iter->name);
424                         multi_out_state_node->add_property ("active", multi_out_state_iter->active ? "yes" : "no");
425                         multi_out_config_node->add_child_nocopy (*multi_out_state_node);
426                 }
427                 state_node->add_child_nocopy (*multi_out_config_node);
428
429                 // stereo out outputs
430                 XMLNode* stereo_out_config_node = new XMLNode ("StereoOutConfiguration");
431                 PortStateList& stereo_out_channels = state_ptr->stereo_out_channel_states;
432                 PortStateList::const_iterator stereo_out_state_iter = stereo_out_channels.begin ();
433                 for (; stereo_out_state_iter != stereo_out_channels.end (); ++stereo_out_state_iter) {
434                         XMLNode* stereo_out_state_node = new XMLNode ("output" );
435                         stereo_out_state_node->add_property ("name", stereo_out_state_iter->name);
436                         stereo_out_state_node->add_property ("active", stereo_out_state_iter->active ? "yes" : "no");
437                         stereo_out_config_node->add_child_nocopy (*stereo_out_state_node);
438                 }
439                 state_node->add_child_nocopy (*stereo_out_config_node);
440
441                 engine_states->add_child_nocopy (*state_node);
442         }
443
444         audio_midi_settings_node->add_child_nocopy (*engine_states);
445 }
446
447
448 void
449 EngineStateController::_serialize_midi_port_states (XMLNode* audio_midi_settings_node)
450 {
451         if (!audio_midi_settings_node) {
452                 return;
453         }
454
455         // clean up state data first
456         audio_midi_settings_node->remove_nodes_and_delete ("MidiStates" );
457
458         XMLNode* midi_states_node = new XMLNode ("MidiStates" );
459
460         XMLNode* midi_input_states_node = new XMLNode ("MidiInputs" );
461         MidiPortStateList::const_iterator midi_input_state_iter = _midi_inputs.begin ();
462         for (; midi_input_state_iter != _midi_inputs.end (); ++midi_input_state_iter) {
463                 XMLNode* midi_input_node = new XMLNode ("input" );
464                 midi_input_node->add_property ("name", midi_input_state_iter->name);
465                 midi_input_node->add_property ("active", midi_input_state_iter->active ? "yes" : "no");
466                 midi_input_node->add_property ("scene_connected", midi_input_state_iter->scene_connected ? "yes" : "no");
467                 midi_input_node->add_property ("mtc-in", midi_input_state_iter->mtc_in ? "yes" : "no");
468                 midi_input_states_node->add_child_nocopy (*midi_input_node);
469         }
470         midi_states_node->add_child_nocopy (*midi_input_states_node);
471
472         XMLNode* midi_output_states_node = new XMLNode ("MidiOutputs" );
473         MidiPortStateList::const_iterator midi_output_state_iter = _midi_outputs.begin ();
474         for (; midi_output_state_iter != _midi_outputs.end (); ++midi_output_state_iter) {
475                 XMLNode* midi_output_node = new XMLNode ("output" );
476                 midi_output_node->add_property ("name", midi_output_state_iter->name);
477                 midi_output_node->add_property ("active", midi_output_state_iter->active ? "yes" : "no");
478                 midi_output_node->add_property ("scene_connected", midi_output_state_iter->scene_connected ? "yes" : "no");
479                 midi_output_node->add_property ("mtc-in", midi_output_state_iter->mtc_in ? "yes" : "no");
480                 midi_output_states_node->add_child_nocopy (*midi_output_node);
481         }
482         midi_states_node->add_child_nocopy (*midi_output_states_node);
483
484         audio_midi_settings_node->add_child_nocopy (*midi_states_node);
485 }
486
487
488 bool
489 EngineStateController::_apply_state (const StatePtr& state)
490 {
491         bool applied = false;
492
493         if (set_new_backend_as_current (state->backend_name)) {
494                 applied = set_new_device_as_current (state->device_name);
495         }
496
497         return applied;
498 }
499
500
501 void
502 EngineStateController::_do_initial_engine_setup ()
503 {
504         bool state_applied = false;
505
506         // if we have no saved state load default values
507         if (!_states.empty ()) {
508
509                 // look for last active state first
510                 StateList::const_iterator state_iter = _states.begin ();
511                 for (; state_iter != _states.end (); ++state_iter) {
512                         if ( (*state_iter)->active ) {
513                                 state_applied = _apply_state (*state_iter);
514                                 break;
515                         }
516                 }
517
518                 // last active state was not applied
519                 // try others
520                 if (!state_applied) {
521                         StateList::const_iterator state_iter = _states.begin ();
522                         for (; state_iter != _states.end (); ++state_iter) {
523                                 state_applied = _apply_state (*state_iter);
524                                 break;
525                         }
526                 }
527         }
528
529         if (!state_applied ){
530                 std::vector<const AudioBackendInfo*> backends = AudioEngine::instance ()->available_backends ();
531
532                 if (!backends.empty ()) {
533
534                         if (!set_new_backend_as_current (backends.front ()->name )) {
535                                 std::cerr << "\tfailed to set backend [" << backends.front ()->name << "]\n";
536                         }
537                 }
538
539         }
540 }
541
542
543 bool
544 EngineStateController::_validate_current_device_state ()
545 {
546         boost::shared_ptr<AudioBackend> backend = AudioEngine::instance ()->current_backend ();
547         assert (backend);
548
549         // check if device parameters from the state record are still valid
550         // validate sample rate
551         std::vector<float> sample_rates = backend->available_sample_rates (_current_state->device_name);
552
553         if (sample_rates.empty ()) {
554                 return false;
555         }
556
557         // check if session desired sample rate (if it's set) could be used with this device
558         if (_session != 0) {
559
560                 if ( !set_new_sample_rate_in_controller (_session->nominal_frame_rate ())) {
561                         if ( !set_new_sample_rate_in_controller (backend->default_sample_rate ()) ) {
562                                 if (!set_new_sample_rate_in_controller (sample_rates.front ()) ) {
563                                         return false;
564                                 }
565                         }
566                 }
567
568         } else {
569                 // check if current sample rate is supported because we have no session desired sample rate value
570                 if ( !set_new_sample_rate_in_controller (_current_state->sample_rate)) {
571                         if ( !set_new_sample_rate_in_controller (backend->default_sample_rate ()) ) {
572                                 if (!set_new_sample_rate_in_controller (sample_rates.front ()) ) {
573                                         return false;
574                                 }
575                         }
576                 }
577         }
578
579         // validate buffer size
580         std::vector<pframes_t> buffer_sizes = backend->available_buffer_sizes (_current_state->device_name);
581         // check if buffer size is supported
582         std::vector<pframes_t>::iterator bs_iter = std::find (buffer_sizes.begin (), buffer_sizes.end (), _current_state->buffer_size);
583         // if current is not found switch to default if is supported
584         if (bs_iter == buffer_sizes.end ()) {
585                 bs_iter = std::find (buffer_sizes.begin (), buffer_sizes.end (), backend->default_buffer_size (_current_state->device_name));
586
587                 if (bs_iter != buffer_sizes.end ()) {
588                         _current_state->buffer_size = backend->default_buffer_size (_current_state->device_name);
589                 } else {
590                         if (!buffer_sizes.empty ()) {
591                                 _current_state->buffer_size = buffer_sizes.front ();
592                         }
593                 }
594
595         }
596
597         return true;
598 }
599
600
601 void
602 EngineStateController::_update_ltc_source_port ()
603 {
604         // this method is called if the list of ports is changed
605
606         // check that ltc-in port from Config still exists
607         if (_audio_input_port_exists (get_ltc_source_port ())) {
608                 // audio port, that was saved in Config, exists
609                 return ;
610         }
611
612         //otherwise set first available audio port
613         if (!_current_state->input_channel_states.empty ()) {
614                 set_ltc_source_port (_current_state->input_channel_states.front ().name);
615                 return ;
616         }
617
618         // no available audio-in ports
619         set_ltc_source_port ("");
620 }
621
622 void
623 EngineStateController::_update_ltc_output_port ()
624 {
625         // this method is called if the list of ports is changed
626
627         // check that ltc-out port from Config still exists
628         if (_audio_output_port_exists (get_ltc_output_port ())) {
629                 // audio port, that was saved in Config, exists
630                 return ;
631         }
632
633         PortStateList* output_states;
634         if (Config->get_output_auto_connect () & AutoConnectMaster) {
635                 output_states = &_current_state->stereo_out_channel_states;
636         } else {
637                 output_states = &_current_state->multi_out_channel_states;
638         }
639
640         //otherwise set first available audio port
641         if (!output_states->empty ()) {
642                 set_ltc_output_port (output_states->front ().name);
643                 return ;
644         }
645
646         // no available audio-out ports
647         set_ltc_output_port ("");
648 }
649
650
651 bool
652 EngineStateController::_audio_input_port_exists (const std::string& port_name)
653 {
654         PortStateList::const_iterator iter = _current_state->input_channel_states.begin ();
655         for (; iter != _current_state->input_channel_states.end (); ++iter ) {
656                 if (iter->name == port_name)
657                         return true;
658         }
659         return false;
660 }
661
662 bool
663 EngineStateController::_audio_output_port_exists (const std::string& port_name)
664 {
665         PortStateList* output_states;
666         if (Config->get_output_auto_connect () & AutoConnectMaster) {
667                 output_states = &_current_state->stereo_out_channel_states;
668         } else {
669                 output_states = &_current_state->multi_out_channel_states;
670         }
671
672         PortStateList::const_iterator iter = output_states->begin ();
673         for (; iter != output_states->end (); ++iter ) {
674                 if (iter->name == port_name)
675                         return true;
676         }
677         return false;
678 }
679
680
681 const std::string&
682 EngineStateController::get_current_backend_name () const
683 {
684         return _current_state->backend_name;
685 }
686
687
688 const std::string&
689 EngineStateController::get_current_device_name () const
690 {
691         return _current_state->device_name;
692 }
693
694
695 void
696 EngineStateController::available_backends (std::vector<const AudioBackendInfo*>& available_backends)
697 {
698         available_backends = AudioEngine::instance ()->available_backends ();
699 }
700
701
702 void
703 EngineStateController::enumerate_devices (std::vector<AudioBackend::DeviceStatus>& device_vector) const
704 {
705         boost::shared_ptr<AudioBackend> backend = AudioEngine::instance ()->current_backend ();
706         assert (backend);
707         device_vector = backend->enumerate_devices ();
708 }
709
710
711 framecnt_t
712 EngineStateController::get_current_sample_rate () const
713 {
714         return _current_state->sample_rate;
715 }
716
717
718 framecnt_t
719 EngineStateController::get_default_sample_rate () const
720 {
721         boost::shared_ptr<AudioBackend> backend = AudioEngine::instance ()->current_backend ();
722         assert (backend);
723         return backend->default_sample_rate ();
724 }
725
726
727 void
728 EngineStateController::available_sample_rates_for_current_device (std::vector<float>& sample_rates) const
729 {
730         boost::shared_ptr<AudioBackend> backend = AudioEngine::instance ()->current_backend ();
731         assert (backend);
732         sample_rates = backend->available_sample_rates (_current_state->device_name);
733 }
734
735
736 uint32_t
737 EngineStateController::get_current_buffer_size () const
738 {
739         return _current_state->buffer_size;
740 }
741
742
743 uint32_t
744 EngineStateController::get_default_buffer_size () const
745 {
746         boost::shared_ptr<AudioBackend> backend = AudioEngine::instance ()->current_backend ();
747         assert (backend);
748         return backend->default_buffer_size (_current_state->device_name);
749 }
750
751
752 void
753 EngineStateController::available_buffer_sizes_for_current_device (std::vector<pframes_t>& buffer_sizes) const
754 {
755         boost::shared_ptr<AudioBackend> backend = AudioEngine::instance ()->current_backend ();
756         assert (backend);
757         buffer_sizes = backend->available_buffer_sizes (_current_state->device_name);
758 }
759
760
761 bool
762 EngineStateController::set_new_backend_as_current (const std::string& backend_name)
763 {
764         if (backend_name == AudioEngine::instance ()->current_backend_name ()) {
765                 return true;
766         }
767
768         boost::shared_ptr<AudioBackend> backend = AudioEngine::instance ()->set_backend (backend_name, PROGRAM_NAME, "");
769         if (backend)
770         {
771                 if (_current_state != NULL) {
772                         _current_state->active = false;
773                 }
774
775                 StateList::iterator found_state_iter = find_if (_states.begin (), _states.end (),
776                                                                 State::StatePredicate (backend_name, "None"));
777
778                 if (found_state_iter != _states.end ()) {
779                         // we found a record for new engine with None device - switch to it
780                         _current_state = *found_state_iter;
781                         _validate_current_device_state ();
782                 } else {
783                         // create new record for this engine with default device
784                         _current_state = boost::shared_ptr<State>(new State ());
785                         _current_state->backend_name = backend_name;
786                         _current_state->device_name = "None";
787                         _validate_current_device_state ();
788                         _states.push_front (_current_state);
789                 }
790
791                 push_current_state_to_backend (false);
792
793                 return true;
794         }
795
796         return false;
797 }
798
799
800 bool
801 EngineStateController::set_new_device_as_current (const std::string& device_name)
802 {
803         if (_current_state->device_name == device_name) {
804                 return true;
805         }
806
807         boost::shared_ptr<AudioBackend> backend = AudioEngine::instance ()->current_backend ();
808         assert (backend);
809
810         std::vector<AudioBackend::DeviceStatus> device_vector = backend->enumerate_devices ();
811
812         // validate the device
813         std::vector<AudioBackend::DeviceStatus>::iterator device_iter;
814         device_iter = std::find_if (device_vector.begin (), device_vector.end (), DevicePredicate (device_name));
815
816         // device is available
817         if (device_iter != device_vector.end ()) {
818
819                 boost::shared_ptr<State> previous_state (_current_state);
820
821                 // look through state list and find the record for this device and current engine
822                 StateList::iterator found_state_iter = find_if (_states.begin (), _states.end (),
823                                                                 State::StatePredicate (backend->name (), device_name));
824
825                 if (found_state_iter != _states.end ())
826                 {
827                         // we found a record for current engine and provided device name - switch to it
828
829                         _current_state = *found_state_iter;
830
831                         if (!_validate_current_device_state ()) {
832                                 _current_state = previous_state;
833                                 return false;
834                         }
835
836                 } else {
837
838                         // the record is not found, create new one
839                         _current_state = boost::shared_ptr<State>(new State ());
840
841                         _current_state->backend_name = backend->name ();
842                         _current_state->device_name = device_name;
843
844                         if (!_validate_current_device_state ()) {
845                                 _current_state = previous_state;
846                                 return false;
847                         }
848
849                         _states.push_front (_current_state);
850                 }
851
852                 if (previous_state != NULL) {
853                         previous_state->active = false;
854                 }
855
856                 push_current_state_to_backend (false);
857
858                 _last_used_real_device.clear ();
859
860                 if (device_name != "None") {
861                         _last_used_real_device = device_name;
862                 }
863
864                 return true;
865         }
866
867         // device is not supported by current backend
868         return false;
869 }
870
871
872 bool
873 EngineStateController::set_new_sample_rate_in_controller (framecnt_t sample_rate)
874 {
875         boost::shared_ptr<AudioBackend> backend = AudioEngine::instance ()->current_backend ();
876         assert (backend);
877
878         std::vector<float> sample_rates = backend->available_sample_rates (_current_state->device_name);
879         std::vector<float>::iterator iter = std::find (sample_rates.begin (), sample_rates.end (), (float)sample_rate);
880
881         if (iter != sample_rates.end ()) {
882                 _current_state->sample_rate = sample_rate;
883                 return true;
884         }
885
886         return false;
887 }
888
889
890 bool
891 EngineStateController::set_new_buffer_size_in_controller (pframes_t buffer_size)
892 {
893         boost::shared_ptr<AudioBackend> backend = AudioEngine::instance ()->current_backend ();
894         assert (backend);
895
896         std::vector<uint32_t> buffer_sizes = backend->available_buffer_sizes (_current_state->device_name);
897         std::vector<uint32_t>::iterator iter = std::find (buffer_sizes.begin (), buffer_sizes.end (), buffer_size);
898
899         if (iter != buffer_sizes.end ()) {
900                 _current_state->buffer_size = buffer_size;
901                 return true;
902         }
903
904         return false;
905 }
906
907
908 uint32_t
909 EngineStateController::get_available_inputs_count () const
910 {
911         uint32_t available_channel_count = 0;
912
913         PortStateList::const_iterator iter = _current_state->input_channel_states.begin ();
914
915         for (; iter != _current_state->input_channel_states.end (); ++iter) {
916                 if (iter->active) {
917                         ++available_channel_count;
918                 }
919         }
920
921         return available_channel_count;
922 }
923
924
925 uint32_t
926 EngineStateController::get_available_outputs_count () const
927 {
928         uint32_t available_channel_count = 0;
929
930         PortStateList* output_states;
931         if (Config->get_output_auto_connect () & AutoConnectMaster) {
932                 output_states = &_current_state->stereo_out_channel_states;
933         } else {
934                 output_states = &_current_state->multi_out_channel_states;
935         }
936
937         PortStateList::const_iterator iter = output_states->begin ();
938
939         for (; iter != output_states->end (); ++iter) {
940                 if (iter->active) {
941                         ++available_channel_count;
942                 }
943         }
944
945         return available_channel_count;
946 }
947
948
949 void
950 EngineStateController::get_physical_audio_inputs (std::vector<std::string>& port_names)
951 {
952         port_names.clear ();
953
954         PortStateList &input_states = _current_state->input_channel_states;
955
956         PortStateList::iterator iter = input_states.begin ();
957         for (; iter != input_states.end (); ++iter) {
958                 if (iter->active) {
959                         port_names.push_back (iter->name);
960                 }
961         }
962 }
963
964
965 void
966 EngineStateController::get_physical_audio_outputs (std::vector<std::string>& port_names)
967 {
968         port_names.clear ();
969
970         PortStateList* output_states;
971         if (Config->get_output_auto_connect () & AutoConnectMaster) {
972                 output_states = &_current_state->stereo_out_channel_states;
973         } else {
974                 output_states = &_current_state->multi_out_channel_states;
975         }
976
977         PortStateList::iterator iter = output_states->begin ();
978         for (; iter != output_states->end (); ++iter) {
979                 if (iter->active) {
980                         port_names.push_back (iter->name);
981                 }
982         }
983 }
984
985
986 void
987 EngineStateController::get_physical_midi_inputs (std::vector<std::string>& port_names)
988 {
989         port_names.clear ();
990
991         MidiPortStateList::iterator iter = _midi_inputs.begin ();
992         for (; iter != _midi_inputs.end (); ++iter) {
993                 if (iter->available && iter->active) {
994                         port_names.push_back (iter->name);
995                 }
996         }
997 }
998
999
1000 void
1001 EngineStateController::get_physical_midi_outputs (std::vector<std::string>& port_names)
1002 {
1003         port_names.clear ();
1004
1005         MidiPortStateList::iterator iter = _midi_outputs.begin ();
1006         for (; iter != _midi_outputs.end (); ++iter) {
1007                 if (iter->available && iter->active) {
1008                         port_names.push_back (iter->name);
1009                 }
1010         }
1011 }
1012
1013
1014 void
1015 EngineStateController::set_physical_audio_input_state (const std::string& port_name, bool state)
1016 {
1017         PortStateList &input_states = _current_state->input_channel_states;
1018         PortStateList::iterator found_state_iter;
1019         found_state_iter = std::find (input_states.begin (), input_states.end (), PortState (port_name));
1020
1021         if (found_state_iter != input_states.end () && found_state_iter->active != state ) {
1022                 found_state_iter->active = state;
1023                 AudioEngine::instance ()->reconnect_session_routes (true, false);
1024
1025                 InputConfigChanged ();
1026         }
1027 }
1028
1029
1030 void
1031 EngineStateController::set_physical_audio_output_state (const std::string& port_name, bool state)
1032 {
1033         PortStateList* output_states;
1034         if (Config->get_output_auto_connect () & AutoConnectMaster) {
1035                 output_states = &_current_state->stereo_out_channel_states;
1036         } else {
1037                 output_states = &_current_state->multi_out_channel_states;
1038         }
1039
1040         PortStateList::iterator target_state_iter;
1041         target_state_iter = std::find (output_states->begin (), output_states->end (), PortState (port_name));
1042
1043         if (target_state_iter != output_states->end () && target_state_iter->active != state ) {
1044                 target_state_iter->active = state;
1045
1046                 // if StereoOut mode is used
1047                 if (Config->get_output_auto_connect () & AutoConnectMaster) {
1048
1049                         // get next element
1050                         PortStateList::iterator next_state_iter (target_state_iter);
1051
1052                         // loopback
1053                         if (++next_state_iter == output_states->end ()) {
1054                                 next_state_iter = output_states->begin ();
1055                         }
1056
1057
1058                         // only two outputs should be enabled
1059                         if (output_states->size () <= 2) {
1060
1061                                 target_state_iter->active = true;
1062                                 next_state_iter->active = true;
1063
1064                         } else {
1065
1066                                 // if current was set to active - activate next and disable the rest
1067                                 if (target_state_iter->active ) {
1068                                         next_state_iter->active = true;
1069                                 } else {
1070                                         // if current was deactivated but the next is active
1071                                         if (next_state_iter->active) {
1072                                                 if (++next_state_iter == output_states->end ()) {
1073                                                         next_state_iter = output_states->begin ();
1074                                                 }
1075                                                 next_state_iter->active = true;
1076                                         } else {
1077                                                 // if current was deactivated but the previous is active - restore the state of current
1078                                                 target_state_iter->active = true; // state restored;
1079                                                 --target_state_iter; // switch to previous to make it stop point in the next cycle
1080                                                 target_state_iter->active = true;
1081                                         }
1082                                 }
1083
1084                                 // now deactivate the rest
1085                                 while (++next_state_iter != target_state_iter) {
1086
1087                                         if (next_state_iter == output_states->end ()) {
1088                                                 next_state_iter = output_states->begin ();
1089                                                 // we jumped, so additional check is required
1090                                                 if (next_state_iter == target_state_iter) {
1091                                                         break;
1092                                                 }
1093                                         }
1094
1095                                         next_state_iter->active = false;
1096                                 }
1097
1098                         }
1099                 }
1100
1101                 AudioEngine::instance ()->reconnect_session_routes (false, true);
1102                 OutputConfigChanged ();
1103         }
1104 }
1105
1106
1107 bool
1108 EngineStateController::get_physical_audio_input_state (const std::string& port_name)
1109 {
1110         bool state = false;
1111
1112         PortStateList &input_states = _current_state->input_channel_states;
1113         PortStateList::iterator found_state_iter;
1114         found_state_iter = std::find (input_states.begin (), input_states.end (), PortState (port_name));
1115
1116         if (found_state_iter != input_states.end ()) {
1117                 state = found_state_iter->active;
1118         }
1119
1120         return state;
1121 }
1122
1123
1124 bool
1125 EngineStateController::get_physical_audio_output_state (const std::string& port_name)
1126 {
1127         bool state = false;
1128
1129         PortStateList* output_states;
1130         if (Config->get_output_auto_connect () & AutoConnectMaster) {
1131                 output_states = &_current_state->stereo_out_channel_states;
1132         } else {
1133                 output_states = &_current_state->multi_out_channel_states;
1134         }
1135
1136         PortStateList::iterator found_state_iter;
1137         found_state_iter = std::find (output_states->begin (), output_states->end (), PortState (port_name));
1138
1139         if (found_state_iter != output_states->end ()) {
1140                 state = found_state_iter->active;
1141         }
1142
1143         return state;
1144 }
1145
1146
1147 void
1148 EngineStateController::set_physical_midi_input_state (const std::string& port_name, bool state) {
1149
1150         MidiPortStateList::iterator found_state_iter;
1151         found_state_iter = std::find (_midi_inputs.begin (), _midi_inputs.end (), MidiPortState (port_name));
1152
1153         if (found_state_iter != _midi_inputs.end () && found_state_iter->available && found_state_iter->active != state ) {
1154                 found_state_iter->active = state;
1155
1156                 if (_session) {
1157                         // reconnect MTC inputs as well
1158                         if (found_state_iter->mtc_in) {
1159                                 _session->reconnect_mtc_ports ();
1160                         }
1161                         _session->reconnect_mmc_ports (true);
1162                 }
1163
1164                 MIDIInputConfigChanged ();
1165         }
1166 }
1167
1168
1169 void
1170 EngineStateController::set_physical_midi_output_state (const std::string& port_name, bool state) {
1171
1172         MidiPortStateList::iterator found_state_iter;
1173         found_state_iter = std::find (_midi_outputs.begin (), _midi_outputs.end (), MidiPortState (port_name));
1174
1175         if (found_state_iter != _midi_outputs.end () && found_state_iter->available && found_state_iter->active != state ) {
1176                 found_state_iter->active = state;
1177
1178                 if (_session) {
1179                         _session->reconnect_mmc_ports (false);
1180                 }
1181
1182                 MIDIOutputConfigChanged ();
1183         }
1184 }
1185
1186
1187 bool
1188 EngineStateController::get_physical_midi_input_state (const std::string& port_name, bool& scene_connected) {
1189
1190         bool state = false;
1191
1192         MidiPortStateList::iterator found_state_iter;
1193         found_state_iter = std::find (_midi_inputs.begin (), _midi_inputs.end (), MidiPortState (port_name));
1194
1195         if (found_state_iter != _midi_inputs.end () && found_state_iter->available) {
1196                 state = found_state_iter->active;
1197                 scene_connected = found_state_iter->scene_connected;
1198         }
1199
1200         return state;
1201 }
1202
1203
1204 bool
1205 EngineStateController::get_physical_midi_output_state (const std::string& port_name, bool& scene_connected) {
1206
1207         bool state = false;
1208
1209         MidiPortStateList::iterator found_state_iter;
1210         found_state_iter = std::find (_midi_outputs.begin (), _midi_outputs.end (), MidiPortState (port_name));
1211
1212         if (found_state_iter != _midi_outputs.end () && found_state_iter->available) {
1213                 state = found_state_iter->active;
1214                 scene_connected = found_state_iter->scene_connected;
1215         }
1216
1217         return state;
1218 }
1219
1220
1221 void
1222 EngineStateController::set_physical_midi_scene_in_connection_state (const std::string& port_name, bool state) {
1223
1224         MidiPortStateList::iterator found_state_iter;
1225         found_state_iter = std::find (_midi_inputs.begin (), _midi_inputs.end (), MidiPortState (port_name));
1226
1227         if (found_state_iter != _midi_inputs.end () && found_state_iter->available && found_state_iter->active ) {
1228                 found_state_iter->scene_connected = state;
1229
1230                 std::vector<std::string> ports;
1231                 ports.push_back (port_name);
1232                 MIDISceneInputConnectionChanged (ports, state);
1233         }
1234
1235 }
1236
1237
1238 void
1239 EngineStateController::set_physical_midi_scenen_out_connection_state (const std::string& port_name, bool state) {
1240
1241         MidiPortStateList::iterator found_state_iter;
1242         found_state_iter = std::find (_midi_outputs.begin (), _midi_outputs.end (), MidiPortState (port_name));
1243
1244         if (found_state_iter != _midi_outputs.end () && found_state_iter->available && found_state_iter->active ) {
1245                 found_state_iter->scene_connected = state;
1246
1247                 std::vector<std::string> ports;
1248                 ports.push_back (port_name);
1249                 MIDISceneOutputConnectionChanged (ports, state);
1250         }
1251
1252 }
1253
1254
1255 void
1256 EngineStateController::set_all_midi_scene_inputs_disconnected ()
1257 {
1258         MidiPortStateList::iterator iter = _midi_inputs.begin ();
1259         for (; iter != _midi_inputs.end (); ++iter) {
1260                 iter->scene_connected = false;
1261         }
1262
1263         std::vector<std::string> ports;
1264         MIDISceneInputConnectionChanged (ports, false);
1265 }
1266
1267
1268 void
1269 EngineStateController::set_all_midi_scene_outputs_disconnected ()
1270 {
1271         MidiPortStateList::iterator iter = _midi_outputs.begin ();
1272         for (; iter != _midi_outputs.end (); ++iter) {
1273                 iter->scene_connected = false;
1274         }
1275
1276         std::vector<std::string> ports;
1277         MIDISceneOutputConnectionChanged (ports, false);
1278 }
1279
1280
1281 void
1282 EngineStateController::set_mtc_source_port (const std::string& port_name)
1283 {
1284         MidiPortStateList::iterator iter = _midi_inputs.begin ();
1285         for (; iter != _midi_inputs.end (); ++iter) {
1286                 iter->mtc_in = false;
1287
1288                 if (iter->name == port_name) {
1289                         iter->mtc_in = true;
1290
1291                         if (_session) {
1292                                 _session->reconnect_mtc_ports ();
1293                         }
1294                 }
1295         }
1296
1297         if (_session && port_name.empty ()) {
1298                 _session->reconnect_mtc_ports ();
1299         }
1300
1301         MTCInputChanged (port_name);
1302 }
1303
1304
1305 void
1306 EngineStateController::set_state_to_all_inputs (bool state)
1307 {
1308         bool something_changed = false;
1309
1310         PortStateList::iterator iter = _current_state->input_channel_states.begin ();
1311         for (; iter != _current_state->input_channel_states.end (); ++iter) {
1312                 if (iter->active != state) {
1313                         iter->active = state;
1314                         something_changed = true;
1315                 }
1316         }
1317
1318         if (something_changed) {
1319                 AudioEngine::instance ()->reconnect_session_routes (true, false);
1320                 InputConfigChanged ();
1321         }
1322 }
1323
1324
1325 void
1326 EngineStateController::set_state_to_all_outputs (bool state)
1327 {
1328         // unapplicable in Stereo Out mode, just return
1329         if (Config->get_output_auto_connect () & AutoConnectMaster) {
1330                 return;
1331         }
1332
1333         bool something_changed = false;
1334
1335         PortStateList::iterator iter = _current_state->multi_out_channel_states.begin ();
1336         for (; iter != _current_state->multi_out_channel_states.end (); ++iter) {
1337                 if (iter->active != state) {
1338                         iter->active = state;
1339                         something_changed = true;
1340                 }
1341         }
1342
1343         if (something_changed) {
1344                 AudioEngine::instance ()->reconnect_session_routes (false, true);
1345                 OutputConfigChanged ();
1346         }
1347 }
1348
1349
1350 void
1351 EngineStateController::get_physical_audio_input_states (std::vector<PortState>& channel_states)
1352 {
1353         PortStateList &input_states = _current_state->input_channel_states;
1354         channel_states.assign (input_states.begin (), input_states.end ());
1355 }
1356
1357
1358 void
1359 EngineStateController::get_physical_audio_output_states (std::vector<PortState>& channel_states)
1360 {
1361         PortStateList* output_states;
1362         if (Config->get_output_auto_connect () & AutoConnectMaster) {
1363                 output_states = &_current_state->stereo_out_channel_states;
1364         } else {
1365                 output_states = &_current_state->multi_out_channel_states;
1366         }
1367
1368         channel_states.assign (output_states->begin (), output_states->end ());
1369 }
1370
1371
1372 void
1373 EngineStateController::get_physical_midi_input_states (std::vector<MidiPortState>& channel_states)
1374 {
1375         channel_states.clear ();
1376
1377         MidiPortStateList::iterator iter = _midi_inputs.begin ();
1378
1379         for (; iter != _midi_inputs.end (); ++iter ) {
1380                 if (iter->available) {
1381                         MidiPortState state (iter->name);
1382                         state.active = iter->active;
1383                         state.available = true;
1384                         state.scene_connected = iter->scene_connected;
1385                         state.mtc_in = iter->mtc_in;
1386                         channel_states.push_back (state);
1387                 }
1388         }
1389 }
1390
1391 void
1392 EngineStateController::get_physical_midi_output_states (std::vector<MidiPortState>& channel_states)
1393 {
1394         channel_states.clear ();
1395
1396         MidiPortStateList::iterator iter = _midi_outputs.begin ();
1397
1398         for (; iter != _midi_outputs.end (); ++iter ) {
1399                 if (iter->available) {
1400                         MidiPortState state (iter->name);
1401                         state.active = iter->active;
1402                         state.available = true;
1403                         state.scene_connected = iter->scene_connected;
1404                         state.mtc_in = iter->mtc_in;
1405                         channel_states.push_back (state);
1406                 }
1407         }
1408 }
1409
1410
1411 void
1412 EngineStateController::_on_session_loaded ()
1413 {
1414         if (!_session) {
1415                 return;
1416         }
1417
1418         AudioEngine::instance ()->reconnect_session_routes (true, true);
1419         _session->reconnect_mtc_ports ();
1420         _session->reconnect_mmc_ports (true);
1421         _session->reconnect_mmc_ports (false);
1422
1423         // This is done during session construction
1424         // _session->reconnect_ltc_input ();
1425         // _session->reconnect_ltc_output ();
1426
1427         framecnt_t desired_sample_rate = _session->nominal_frame_rate ();
1428         if ( desired_sample_rate > 0 && set_new_sample_rate_in_controller (desired_sample_rate))
1429         {
1430                 push_current_state_to_backend (false);
1431                 SampleRateChanged (); // emit a signal
1432         }
1433 }
1434
1435
1436 void
1437 EngineStateController::_on_sample_rate_change (framecnt_t new_sample_rate)
1438 {
1439         if (_current_state->sample_rate != new_sample_rate) {
1440
1441                 // if sample rate has been changed
1442                 framecnt_t sample_rate_to_set = new_sample_rate;
1443                 if (AudioEngine::instance ()->session ()) {
1444                         // and we have current session we should restore it back to the one tracks uses
1445                         sample_rate_to_set = AudioEngine::instance ()->session ()->frame_rate ();
1446                 }
1447
1448                 if ( !set_new_sample_rate_in_controller (sample_rate_to_set)) {
1449                         // if sample rate can't be set
1450                         // switch to NONE device
1451                         set_new_device_as_current ("None");
1452                         DeviceListChanged (false);
1453                         DeviceError ();
1454                 }
1455         }
1456
1457         SampleRateChanged (); // emit a signal
1458 }
1459
1460
1461 void
1462 EngineStateController::_on_buffer_size_change (pframes_t new_buffer_size)
1463 {
1464         if (_current_state->buffer_size != new_buffer_size) {
1465                 _current_state->buffer_size = new_buffer_size;
1466         }
1467
1468         BufferSizeChanged (); // emit a signal
1469 }
1470
1471
1472 void
1473 EngineStateController::_on_device_list_change ()
1474 {
1475         bool current_device_disconnected = false;
1476
1477         boost::shared_ptr<AudioBackend> backend = AudioEngine::instance ()->current_backend ();
1478         assert (backend);
1479
1480         std::vector<AudioBackend::DeviceStatus> device_vector = backend->enumerate_devices ();
1481
1482         // find out out if current device is still available if it's not None
1483         if (_current_state->device_name != "None")
1484         {
1485                 std::vector<AudioBackend::DeviceStatus>::iterator device_iter;
1486                 device_iter = std::find_if (device_vector.begin (), device_vector.end (), DevicePredicate (_current_state->device_name));
1487
1488                 // if current device is not available any more - switch to None device
1489                 if (device_iter == device_vector.end ()) {
1490
1491                         StateList::iterator found_state_iter = find_if (_states.begin (), _states.end (),
1492                                                                         State::StatePredicate (_current_state->backend_name, "None"));
1493
1494                         if (found_state_iter != _states.end ()) {
1495                                 // found the record - switch to it
1496                                 _current_state = *found_state_iter;
1497                                 _validate_current_device_state ();
1498                         } else {
1499                                 // create new record for this engine with default device
1500                                 _current_state = boost::shared_ptr<State>(new State ());
1501                                 _current_state->backend_name = backend->name ();
1502                                 _current_state->device_name = "None";
1503                                 _validate_current_device_state ();
1504                                 _states.push_front (_current_state);
1505                         }
1506
1507                         push_current_state_to_backend (true);
1508                         current_device_disconnected = true;
1509                 }
1510         } else {
1511                 // if the device which was active before is available now - switch to it
1512
1513                 std::vector<AudioBackend::DeviceStatus>::iterator device_iter;
1514                 device_iter = std::find_if (device_vector.begin (), device_vector.end (), DevicePredicate (_last_used_real_device));
1515
1516                 if (device_iter != device_vector.end ()) {
1517                         StateList::iterator found_state_iter = find_if (_states.begin (), _states.end (),
1518                                                                         State::StatePredicate (_current_state->backend_name,
1519                                                                                               _last_used_real_device));
1520
1521                         if (found_state_iter != _states.end ()) {
1522
1523                                 boost::shared_ptr<State> previous_state (_current_state);
1524                                 _current_state = *found_state_iter;
1525
1526                                 if (_validate_current_device_state ()) {
1527                                         push_current_state_to_backend (false);
1528                                 } else {
1529                                         // cannot use this device right now
1530                                         _last_used_real_device.clear ();
1531                                         _current_state = previous_state;
1532                                 }
1533                         }
1534                 }
1535         }
1536
1537         DeviceListChanged (current_device_disconnected); // emit a signal
1538 }
1539
1540
1541 void
1542 EngineStateController::_update_device_channels_state ()
1543 {
1544         boost::shared_ptr<AudioBackend> backend = AudioEngine::instance ()->current_backend ();
1545         assert (backend);
1546
1547         // update audio input states
1548         std::vector<std::string> phys_audio_inputs;
1549         backend->get_physical_inputs (DataType::AUDIO, phys_audio_inputs);
1550
1551         PortStateList new_input_states;
1552         PortStateList &input_states = _current_state->input_channel_states;
1553
1554         std::vector<std::string>::const_iterator input_iter = phys_audio_inputs.begin ();
1555         for (; input_iter != phys_audio_inputs.end (); ++input_iter) {
1556
1557                 PortState state (*input_iter);
1558                 state.active = true;
1559                 PortStateList::const_iterator found_state_iter = std::find (input_states.begin (), input_states.end (), state);
1560
1561                 if (found_state_iter != input_states.end ()) {
1562                         new_input_states.push_back (*found_state_iter);
1563                 } else {
1564                         new_input_states.push_back (state);
1565                 }
1566         }
1567         _current_state->input_channel_states = new_input_states;
1568
1569         // update audio output states (multi out mode)
1570         std::vector<std::string> phys_audio_outputs;
1571         backend->get_physical_outputs (DataType::AUDIO, phys_audio_outputs);
1572
1573         PortStateList new_output_states;
1574         PortStateList &output_multi_states = _current_state->multi_out_channel_states;
1575
1576         std::vector<std::string>::const_iterator output_iter = phys_audio_outputs.begin ();
1577         for (; output_iter != phys_audio_outputs.end (); ++output_iter) {
1578
1579                 PortState state (*output_iter);
1580                 state.active = true;
1581                 PortStateList::const_iterator found_state_iter = std::find (output_multi_states.begin (), output_multi_states.end (), state);
1582
1583                 if (found_state_iter != output_multi_states.end ()) {
1584                         new_output_states.push_back (*found_state_iter);
1585                 } else {
1586                         new_output_states.push_back (state);
1587                 }
1588         }
1589
1590         _current_state->multi_out_channel_states = new_output_states;
1591
1592         // update audio output states (stereo out mode)
1593         new_output_states.clear ();
1594         PortStateList &output_stereo_states = _current_state->stereo_out_channel_states;
1595
1596         output_iter = phys_audio_outputs.begin ();
1597         for (; output_iter != phys_audio_outputs.end (); ++output_iter) {
1598
1599                 PortState state (*output_iter);
1600                 state.active = true;
1601                 PortStateList::const_iterator found_state_iter = std::find (output_stereo_states.begin (), output_stereo_states.end (), state);
1602
1603                 if (found_state_iter != output_stereo_states.end ()) {
1604                         new_output_states.push_back (*found_state_iter);
1605                 } else {
1606                         new_output_states.push_back (state);
1607                 }
1608         }
1609
1610         _current_state->stereo_out_channel_states = new_output_states;
1611         _refresh_stereo_out_channel_states ();
1612
1613
1614         // update midi ports: unlike audio ports which states are saved per device
1615         // each midi port state is saved individualy
1616         // so get all midi ports from the backend
1617         // and compare to the list of midi ports we have
1618         // if physical port is new, add it to our state list
1619         // if physical port is present in our state list - mark it available
1620         // if there is no corresponding physical port to one we have in a list - leave it unavailable
1621         MidiPortStateList::iterator iter = _midi_inputs.begin ();
1622         for (; iter != _midi_inputs.end (); ++iter) {
1623                 iter->available = false;
1624         }
1625
1626         for (iter = _midi_outputs.begin (); iter != _midi_outputs.end (); ++iter) {
1627                 iter->available = false;
1628         }
1629
1630         // update midi input ports
1631         std::vector<std::string> phys_midi_inputs;
1632         backend->get_physical_inputs (DataType::MIDI, phys_midi_inputs);
1633
1634         std::vector<std::string>::const_iterator midi_input_iter = phys_midi_inputs.begin ();
1635         for (; midi_input_iter != phys_midi_inputs.end (); ++midi_input_iter) {
1636
1637                 MidiPortState state (*midi_input_iter);
1638                 state.active = false;
1639                 state.available = true;
1640                 MidiPortStateList::iterator found_state_iter = std::find (_midi_inputs.begin (), _midi_inputs.end (), state);
1641
1642                 if (found_state_iter != _midi_inputs.end ()) {
1643                         found_state_iter->available = true;
1644                 } else {
1645                         _midi_inputs.push_back (state);
1646                 }
1647         }
1648
1649         // update midi output ports
1650         std::vector<std::string> phys_midi_outputs;
1651         backend->get_physical_outputs (DataType::MIDI, phys_midi_outputs);
1652
1653         std::vector<std::string>::const_iterator midi_output_iter = phys_midi_outputs.begin ();
1654         for (; midi_output_iter != phys_midi_outputs.end (); ++midi_output_iter) {
1655
1656                 MidiPortState state (*midi_output_iter);
1657                 state.active = false;
1658                 state.available = true;
1659                 MidiPortStateList::iterator found_state_iter = std::find (_midi_outputs.begin (), _midi_outputs.end (), state);
1660
1661                 if (found_state_iter != _midi_outputs.end ()) {
1662                         found_state_iter->available = true;
1663                 } else {
1664                         _midi_outputs.push_back (state);
1665                 }
1666         }
1667 }
1668
1669
1670 void
1671 EngineStateController::_refresh_stereo_out_channel_states ()
1672 {
1673         PortStateList &output_states = _current_state->stereo_out_channel_states;
1674         PortStateList::iterator active_iter = output_states.begin ();
1675
1676         for (; active_iter != output_states.end (); ++active_iter) {
1677                 if (active_iter->active) {
1678                         break;
1679                 }
1680         }
1681
1682         uint32_t pending_active_channels = 2;
1683         PortStateList::iterator iter = output_states.begin ();
1684         // if found active
1685         if (active_iter != output_states.end ()) {
1686                 iter = active_iter;
1687                 if (++iter == output_states.end ()) {
1688                         iter = output_states.begin ();
1689                 }
1690
1691                 (iter++)->active = true;
1692                 pending_active_channels = 0;
1693         }
1694
1695         // drop the rest of the states to false (until we reach the end or first existing active channel)
1696         for (; iter != output_states.end () && iter != active_iter; ++iter) {
1697                 if (pending_active_channels) {
1698                         iter->active = true;
1699                         --pending_active_channels;
1700                 } else {
1701                         iter->active = false;
1702                 }
1703         }
1704 }
1705
1706
1707 void
1708 EngineStateController::_on_engine_running ()
1709 {
1710         AudioEngine::instance ()->reconnect_session_routes (true, true);
1711         _current_state->active = true;
1712
1713         EngineRunning (); // emit a signal
1714 }
1715
1716
1717 void
1718 EngineStateController::_on_engine_stopped ()
1719 {
1720         EngineStopped ();
1721 }
1722
1723
1724 void
1725 EngineStateController::_on_engine_halted ()
1726 {
1727         EngineHalted ();
1728 }
1729
1730
1731 void
1732 EngineStateController::_on_device_error ()
1733 {
1734         set_new_device_as_current ("None");
1735         push_current_state_to_backend (true);
1736         DeviceListChanged (false);
1737         DeviceError ();
1738 }
1739
1740
1741 void
1742 EngineStateController::_on_parameter_changed (const std::string& parameter_name)
1743 {
1744         if (parameter_name == "output-auto-connect") {
1745
1746                 AudioEngine::instance ()->reconnect_session_routes (false, true);
1747                 OutputConfigChanged (); // emit a signal
1748                 OutputConnectionModeChanged (); // emit signal
1749         }
1750 }
1751
1752
1753 void
1754 EngineStateController::_on_ports_registration_update ()
1755 {
1756         _update_device_channels_state ();
1757
1758         // update MIDI connections
1759         if (_session) {
1760                 _session->reconnect_midi_scene_ports (true);
1761                 _session->reconnect_midi_scene_ports (false);
1762
1763                 _session->reconnect_mtc_ports ();
1764
1765                 _session->reconnect_mmc_ports (true);
1766                 _session->reconnect_mmc_ports (false);
1767
1768                 _session->reconnect_ltc_input ();
1769                 _session->reconnect_ltc_output ();
1770         }
1771
1772         _update_ltc_source_port ();
1773         _update_ltc_output_port ();
1774
1775         PortRegistrationChanged (); // emit a signal
1776 }
1777
1778
1779 bool
1780 EngineStateController::push_current_state_to_backend (bool start)
1781 {
1782         boost::shared_ptr<AudioBackend> backend = AudioEngine::instance ()->current_backend ();
1783
1784         if (!backend) {
1785                 return false;
1786         }
1787
1788         // check if anything changed
1789         bool state_changed = (_current_state->device_name != backend->device_name ()) ||
1790                 (_current_state->sample_rate != backend->sample_rate ()) ||
1791                 (_current_state->buffer_size != backend->buffer_size ());
1792
1793         bool was_running = AudioEngine::instance ()->running ();
1794
1795         Glib::Threads::RecMutex::Lock sl (AudioEngine::instance ()->state_lock ());
1796         if (state_changed) {
1797
1798                 if (was_running) {
1799
1800                         if (_current_state->device_name != backend->device_name ()) {
1801                                 // device has been changed
1802                                 // the list of ports has been changed too
1803                                 // current ltc_source_port and ltc_output_port aren't available
1804                                 set_ltc_source_port ("");
1805                                 set_ltc_output_port ("");
1806                         }
1807
1808                         if (AudioEngine::instance ()->stop ()) {
1809                                 return false;
1810                         }
1811                 }
1812
1813                 int result = 0;
1814                 {
1815                         std::cout << "EngineStateController::Setting device: " << _current_state->device_name << std::endl;
1816                         if ((_current_state->device_name != backend->device_name ()) && (result = backend->set_device_name (_current_state->device_name))) {
1817                                 error << string_compose (_("Cannot set device name to %1"), get_current_device_name ()) << endmsg;
1818                         }
1819
1820                         if (!result ) {
1821                                 std::cout << "EngineStateController::Setting device sample rate " << _current_state->sample_rate << std::endl;
1822                                 result = backend->set_sample_rate (_current_state->sample_rate);
1823
1824                                 if (result) {
1825                                         error << string_compose (_("Cannot set sample rate to %1"), get_current_sample_rate ()) << endmsg;
1826                                 }
1827                         }
1828
1829                         if (!result ) {
1830                                 std::cout << "EngineStateController::Setting device buffer size " << _current_state->buffer_size << std::endl;
1831                                 result = backend->set_buffer_size (_current_state->buffer_size);
1832
1833                                 if (result) {
1834                                         error << string_compose (_("Cannot set buffer size to %1"), get_current_buffer_size ()) << endmsg;
1835                                 }
1836                         }
1837                 }
1838
1839                 if (result) // error during device setup
1840                 {
1841                         //switch to None device and notify about the issue
1842                         set_new_device_as_current ("None");
1843                         DeviceListChanged (false);
1844                         DeviceError ();
1845                 }
1846
1847                 if (AudioEngine::instance ()->backend_reset_requested ()) {
1848                         // device asked for reset, do not start engine now
1849                         // free sate lock and let Engine reset the device as it's required
1850                         return true;
1851                 }
1852         }
1853
1854         if (start || (was_running && state_changed)) {
1855                 if (AudioEngine::instance ()->start () && !AudioEngine::instance ()->is_reset_requested ()) {
1856                         //switch to None device and notify about the issue
1857                         set_new_device_as_current ("None");
1858                         AudioEngine::instance ()->start ();
1859                         DeviceListChanged (false);
1860                         DeviceError ();
1861                         return false;
1862                 }
1863         }
1864
1865         save_audio_midi_settings ();
1866
1867         return true;
1868 }
1869
1870
1871 std::string
1872 EngineStateController::get_mtc_source_port ()
1873 {
1874         MidiPortStateList::const_iterator state_iter = _midi_inputs.begin ();
1875         for (; state_iter != _midi_inputs.end (); ++state_iter) {
1876                 if (state_iter->available && state_iter->mtc_in) {
1877                         return (state_iter->name);
1878                 }
1879         }
1880
1881         return "";
1882 }
1883
1884 void
1885 EngineStateController::set_ltc_source_port (const std::string& port)
1886 {
1887         Config->set_ltc_source_port (port);
1888 }
1889
1890 std::string
1891 EngineStateController::get_ltc_source_port ()
1892 {
1893         return Config->get_ltc_source_port ();
1894 }
1895
1896 void
1897 EngineStateController::set_ltc_output_port (const std::string& port)
1898 {
1899         Config->set_ltc_output_port (port);
1900 }
1901
1902 std::string
1903 EngineStateController::get_ltc_output_port ()
1904 {
1905         return Config->get_ltc_output_port ();
1906 }
1907