2 Copyright (C) 2014 Waves Audio Ltd.
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.
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.
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.
20 #include "ardour/engine_state_controller.h"
22 #include "ardour/audioengine.h"
23 #include "ardour/session.h"
24 #include "ardour/rc_configuration.h"
25 #include "ardour/data_type.h"
27 #include "pbd/pthread_utils.h"
28 #include "pbd/error.h"
32 using namespace ARDOUR;
37 struct DevicePredicate
39 DevicePredicate (const std::string& device_name)
40 : _device_name (device_name)
43 bool operator ()(const AudioBackend::DeviceStatus& rhs)
45 return _device_name == rhs.name;
49 std::string _device_name;
53 EngineStateController*
54 EngineStateController::instance ()
56 static EngineStateController instance;
61 EngineStateController::EngineStateController ()
63 , _last_used_real_device ("")
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));
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));
77 /* Global configuration parameters update */
78 Config->ParameterChanged.connect_same_thread (update_connections, boost::bind (&EngineStateController::_on_parameter_changed, this, _1));
80 _deserialize_and_load_engine_states ();
81 _deserialize_and_load_midi_port_states ();
82 _do_initial_engine_setup ();
84 // now push the sate to the backend
85 push_current_state_to_backend (false);
89 EngineStateController::~EngineStateController ()
95 EngineStateController::set_session (Session* session)
98 _session->SessionLoaded.connect_same_thread (session_connections, boost::bind (&EngineStateController::_on_session_loaded, this));
103 EngineStateController::remove_session ()
105 session_connections.drop_connections ();
111 EngineStateController::serialize_audio_midi_settings ()
114 XMLNode* root = new XMLNode ("AudioMidiSettings");
116 _serialize_engine_states (root);
117 _serialize_midi_port_states (root);
124 EngineStateController::save_audio_midi_settings ()
126 Config->add_extra_xml (serialize_audio_midi_settings ());
127 Config->save_state ();
132 EngineStateController::_deserialize_and_load_engine_states ()
134 XMLNode* audio_midi_settings_root = ARDOUR::Config->extra_xml ("AudioMidiSettings");
136 if (!audio_midi_settings_root) {
140 XMLNode* engine_states = audio_midi_settings_root->child ("EngineStates");
142 if (!engine_states) {
146 XMLNodeList state_nodes_list = engine_states->children ();
147 XMLNodeConstIterator state_node_iter = state_nodes_list.begin ();
149 for (; state_node_iter != state_nodes_list.end (); ++state_node_iter) {
151 XMLNode* state_node = *state_node_iter;
152 StatePtr engine_state (new State);
153 XMLProperty const * prop = NULL;
155 if ((prop = state_node->property ("backend-name")) == 0) {
158 engine_state->backend_name = prop->value ();
160 if ((prop = state_node->property ("device-name")) == 0) {
163 engine_state->device_name = prop->value ();
165 if ((prop = state_node->property ("sample-rate")) == 0) {
168 engine_state->sample_rate = atoi (prop->value ());
170 if ((prop = state_node->property ("buffer-size")) == 0) {
173 engine_state->buffer_size = atoi (prop->value ());
175 if ((prop = state_node->property ("active")) == 0) {
178 engine_state->active = string_is_affirmative (prop->value ());
180 XMLNodeList state_children_list = state_node->children ();
181 XMLNodeConstIterator state_child_iter = state_children_list.begin ();
183 for (; state_child_iter != state_children_list.end (); ++state_child_iter) {
184 XMLNode* state_child = *state_child_iter;
186 if (state_child->name () == "InputConfiguration") {
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;
192 for (; input_state_node_iter != input_states_nodes.end (); ++input_state_node_iter) {
194 XMLNode* input_state_node = *input_state_node_iter;
196 if (input_state_node->name () != "input") {
199 PortState input_state (input_state_node->name ());
201 if ((prop = input_state_node->property ("name")) == 0) {
204 input_state.name = prop->value ();
206 if ((prop = input_state_node->property ("active")) == 0) {
209 input_state.active = string_is_affirmative (prop->value ());
211 input_states.push_back (input_state);
214 } else if (state_child->name () == "MultiOutConfiguration") {
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;
220 for (; multi_out_state_node_iter != multi_out_state_nodes.end (); ++multi_out_state_node_iter) {
222 XMLNode* multi_out_state_node = *multi_out_state_node_iter;
224 if (multi_out_state_node->name () != "output") {
227 PortState multi_out_state (multi_out_state_node->name ());
229 if ((prop = multi_out_state_node->property ("name")) == 0) {
232 multi_out_state.name = prop->value ();
234 if ((prop = multi_out_state_node->property ("active")) == 0) {
237 multi_out_state.active = string_is_affirmative (prop->value ());
239 multi_out_states.push_back (multi_out_state);
241 } else if (state_child->name () == "StereoOutConfiguration") {
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;
247 for (; stereo_out_state_node_iter != stereo_out_state_nodes.end (); ++stereo_out_state_node_iter) {
249 XMLNode* stereo_out_state_node = *stereo_out_state_node_iter;
251 if (stereo_out_state_node->name () != "output") {
254 PortState stereo_out_state (stereo_out_state_node->name ());
256 if ((prop = stereo_out_state_node->property ("name")) == 0) {
259 stereo_out_state.name = prop->value ();
261 if ((prop = stereo_out_state_node->property ("active")) == 0) {
264 stereo_out_state.active = string_is_affirmative (prop->value ());
266 stereo_out_states.push_back (stereo_out_state);
271 _states.push_back (engine_state);
277 EngineStateController::_deserialize_and_load_midi_port_states ()
279 XMLNode* audio_midi_settings_root = ARDOUR::Config->extra_xml ("AudioMidiSettings");
281 if (!audio_midi_settings_root) {
285 XMLNode* midi_states = audio_midi_settings_root->child ("MidiStates");
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) {
295 XMLNode* state_node = *state_node_iter;
296 if (state_node->name () == "MidiInputs") {
298 XMLNodeList input_state_nodes = state_node->children ();
299 XMLNodeConstIterator input_state_node_iter = input_state_nodes.begin ();
300 _midi_inputs.clear ();
302 for (; input_state_node_iter != input_state_nodes.end (); ++input_state_node_iter) {
304 XMLNode* input_state_node = *input_state_node_iter;
305 XMLProperty const * prop = NULL;
307 if (input_state_node->name () != "input") {
310 MidiPortState input_state (input_state_node->name ());
312 if ((prop = input_state_node->property ("name")) == 0) {
315 input_state.name = prop->value ();
317 if ((prop = input_state_node->property ("active")) == 0) {
320 input_state.active = string_is_affirmative (prop->value ());
322 if ((prop = input_state_node->property ("scene-connected")) == 0) {
325 input_state.scene_connected = string_is_affirmative (prop->value ());
327 if ((prop = input_state_node->property ("mtc-in")) == 0) {
330 input_state.mtc_in = string_is_affirmative (prop->value ());
332 _midi_inputs.push_back (input_state);
335 } else if (state_node->name () == "MidiOutputs") {
337 XMLNodeList output_state_nodes = state_node->children ();
338 XMLNodeConstIterator output_state_node_iter = output_state_nodes.begin ();
339 _midi_outputs.clear ();
341 for (; output_state_node_iter != output_state_nodes.end (); ++output_state_node_iter) {
343 XMLNode* output_state_node = *output_state_node_iter;
344 XMLProperty const * prop = NULL;
346 if (output_state_node->name () != "output") {
349 MidiPortState output_state (output_state_node->name ());
351 if ((prop = output_state_node->property ("name")) == 0) {
354 output_state.name = prop->value ();
356 if ((prop = output_state_node->property ("active")) == 0) {
359 output_state.active = string_is_affirmative (prop->value ());
361 if ((prop = output_state_node->property ("scene-connected")) == 0) {
364 output_state.scene_connected = string_is_affirmative (prop->value ());
366 if ((prop = output_state_node->property ("mtc-in")) == 0) {
369 output_state.mtc_in = string_is_affirmative (prop->value ());
371 _midi_outputs.push_back (output_state);
379 EngineStateController::_serialize_engine_states (XMLNode* audio_midi_settings_node)
381 if (!audio_midi_settings_node) {
385 // clean up state data first
386 audio_midi_settings_node->remove_nodes_and_delete ("EngineStates" );
388 XMLNode* engine_states = new XMLNode ("EngineStates" );
390 StateList::const_iterator state_iter = _states.begin ();
391 for (; state_iter != _states.end (); ++state_iter) {
393 StatePtr state_ptr = *state_iter;
395 // create new node for the state
396 XMLNode* state_node = new XMLNode ("State");
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");
404 // store channel states:
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);
415 state_node->add_child_nocopy (*input_config_node);
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);
427 state_node->add_child_nocopy (*multi_out_config_node);
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);
439 state_node->add_child_nocopy (*stereo_out_config_node);
441 engine_states->add_child_nocopy (*state_node);
444 audio_midi_settings_node->add_child_nocopy (*engine_states);
449 EngineStateController::_serialize_midi_port_states (XMLNode* audio_midi_settings_node)
451 if (!audio_midi_settings_node) {
455 // clean up state data first
456 audio_midi_settings_node->remove_nodes_and_delete ("MidiStates" );
458 XMLNode* midi_states_node = new XMLNode ("MidiStates" );
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);
470 midi_states_node->add_child_nocopy (*midi_input_states_node);
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);
482 midi_states_node->add_child_nocopy (*midi_output_states_node);
484 audio_midi_settings_node->add_child_nocopy (*midi_states_node);
489 EngineStateController::_apply_state (const StatePtr& state)
491 bool applied = false;
493 if (set_new_backend_as_current (state->backend_name)) {
494 applied = set_new_device_as_current (state->device_name);
502 EngineStateController::_do_initial_engine_setup ()
504 bool state_applied = false;
506 // if we have no saved state load default values
507 if (!_states.empty ()) {
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);
518 // last active state was not applied
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);
529 if (!state_applied ){
530 std::vector<const AudioBackendInfo*> backends = AudioEngine::instance ()->available_backends ();
532 if (!backends.empty ()) {
534 if (!set_new_backend_as_current (backends.front ()->name )) {
535 std::cerr << "\tfailed to set backend [" << backends.front ()->name << "]\n";
544 EngineStateController::_validate_current_device_state ()
546 boost::shared_ptr<AudioBackend> backend = AudioEngine::instance ()->current_backend ();
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);
553 if (sample_rates.empty ()) {
557 // check if session desired sample rate (if it's set) could be used with this device
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 ()) ) {
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 ()) ) {
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));
587 if (bs_iter != buffer_sizes.end ()) {
588 _current_state->buffer_size = backend->default_buffer_size (_current_state->device_name);
590 if (!buffer_sizes.empty ()) {
591 _current_state->buffer_size = buffer_sizes.front ();
602 EngineStateController::_update_ltc_source_port ()
604 // this method is called if the list of ports is changed
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
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);
618 // no available audio-in ports
619 set_ltc_source_port ("");
623 EngineStateController::_update_ltc_output_port ()
625 // this method is called if the list of ports is changed
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
633 PortStateList* output_states;
634 if (Config->get_output_auto_connect () & AutoConnectMaster) {
635 output_states = &_current_state->stereo_out_channel_states;
637 output_states = &_current_state->multi_out_channel_states;
640 //otherwise set first available audio port
641 if (!output_states->empty ()) {
642 set_ltc_output_port (output_states->front ().name);
646 // no available audio-out ports
647 set_ltc_output_port ("");
652 EngineStateController::_audio_input_port_exists (const std::string& port_name)
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)
663 EngineStateController::_audio_output_port_exists (const std::string& port_name)
665 PortStateList* output_states;
666 if (Config->get_output_auto_connect () & AutoConnectMaster) {
667 output_states = &_current_state->stereo_out_channel_states;
669 output_states = &_current_state->multi_out_channel_states;
672 PortStateList::const_iterator iter = output_states->begin ();
673 for (; iter != output_states->end (); ++iter ) {
674 if (iter->name == port_name)
682 EngineStateController::get_current_backend_name () const
684 return _current_state->backend_name;
689 EngineStateController::get_current_device_name () const
691 return _current_state->device_name;
696 EngineStateController::available_backends (std::vector<const AudioBackendInfo*>& available_backends)
698 available_backends = AudioEngine::instance ()->available_backends ();
703 EngineStateController::enumerate_devices (std::vector<AudioBackend::DeviceStatus>& device_vector) const
705 boost::shared_ptr<AudioBackend> backend = AudioEngine::instance ()->current_backend ();
707 device_vector = backend->enumerate_devices ();
712 EngineStateController::get_current_sample_rate () const
714 return _current_state->sample_rate;
719 EngineStateController::get_default_sample_rate () const
721 boost::shared_ptr<AudioBackend> backend = AudioEngine::instance ()->current_backend ();
723 return backend->default_sample_rate ();
728 EngineStateController::available_sample_rates_for_current_device (std::vector<float>& sample_rates) const
730 boost::shared_ptr<AudioBackend> backend = AudioEngine::instance ()->current_backend ();
732 sample_rates = backend->available_sample_rates (_current_state->device_name);
737 EngineStateController::get_current_buffer_size () const
739 return _current_state->buffer_size;
744 EngineStateController::get_default_buffer_size () const
746 boost::shared_ptr<AudioBackend> backend = AudioEngine::instance ()->current_backend ();
748 return backend->default_buffer_size (_current_state->device_name);
753 EngineStateController::available_buffer_sizes_for_current_device (std::vector<pframes_t>& buffer_sizes) const
755 boost::shared_ptr<AudioBackend> backend = AudioEngine::instance ()->current_backend ();
757 buffer_sizes = backend->available_buffer_sizes (_current_state->device_name);
762 EngineStateController::set_new_backend_as_current (const std::string& backend_name)
764 if (backend_name == AudioEngine::instance ()->current_backend_name ()) {
768 boost::shared_ptr<AudioBackend> backend = AudioEngine::instance ()->set_backend (backend_name, PROGRAM_NAME, "");
771 if (_current_state != NULL) {
772 _current_state->active = false;
775 StateList::iterator found_state_iter = find_if (_states.begin (), _states.end (),
776 State::StatePredicate (backend_name, "None"));
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 ();
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);
791 push_current_state_to_backend (false);
801 EngineStateController::set_new_device_as_current (const std::string& device_name)
803 if (_current_state->device_name == device_name) {
807 boost::shared_ptr<AudioBackend> backend = AudioEngine::instance ()->current_backend ();
810 std::vector<AudioBackend::DeviceStatus> device_vector = backend->enumerate_devices ();
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));
816 // device is available
817 if (device_iter != device_vector.end ()) {
819 boost::shared_ptr<State> previous_state (_current_state);
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));
825 if (found_state_iter != _states.end ())
827 // we found a record for current engine and provided device name - switch to it
829 _current_state = *found_state_iter;
831 if (!_validate_current_device_state ()) {
832 _current_state = previous_state;
838 // the record is not found, create new one
839 _current_state = boost::shared_ptr<State>(new State ());
841 _current_state->backend_name = backend->name ();
842 _current_state->device_name = device_name;
844 if (!_validate_current_device_state ()) {
845 _current_state = previous_state;
849 _states.push_front (_current_state);
852 if (previous_state != NULL) {
853 previous_state->active = false;
856 push_current_state_to_backend (false);
858 _last_used_real_device.clear ();
860 if (device_name != "None") {
861 _last_used_real_device = device_name;
867 // device is not supported by current backend
873 EngineStateController::set_new_sample_rate_in_controller (framecnt_t sample_rate)
875 boost::shared_ptr<AudioBackend> backend = AudioEngine::instance ()->current_backend ();
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);
881 if (iter != sample_rates.end ()) {
882 _current_state->sample_rate = sample_rate;
891 EngineStateController::set_new_buffer_size_in_controller (pframes_t buffer_size)
893 boost::shared_ptr<AudioBackend> backend = AudioEngine::instance ()->current_backend ();
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);
899 if (iter != buffer_sizes.end ()) {
900 _current_state->buffer_size = buffer_size;
909 EngineStateController::get_available_inputs_count () const
911 uint32_t available_channel_count = 0;
913 PortStateList::const_iterator iter = _current_state->input_channel_states.begin ();
915 for (; iter != _current_state->input_channel_states.end (); ++iter) {
917 ++available_channel_count;
921 return available_channel_count;
926 EngineStateController::get_available_outputs_count () const
928 uint32_t available_channel_count = 0;
930 PortStateList* output_states;
931 if (Config->get_output_auto_connect () & AutoConnectMaster) {
932 output_states = &_current_state->stereo_out_channel_states;
934 output_states = &_current_state->multi_out_channel_states;
937 PortStateList::const_iterator iter = output_states->begin ();
939 for (; iter != output_states->end (); ++iter) {
941 ++available_channel_count;
945 return available_channel_count;
950 EngineStateController::get_physical_audio_inputs (std::vector<std::string>& port_names)
954 PortStateList &input_states = _current_state->input_channel_states;
956 PortStateList::iterator iter = input_states.begin ();
957 for (; iter != input_states.end (); ++iter) {
959 port_names.push_back (iter->name);
966 EngineStateController::get_physical_audio_outputs (std::vector<std::string>& port_names)
970 PortStateList* output_states;
971 if (Config->get_output_auto_connect () & AutoConnectMaster) {
972 output_states = &_current_state->stereo_out_channel_states;
974 output_states = &_current_state->multi_out_channel_states;
977 PortStateList::iterator iter = output_states->begin ();
978 for (; iter != output_states->end (); ++iter) {
980 port_names.push_back (iter->name);
987 EngineStateController::get_physical_midi_inputs (std::vector<std::string>& port_names)
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);
1001 EngineStateController::get_physical_midi_outputs (std::vector<std::string>& port_names)
1003 port_names.clear ();
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);
1015 EngineStateController::set_physical_audio_input_state (const std::string& port_name, bool state)
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));
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);
1025 InputConfigChanged ();
1031 EngineStateController::set_physical_audio_output_state (const std::string& port_name, bool state)
1033 PortStateList* output_states;
1034 if (Config->get_output_auto_connect () & AutoConnectMaster) {
1035 output_states = &_current_state->stereo_out_channel_states;
1037 output_states = &_current_state->multi_out_channel_states;
1040 PortStateList::iterator target_state_iter;
1041 target_state_iter = std::find (output_states->begin (), output_states->end (), PortState (port_name));
1043 if (target_state_iter != output_states->end () && target_state_iter->active != state ) {
1044 target_state_iter->active = state;
1046 // if StereoOut mode is used
1047 if (Config->get_output_auto_connect () & AutoConnectMaster) {
1050 PortStateList::iterator next_state_iter (target_state_iter);
1053 if (++next_state_iter == output_states->end ()) {
1054 next_state_iter = output_states->begin ();
1058 // only two outputs should be enabled
1059 if (output_states->size () <= 2) {
1061 target_state_iter->active = true;
1062 next_state_iter->active = true;
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;
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 ();
1075 next_state_iter->active = true;
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;
1084 // now deactivate the rest
1085 while (++next_state_iter != target_state_iter) {
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) {
1095 next_state_iter->active = false;
1101 AudioEngine::instance ()->reconnect_session_routes (false, true);
1102 OutputConfigChanged ();
1108 EngineStateController::get_physical_audio_input_state (const std::string& port_name)
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));
1116 if (found_state_iter != input_states.end ()) {
1117 state = found_state_iter->active;
1125 EngineStateController::get_physical_audio_output_state (const std::string& port_name)
1129 PortStateList* output_states;
1130 if (Config->get_output_auto_connect () & AutoConnectMaster) {
1131 output_states = &_current_state->stereo_out_channel_states;
1133 output_states = &_current_state->multi_out_channel_states;
1136 PortStateList::iterator found_state_iter;
1137 found_state_iter = std::find (output_states->begin (), output_states->end (), PortState (port_name));
1139 if (found_state_iter != output_states->end ()) {
1140 state = found_state_iter->active;
1148 EngineStateController::set_physical_midi_input_state (const std::string& port_name, bool state) {
1150 MidiPortStateList::iterator found_state_iter;
1151 found_state_iter = std::find (_midi_inputs.begin (), _midi_inputs.end (), MidiPortState (port_name));
1153 if (found_state_iter != _midi_inputs.end () && found_state_iter->available && found_state_iter->active != state ) {
1154 found_state_iter->active = state;
1157 // reconnect MTC inputs as well
1158 if (found_state_iter->mtc_in) {
1159 _session->reconnect_mtc_ports ();
1161 _session->reconnect_mmc_ports (true);
1164 MIDIInputConfigChanged ();
1170 EngineStateController::set_physical_midi_output_state (const std::string& port_name, bool state) {
1172 MidiPortStateList::iterator found_state_iter;
1173 found_state_iter = std::find (_midi_outputs.begin (), _midi_outputs.end (), MidiPortState (port_name));
1175 if (found_state_iter != _midi_outputs.end () && found_state_iter->available && found_state_iter->active != state ) {
1176 found_state_iter->active = state;
1179 _session->reconnect_mmc_ports (false);
1182 MIDIOutputConfigChanged ();
1188 EngineStateController::get_physical_midi_input_state (const std::string& port_name, bool& scene_connected) {
1192 MidiPortStateList::iterator found_state_iter;
1193 found_state_iter = std::find (_midi_inputs.begin (), _midi_inputs.end (), MidiPortState (port_name));
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;
1205 EngineStateController::get_physical_midi_output_state (const std::string& port_name, bool& scene_connected) {
1209 MidiPortStateList::iterator found_state_iter;
1210 found_state_iter = std::find (_midi_outputs.begin (), _midi_outputs.end (), MidiPortState (port_name));
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;
1222 EngineStateController::set_physical_midi_scene_in_connection_state (const std::string& port_name, bool state) {
1224 MidiPortStateList::iterator found_state_iter;
1225 found_state_iter = std::find (_midi_inputs.begin (), _midi_inputs.end (), MidiPortState (port_name));
1227 if (found_state_iter != _midi_inputs.end () && found_state_iter->available && found_state_iter->active ) {
1228 found_state_iter->scene_connected = state;
1230 std::vector<std::string> ports;
1231 ports.push_back (port_name);
1232 MIDISceneInputConnectionChanged (ports, state);
1239 EngineStateController::set_physical_midi_scenen_out_connection_state (const std::string& port_name, bool state) {
1241 MidiPortStateList::iterator found_state_iter;
1242 found_state_iter = std::find (_midi_outputs.begin (), _midi_outputs.end (), MidiPortState (port_name));
1244 if (found_state_iter != _midi_outputs.end () && found_state_iter->available && found_state_iter->active ) {
1245 found_state_iter->scene_connected = state;
1247 std::vector<std::string> ports;
1248 ports.push_back (port_name);
1249 MIDISceneOutputConnectionChanged (ports, state);
1256 EngineStateController::set_all_midi_scene_inputs_disconnected ()
1258 MidiPortStateList::iterator iter = _midi_inputs.begin ();
1259 for (; iter != _midi_inputs.end (); ++iter) {
1260 iter->scene_connected = false;
1263 std::vector<std::string> ports;
1264 MIDISceneInputConnectionChanged (ports, false);
1269 EngineStateController::set_all_midi_scene_outputs_disconnected ()
1271 MidiPortStateList::iterator iter = _midi_outputs.begin ();
1272 for (; iter != _midi_outputs.end (); ++iter) {
1273 iter->scene_connected = false;
1276 std::vector<std::string> ports;
1277 MIDISceneOutputConnectionChanged (ports, false);
1282 EngineStateController::set_mtc_source_port (const std::string& port_name)
1284 MidiPortStateList::iterator iter = _midi_inputs.begin ();
1285 for (; iter != _midi_inputs.end (); ++iter) {
1286 iter->mtc_in = false;
1288 if (iter->name == port_name) {
1289 iter->mtc_in = true;
1292 _session->reconnect_mtc_ports ();
1297 if (_session && port_name.empty ()) {
1298 _session->reconnect_mtc_ports ();
1301 MTCInputChanged (port_name);
1306 EngineStateController::set_state_to_all_inputs (bool state)
1308 bool something_changed = false;
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;
1318 if (something_changed) {
1319 AudioEngine::instance ()->reconnect_session_routes (true, false);
1320 InputConfigChanged ();
1326 EngineStateController::set_state_to_all_outputs (bool state)
1328 // unapplicable in Stereo Out mode, just return
1329 if (Config->get_output_auto_connect () & AutoConnectMaster) {
1333 bool something_changed = false;
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;
1343 if (something_changed) {
1344 AudioEngine::instance ()->reconnect_session_routes (false, true);
1345 OutputConfigChanged ();
1351 EngineStateController::get_physical_audio_input_states (std::vector<PortState>& channel_states)
1353 PortStateList &input_states = _current_state->input_channel_states;
1354 channel_states.assign (input_states.begin (), input_states.end ());
1359 EngineStateController::get_physical_audio_output_states (std::vector<PortState>& channel_states)
1361 PortStateList* output_states;
1362 if (Config->get_output_auto_connect () & AutoConnectMaster) {
1363 output_states = &_current_state->stereo_out_channel_states;
1365 output_states = &_current_state->multi_out_channel_states;
1368 channel_states.assign (output_states->begin (), output_states->end ());
1373 EngineStateController::get_physical_midi_input_states (std::vector<MidiPortState>& channel_states)
1375 channel_states.clear ();
1377 MidiPortStateList::iterator iter = _midi_inputs.begin ();
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);
1392 EngineStateController::get_physical_midi_output_states (std::vector<MidiPortState>& channel_states)
1394 channel_states.clear ();
1396 MidiPortStateList::iterator iter = _midi_outputs.begin ();
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);
1412 EngineStateController::_on_session_loaded ()
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);
1423 // This is done during session construction
1424 // _session->reconnect_ltc_input ();
1425 // _session->reconnect_ltc_output ();
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))
1430 push_current_state_to_backend (false);
1431 SampleRateChanged (); // emit a signal
1437 EngineStateController::_on_sample_rate_change (framecnt_t new_sample_rate)
1439 if (_current_state->sample_rate != new_sample_rate) {
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 ();
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);
1457 SampleRateChanged (); // emit a signal
1462 EngineStateController::_on_buffer_size_change (pframes_t new_buffer_size)
1464 if (_current_state->buffer_size != new_buffer_size) {
1465 _current_state->buffer_size = new_buffer_size;
1468 BufferSizeChanged (); // emit a signal
1473 EngineStateController::_on_device_list_change ()
1475 bool current_device_disconnected = false;
1477 boost::shared_ptr<AudioBackend> backend = AudioEngine::instance ()->current_backend ();
1480 std::vector<AudioBackend::DeviceStatus> device_vector = backend->enumerate_devices ();
1482 // find out out if current device is still available if it's not None
1483 if (_current_state->device_name != "None")
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));
1488 // if current device is not available any more - switch to None device
1489 if (device_iter == device_vector.end ()) {
1491 StateList::iterator found_state_iter = find_if (_states.begin (), _states.end (),
1492 State::StatePredicate (_current_state->backend_name, "None"));
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 ();
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);
1507 push_current_state_to_backend (true);
1508 current_device_disconnected = true;
1511 // if the device which was active before is available now - switch to it
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));
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));
1521 if (found_state_iter != _states.end ()) {
1523 boost::shared_ptr<State> previous_state (_current_state);
1524 _current_state = *found_state_iter;
1526 if (_validate_current_device_state ()) {
1527 push_current_state_to_backend (false);
1529 // cannot use this device right now
1530 _last_used_real_device.clear ();
1531 _current_state = previous_state;
1537 DeviceListChanged (current_device_disconnected); // emit a signal
1542 EngineStateController::_update_device_channels_state ()
1544 boost::shared_ptr<AudioBackend> backend = AudioEngine::instance ()->current_backend ();
1547 // update audio input states
1548 std::vector<std::string> phys_audio_inputs;
1549 backend->get_physical_inputs (DataType::AUDIO, phys_audio_inputs);
1551 PortStateList new_input_states;
1552 PortStateList &input_states = _current_state->input_channel_states;
1554 std::vector<std::string>::const_iterator input_iter = phys_audio_inputs.begin ();
1555 for (; input_iter != phys_audio_inputs.end (); ++input_iter) {
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);
1561 if (found_state_iter != input_states.end ()) {
1562 new_input_states.push_back (*found_state_iter);
1564 new_input_states.push_back (state);
1567 _current_state->input_channel_states = new_input_states;
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);
1573 PortStateList new_output_states;
1574 PortStateList &output_multi_states = _current_state->multi_out_channel_states;
1576 std::vector<std::string>::const_iterator output_iter = phys_audio_outputs.begin ();
1577 for (; output_iter != phys_audio_outputs.end (); ++output_iter) {
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);
1583 if (found_state_iter != output_multi_states.end ()) {
1584 new_output_states.push_back (*found_state_iter);
1586 new_output_states.push_back (state);
1590 _current_state->multi_out_channel_states = new_output_states;
1592 // update audio output states (stereo out mode)
1593 new_output_states.clear ();
1594 PortStateList &output_stereo_states = _current_state->stereo_out_channel_states;
1596 output_iter = phys_audio_outputs.begin ();
1597 for (; output_iter != phys_audio_outputs.end (); ++output_iter) {
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);
1603 if (found_state_iter != output_stereo_states.end ()) {
1604 new_output_states.push_back (*found_state_iter);
1606 new_output_states.push_back (state);
1610 _current_state->stereo_out_channel_states = new_output_states;
1611 _refresh_stereo_out_channel_states ();
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;
1626 for (iter = _midi_outputs.begin (); iter != _midi_outputs.end (); ++iter) {
1627 iter->available = false;
1630 // update midi input ports
1631 std::vector<std::string> phys_midi_inputs;
1632 backend->get_physical_inputs (DataType::MIDI, phys_midi_inputs);
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) {
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);
1642 if (found_state_iter != _midi_inputs.end ()) {
1643 found_state_iter->available = true;
1645 _midi_inputs.push_back (state);
1649 // update midi output ports
1650 std::vector<std::string> phys_midi_outputs;
1651 backend->get_physical_outputs (DataType::MIDI, phys_midi_outputs);
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) {
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);
1661 if (found_state_iter != _midi_outputs.end ()) {
1662 found_state_iter->available = true;
1664 _midi_outputs.push_back (state);
1671 EngineStateController::_refresh_stereo_out_channel_states ()
1673 PortStateList &output_states = _current_state->stereo_out_channel_states;
1674 PortStateList::iterator active_iter = output_states.begin ();
1676 for (; active_iter != output_states.end (); ++active_iter) {
1677 if (active_iter->active) {
1682 uint32_t pending_active_channels = 2;
1683 PortStateList::iterator iter = output_states.begin ();
1685 if (active_iter != output_states.end ()) {
1687 if (++iter == output_states.end ()) {
1688 iter = output_states.begin ();
1691 (iter++)->active = true;
1692 pending_active_channels = 0;
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;
1701 iter->active = false;
1708 EngineStateController::_on_engine_running ()
1710 AudioEngine::instance ()->reconnect_session_routes (true, true);
1711 _current_state->active = true;
1713 EngineRunning (); // emit a signal
1718 EngineStateController::_on_engine_stopped ()
1725 EngineStateController::_on_engine_halted ()
1732 EngineStateController::_on_device_error ()
1734 set_new_device_as_current ("None");
1735 push_current_state_to_backend (true);
1736 DeviceListChanged (false);
1742 EngineStateController::_on_parameter_changed (const std::string& parameter_name)
1744 if (parameter_name == "output-auto-connect") {
1746 AudioEngine::instance ()->reconnect_session_routes (false, true);
1747 OutputConfigChanged (); // emit a signal
1748 OutputConnectionModeChanged (); // emit signal
1754 EngineStateController::_on_ports_registration_update ()
1756 _update_device_channels_state ();
1758 // update MIDI connections
1760 _session->reconnect_midi_scene_ports (true);
1761 _session->reconnect_midi_scene_ports (false);
1763 _session->reconnect_mtc_ports ();
1765 _session->reconnect_mmc_ports (true);
1766 _session->reconnect_mmc_ports (false);
1768 _session->reconnect_ltc_input ();
1769 _session->reconnect_ltc_output ();
1772 _update_ltc_source_port ();
1773 _update_ltc_output_port ();
1775 PortRegistrationChanged (); // emit a signal
1780 EngineStateController::push_current_state_to_backend (bool start)
1782 boost::shared_ptr<AudioBackend> backend = AudioEngine::instance ()->current_backend ();
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 ());
1793 bool was_running = AudioEngine::instance ()->running ();
1795 Glib::Threads::RecMutex::Lock sl (AudioEngine::instance ()->state_lock ());
1796 if (state_changed) {
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 ("");
1808 if (AudioEngine::instance ()->stop ()) {
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;
1821 std::cout << "EngineStateController::Setting device sample rate " << _current_state->sample_rate << std::endl;
1822 result = backend->set_sample_rate (_current_state->sample_rate);
1825 error << string_compose (_("Cannot set sample rate to %1"), get_current_sample_rate ()) << endmsg;
1830 std::cout << "EngineStateController::Setting device buffer size " << _current_state->buffer_size << std::endl;
1831 result = backend->set_buffer_size (_current_state->buffer_size);
1834 error << string_compose (_("Cannot set buffer size to %1"), get_current_buffer_size ()) << endmsg;
1839 if (result) // error during device setup
1841 //switch to None device and notify about the issue
1842 set_new_device_as_current ("None");
1843 DeviceListChanged (false);
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
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);
1865 save_audio_midi_settings ();
1872 EngineStateController::get_mtc_source_port ()
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);
1885 EngineStateController::set_ltc_source_port (const std::string& port)
1887 Config->set_ltc_source_port (port);
1891 EngineStateController::get_ltc_source_port ()
1893 return Config->get_ltc_source_port ();
1897 EngineStateController::set_ltc_output_port (const std::string& port)
1899 Config->set_ltc_output_port (port);
1903 EngineStateController::get_ltc_output_port ()
1905 return Config->get_ltc_output_port ();