X-Git-Url: https://main.carlh.net/gitweb/?a=blobdiff_plain;f=libs%2Fardour%2Fengine_state_controller.cc;h=57b8a848884501e50ec0616cf2f78d726cc19c8b;hb=9a281963e143d1191d701f6f248a956bdaf9200d;hp=8e05cafcfe208f909a7890c687f356837192b7d5;hpb=6eebb6326ab46c5250905c7c97f35a42531201b1;p=ardour.git diff --git a/libs/ardour/engine_state_controller.cc b/libs/ardour/engine_state_controller.cc index 8e05cafcfe..57b8a84888 100644 --- a/libs/ardour/engine_state_controller.cc +++ b/libs/ardour/engine_state_controller.cc @@ -1,20 +1,20 @@ /* Copyright (C) 2014 Waves Audio Ltd. - + This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. - + You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - + */ #include "ardour/engine_state_controller.h" @@ -33,69 +33,69 @@ using namespace ARDOUR; using namespace PBD; namespace { - + struct DevicePredicate { - DevicePredicate(const std::string& device_name) - : _device_name(device_name) + DevicePredicate (const std::string& device_name) + : _device_name (device_name) {} - - bool operator()(const AudioBackend::DeviceStatus& rhs) + + bool operator ()(const AudioBackend::DeviceStatus& rhs) { return _device_name == rhs.name; } - - private: + + private: std::string _device_name; }; } EngineStateController* -EngineStateController::instance() +EngineStateController::instance () { static EngineStateController instance; return &instance; } -EngineStateController::EngineStateController() - : _current_state() - , _last_used_real_device("") +EngineStateController::EngineStateController () + : _current_state () + , _last_used_real_device ("") { - AudioEngine::instance ()->Running.connect_same_thread (running_connection, boost::bind (&EngineStateController::_on_engine_running, this) ); - AudioEngine::instance ()->Stopped.connect_same_thread (stopped_connection, boost::bind (&EngineStateController::_on_engine_stopped, this) ); - AudioEngine::instance ()->Halted.connect_same_thread (stopped_connection, boost::bind (&EngineStateController::_on_engine_stopped, this) ); - + AudioEngine::instance ()->Running.connect_same_thread (running_connection, boost::bind (&EngineStateController::_on_engine_running, this)); + AudioEngine::instance ()->Stopped.connect_same_thread (stopped_connection, boost::bind (&EngineStateController::_on_engine_stopped, this)); + AudioEngine::instance ()->Halted.connect_same_thread (stopped_connection, boost::bind (&EngineStateController::_on_engine_stopped, this)); + /* Subscribe for udpates from AudioEngine */ - AudioEngine::instance ()->PortRegisteredOrUnregistered.connect_same_thread (update_connections, boost::bind (&EngineStateController::_on_ports_registration_update, this) ); - AudioEngine::instance()->SampleRateChanged.connect_same_thread (update_connections, boost::bind (&EngineStateController::_on_sample_rate_change, this, _1) ); - AudioEngine::instance()->BufferSizeChanged.connect_same_thread (update_connections, boost::bind (&EngineStateController::_on_buffer_size_change, this, _1) ); - AudioEngine::instance()->DeviceListChanged.connect_same_thread (update_connections, boost::bind (&EngineStateController::_on_device_list_change, this) ); - AudioEngine::instance()->DeviceError.connect_same_thread (update_connections, boost::bind (&EngineStateController::_on_device_error, this) ); - + AudioEngine::instance ()->PortRegisteredOrUnregistered.connect_same_thread (update_connections, boost::bind (&EngineStateController::_on_ports_registration_update, this)); + AudioEngine::instance ()->SampleRateChanged.connect_same_thread (update_connections, boost::bind (&EngineStateController::_on_sample_rate_change, this, _1)); + AudioEngine::instance ()->BufferSizeChanged.connect_same_thread (update_connections, boost::bind (&EngineStateController::_on_buffer_size_change, this, _1)); + AudioEngine::instance ()->DeviceListChanged.connect_same_thread (update_connections, boost::bind (&EngineStateController::_on_device_list_change, this)); + AudioEngine::instance ()->DeviceError.connect_same_thread (update_connections, boost::bind (&EngineStateController::_on_device_error, this)); + /* Global configuration parameters update */ - Config->ParameterChanged.connect_same_thread (update_connections, boost::bind (&EngineStateController::_on_parameter_changed, this, _1) ); - - _deserialize_and_load_engine_states(); - _deserialize_and_load_midi_port_states(); - _do_initial_engine_setup(); - + Config->ParameterChanged.connect_same_thread (update_connections, boost::bind (&EngineStateController::_on_parameter_changed, this, _1)); + + _deserialize_and_load_engine_states (); + _deserialize_and_load_midi_port_states (); + _do_initial_engine_setup (); + // now push the sate to the backend - push_current_state_to_backend(false); + push_current_state_to_backend (false); } -EngineStateController::~EngineStateController() +EngineStateController::~EngineStateController () { } void -EngineStateController::set_session(Session* session) +EngineStateController::set_session (Session* session) { _session = session; - _session->SessionLoaded.connect_same_thread (session_connections, boost::bind (&EngineStateController::_on_session_loaded, this) ); + _session->SessionLoaded.connect_same_thread (session_connections, boost::bind (&EngineStateController::_on_session_loaded, this)); } @@ -108,267 +108,267 @@ EngineStateController::remove_session () XMLNode& -EngineStateController::serialize_audio_midi_settings() +EngineStateController::serialize_audio_midi_settings () { - + XMLNode* root = new XMLNode ("AudioMidiSettings"); - - _serialize_engine_states(root); - _serialize_midi_port_states(root); - + + _serialize_engine_states (root); + _serialize_midi_port_states (root); + return *root; } void -EngineStateController::save_audio_midi_settings() +EngineStateController::save_audio_midi_settings () { - Config->add_extra_xml (serialize_audio_midi_settings() ); + Config->add_extra_xml (serialize_audio_midi_settings ()); Config->save_state (); } void -EngineStateController::_deserialize_and_load_engine_states() +EngineStateController::_deserialize_and_load_engine_states () { XMLNode* audio_midi_settings_root = ARDOUR::Config->extra_xml ("AudioMidiSettings"); - + if (!audio_midi_settings_root) { return; } - - XMLNode* engine_states = audio_midi_settings_root->child("EngineStates"); - + + XMLNode* engine_states = audio_midi_settings_root->child ("EngineStates"); + if (!engine_states) { return; } - - XMLNodeList state_nodes_list = engine_states->children(); - XMLNodeConstIterator state_node_iter = state_nodes_list.begin(); - - for (; state_node_iter != state_nodes_list.end(); ++state_node_iter) { - + + XMLNodeList state_nodes_list = engine_states->children (); + XMLNodeConstIterator state_node_iter = state_nodes_list.begin (); + + for (; state_node_iter != state_nodes_list.end (); ++state_node_iter) { + XMLNode* state_node = *state_node_iter; - StatePtr engine_state(new State); + StatePtr engine_state (new State); XMLProperty* prop = NULL; - + if ((prop = state_node->property ("backend-name")) == 0) { continue; } engine_state->backend_name = prop->value (); - + if ((prop = state_node->property ("device-name")) == 0) { continue; } engine_state->device_name = prop->value (); - + if ((prop = state_node->property ("sample-rate")) == 0) { continue; } engine_state->sample_rate = atoi (prop->value ()); - + if ((prop = state_node->property ("buffer-size")) == 0) { continue; } engine_state->buffer_size = atoi (prop->value ()); - + if ((prop = state_node->property ("active")) == 0) { continue; } engine_state->active = string_is_affirmative (prop->value ()); - - XMLNodeList state_children_list = state_node->children(); - XMLNodeConstIterator state_child_iter = state_children_list.begin(); - - for (; state_child_iter != state_children_list.end(); ++state_child_iter) { + + XMLNodeList state_children_list = state_node->children (); + XMLNodeConstIterator state_child_iter = state_children_list.begin (); + + for (; state_child_iter != state_children_list.end (); ++state_child_iter) { XMLNode* state_child = *state_child_iter; - - if (state_child->name() == "InputConfiguration") { - - XMLNodeList input_states_nodes = state_child->children(); - XMLNodeConstIterator input_state_node_iter = input_states_nodes.begin(); + + if (state_child->name () == "InputConfiguration") { + + XMLNodeList input_states_nodes = state_child->children (); + XMLNodeConstIterator input_state_node_iter = input_states_nodes.begin (); PortStateList& input_states = engine_state->input_channel_states; - - for (; input_state_node_iter != input_states_nodes.end(); ++input_state_node_iter) { - + + for (; input_state_node_iter != input_states_nodes.end (); ++input_state_node_iter) { + XMLNode* input_state_node = *input_state_node_iter; - - if (input_state_node->name() != "input") { + + if (input_state_node->name () != "input") { continue; } - PortState input_state (input_state_node->name() ); - + PortState input_state (input_state_node->name ()); + if ((prop = input_state_node->property ("name")) == 0) { continue; } - input_state.name = prop->value(); - + input_state.name = prop->value (); + if ((prop = input_state_node->property ("active")) == 0) { continue; } input_state.active = string_is_affirmative (prop->value ()); - - input_states.push_back(input_state); + + input_states.push_back (input_state); } - - } else if (state_child->name() == "MultiOutConfiguration") { - - XMLNodeList multi_out_state_nodes = state_child->children(); - XMLNodeConstIterator multi_out_state_node_iter = multi_out_state_nodes.begin(); + + } else if (state_child->name () == "MultiOutConfiguration") { + + XMLNodeList multi_out_state_nodes = state_child->children (); + XMLNodeConstIterator multi_out_state_node_iter = multi_out_state_nodes.begin (); PortStateList& multi_out_states = engine_state->multi_out_channel_states; - - for (; multi_out_state_node_iter != multi_out_state_nodes.end(); ++multi_out_state_node_iter) { - + + for (; multi_out_state_node_iter != multi_out_state_nodes.end (); ++multi_out_state_node_iter) { + XMLNode* multi_out_state_node = *multi_out_state_node_iter; - - if (multi_out_state_node->name() != "output") { + + if (multi_out_state_node->name () != "output") { continue; } - PortState multi_out_state (multi_out_state_node->name() ); - + PortState multi_out_state (multi_out_state_node->name ()); + if ((prop = multi_out_state_node->property ("name")) == 0) { continue; } - multi_out_state.name = prop->value(); - + multi_out_state.name = prop->value (); + if ((prop = multi_out_state_node->property ("active")) == 0) { continue; } multi_out_state.active = string_is_affirmative (prop->value ()); - - multi_out_states.push_back(multi_out_state); + + multi_out_states.push_back (multi_out_state); } - } else if (state_child->name() == "StereoOutConfiguration") { - - XMLNodeList stereo_out_state_nodes = state_child->children(); - XMLNodeConstIterator stereo_out_state_node_iter = stereo_out_state_nodes.begin(); + } else if (state_child->name () == "StereoOutConfiguration") { + + XMLNodeList stereo_out_state_nodes = state_child->children (); + XMLNodeConstIterator stereo_out_state_node_iter = stereo_out_state_nodes.begin (); PortStateList& stereo_out_states = engine_state->stereo_out_channel_states; - - for (; stereo_out_state_node_iter != stereo_out_state_nodes.end(); ++stereo_out_state_node_iter) { - + + for (; stereo_out_state_node_iter != stereo_out_state_nodes.end (); ++stereo_out_state_node_iter) { + XMLNode* stereo_out_state_node = *stereo_out_state_node_iter; - - if (stereo_out_state_node->name() != "output") { + + if (stereo_out_state_node->name () != "output") { continue; } - PortState stereo_out_state (stereo_out_state_node->name() ); - + PortState stereo_out_state (stereo_out_state_node->name ()); + if ((prop = stereo_out_state_node->property ("name")) == 0) { continue; } - stereo_out_state.name = prop->value(); - + stereo_out_state.name = prop->value (); + if ((prop = stereo_out_state_node->property ("active")) == 0) { continue; - } + } stereo_out_state.active = string_is_affirmative (prop->value ()); - - stereo_out_states.push_back(stereo_out_state); + + stereo_out_states.push_back (stereo_out_state); } } } - + _states.push_back (engine_state); } } void -EngineStateController::_deserialize_and_load_midi_port_states() -{ +EngineStateController::_deserialize_and_load_midi_port_states () +{ XMLNode* audio_midi_settings_root = ARDOUR::Config->extra_xml ("AudioMidiSettings"); - + if (!audio_midi_settings_root) { return; } - - XMLNode* midi_states = audio_midi_settings_root->child("MidiStates"); - + + XMLNode* midi_states = audio_midi_settings_root->child ("MidiStates"); + if (!midi_states) { return; } - - XMLNodeList state_nodes_list = midi_states->children(); - XMLNodeConstIterator state_node_iter = state_nodes_list.begin(); - for (; state_node_iter != state_nodes_list.end(); ++state_node_iter) { - + + XMLNodeList state_nodes_list = midi_states->children (); + XMLNodeConstIterator state_node_iter = state_nodes_list.begin (); + for (; state_node_iter != state_nodes_list.end (); ++state_node_iter) { + XMLNode* state_node = *state_node_iter; - if (state_node->name() == "MidiInputs") { - - XMLNodeList input_state_nodes = state_node->children(); - XMLNodeConstIterator input_state_node_iter = input_state_nodes.begin(); - _midi_inputs.clear(); - - for (; input_state_node_iter != input_state_nodes.end(); ++input_state_node_iter) { - + if (state_node->name () == "MidiInputs") { + + XMLNodeList input_state_nodes = state_node->children (); + XMLNodeConstIterator input_state_node_iter = input_state_nodes.begin (); + _midi_inputs.clear (); + + for (; input_state_node_iter != input_state_nodes.end (); ++input_state_node_iter) { + XMLNode* input_state_node = *input_state_node_iter; XMLProperty* prop = NULL; - - if (input_state_node->name() != "input") { + + if (input_state_node->name () != "input") { continue; } - MidiPortState input_state (input_state_node->name() ); - + MidiPortState input_state (input_state_node->name ()); + if ((prop = input_state_node->property ("name")) == 0) { continue; } - input_state.name = prop->value(); - + input_state.name = prop->value (); + if ((prop = input_state_node->property ("active")) == 0) { continue; } input_state.active = string_is_affirmative (prop->value ()); - + if ((prop = input_state_node->property ("scene-connected")) == 0) { continue; } input_state.scene_connected = string_is_affirmative (prop->value ()); - + if ((prop = input_state_node->property ("mtc-in")) == 0) { continue; } input_state.mtc_in = string_is_affirmative (prop->value ()); - - _midi_inputs.push_back(input_state); + + _midi_inputs.push_back (input_state); } - - } else if (state_node->name() == "MidiOutputs") { - - XMLNodeList output_state_nodes = state_node->children(); - XMLNodeConstIterator output_state_node_iter = output_state_nodes.begin(); - _midi_outputs.clear(); - - for (; output_state_node_iter != output_state_nodes.end(); ++output_state_node_iter) { - + + } else if (state_node->name () == "MidiOutputs") { + + XMLNodeList output_state_nodes = state_node->children (); + XMLNodeConstIterator output_state_node_iter = output_state_nodes.begin (); + _midi_outputs.clear (); + + for (; output_state_node_iter != output_state_nodes.end (); ++output_state_node_iter) { + XMLNode* output_state_node = *output_state_node_iter; XMLProperty* prop = NULL; - - if (output_state_node->name() != "output") { + + if (output_state_node->name () != "output") { continue; } - MidiPortState output_state (output_state_node->name() ); - + MidiPortState output_state (output_state_node->name ()); + if ((prop = output_state_node->property ("name")) == 0) { continue; } - output_state.name = prop->value(); - + output_state.name = prop->value (); + if ((prop = output_state_node->property ("active")) == 0) { continue; } output_state.active = string_is_affirmative (prop->value ()); - + if ((prop = output_state_node->property ("scene-connected")) == 0) { continue; } output_state.scene_connected = string_is_affirmative (prop->value ()); - + if ((prop = output_state_node->property ("mtc-in")) == 0) { continue; } output_state.mtc_in = string_is_affirmative (prop->value ()); - - _midi_outputs.push_back(output_state); + + _midi_outputs.push_back (output_state); } } } @@ -376,219 +376,219 @@ EngineStateController::_deserialize_and_load_midi_port_states() void -EngineStateController::_serialize_engine_states(XMLNode* audio_midi_settings_node) +EngineStateController::_serialize_engine_states (XMLNode* audio_midi_settings_node) { if (!audio_midi_settings_node) { return; } - + // clean up state data first - audio_midi_settings_node->remove_nodes_and_delete("EngineStates" ); - - XMLNode* engine_states = new XMLNode("EngineStates" ); - - StateList::const_iterator state_iter = _states.begin(); - for (; state_iter != _states.end(); ++state_iter) { - + audio_midi_settings_node->remove_nodes_and_delete ("EngineStates" ); + + XMLNode* engine_states = new XMLNode ("EngineStates" ); + + StateList::const_iterator state_iter = _states.begin (); + for (; state_iter != _states.end (); ++state_iter) { + StatePtr state_ptr = *state_iter; - + // create new node for the state - XMLNode* state_node = new XMLNode("State"); - + XMLNode* state_node = new XMLNode ("State"); + state_node->add_property ("backend-name", state_ptr->backend_name); state_node->add_property ("device-name", state_ptr->device_name); state_node->add_property ("sample-rate", state_ptr->sample_rate); state_node->add_property ("buffer-size", state_ptr->buffer_size); state_node->add_property ("active", state_ptr->active ? "yes" : "no"); - + // store channel states: // inputs - XMLNode* input_config_node = new XMLNode("InputConfiguration"); + XMLNode* input_config_node = new XMLNode ("InputConfiguration"); PortStateList& input_channels = state_ptr->input_channel_states; - PortStateList::const_iterator input_state_iter = input_channels.begin(); - for (; input_state_iter != input_channels.end(); ++input_state_iter) { - XMLNode* input_state_node = new XMLNode("input"); + PortStateList::const_iterator input_state_iter = input_channels.begin (); + for (; input_state_iter != input_channels.end (); ++input_state_iter) { + XMLNode* input_state_node = new XMLNode ("input"); input_state_node->add_property ("name", input_state_iter->name); input_state_node->add_property ("active", input_state_iter->active ? "yes" : "no"); - input_config_node->add_child_nocopy(*input_state_node); + input_config_node->add_child_nocopy (*input_state_node); } - state_node->add_child_nocopy(*input_config_node); - + state_node->add_child_nocopy (*input_config_node); + // multi out outputs - XMLNode* multi_out_config_node = new XMLNode("MultiOutConfiguration"); + XMLNode* multi_out_config_node = new XMLNode ("MultiOutConfiguration"); PortStateList& multi_out_channels = state_ptr->multi_out_channel_states; - PortStateList::const_iterator multi_out_state_iter = multi_out_channels.begin(); - for (; multi_out_state_iter != multi_out_channels.end(); ++multi_out_state_iter) { - XMLNode* multi_out_state_node = new XMLNode("output" ); + PortStateList::const_iterator multi_out_state_iter = multi_out_channels.begin (); + for (; multi_out_state_iter != multi_out_channels.end (); ++multi_out_state_iter) { + XMLNode* multi_out_state_node = new XMLNode ("output" ); multi_out_state_node->add_property ("name", multi_out_state_iter->name); multi_out_state_node->add_property ("active", multi_out_state_iter->active ? "yes" : "no"); - multi_out_config_node->add_child_nocopy(*multi_out_state_node); + multi_out_config_node->add_child_nocopy (*multi_out_state_node); } - state_node->add_child_nocopy(*multi_out_config_node); - + state_node->add_child_nocopy (*multi_out_config_node); + // stereo out outputs - XMLNode* stereo_out_config_node = new XMLNode("StereoOutConfiguration"); + XMLNode* stereo_out_config_node = new XMLNode ("StereoOutConfiguration"); PortStateList& stereo_out_channels = state_ptr->stereo_out_channel_states; - PortStateList::const_iterator stereo_out_state_iter = stereo_out_channels.begin(); - for (; stereo_out_state_iter != stereo_out_channels.end(); ++stereo_out_state_iter) { - XMLNode* stereo_out_state_node = new XMLNode("output" ); + PortStateList::const_iterator stereo_out_state_iter = stereo_out_channels.begin (); + for (; stereo_out_state_iter != stereo_out_channels.end (); ++stereo_out_state_iter) { + XMLNode* stereo_out_state_node = new XMLNode ("output" ); stereo_out_state_node->add_property ("name", stereo_out_state_iter->name); stereo_out_state_node->add_property ("active", stereo_out_state_iter->active ? "yes" : "no"); - stereo_out_config_node->add_child_nocopy(*stereo_out_state_node); + stereo_out_config_node->add_child_nocopy (*stereo_out_state_node); } - state_node->add_child_nocopy(*stereo_out_config_node); - - engine_states->add_child_nocopy(*state_node); + state_node->add_child_nocopy (*stereo_out_config_node); + + engine_states->add_child_nocopy (*state_node); } - audio_midi_settings_node->add_child_nocopy(*engine_states); + audio_midi_settings_node->add_child_nocopy (*engine_states); } void -EngineStateController::_serialize_midi_port_states(XMLNode* audio_midi_settings_node) +EngineStateController::_serialize_midi_port_states (XMLNode* audio_midi_settings_node) { if (!audio_midi_settings_node) { return; } - + // clean up state data first - audio_midi_settings_node->remove_nodes_and_delete("MidiStates" ); - - XMLNode* midi_states_node = new XMLNode("MidiStates" ); - - XMLNode* midi_input_states_node = new XMLNode("MidiInputs" ); - MidiPortStateList::const_iterator midi_input_state_iter = _midi_inputs.begin(); - for (; midi_input_state_iter != _midi_inputs.end(); ++midi_input_state_iter) { - XMLNode* midi_input_node = new XMLNode("input" ); + audio_midi_settings_node->remove_nodes_and_delete ("MidiStates" ); + + XMLNode* midi_states_node = new XMLNode ("MidiStates" ); + + XMLNode* midi_input_states_node = new XMLNode ("MidiInputs" ); + MidiPortStateList::const_iterator midi_input_state_iter = _midi_inputs.begin (); + for (; midi_input_state_iter != _midi_inputs.end (); ++midi_input_state_iter) { + XMLNode* midi_input_node = new XMLNode ("input" ); midi_input_node->add_property ("name", midi_input_state_iter->name); midi_input_node->add_property ("active", midi_input_state_iter->active ? "yes" : "no"); midi_input_node->add_property ("scene_connected", midi_input_state_iter->scene_connected ? "yes" : "no"); midi_input_node->add_property ("mtc-in", midi_input_state_iter->mtc_in ? "yes" : "no"); - midi_input_states_node->add_child_nocopy(*midi_input_node); - } - midi_states_node->add_child_nocopy(*midi_input_states_node); - - XMLNode* midi_output_states_node = new XMLNode("MidiOutputs" ); - MidiPortStateList::const_iterator midi_output_state_iter = _midi_outputs.begin(); - for (; midi_output_state_iter != _midi_outputs.end(); ++midi_output_state_iter) { - XMLNode* midi_output_node = new XMLNode("output" ); + midi_input_states_node->add_child_nocopy (*midi_input_node); + } + midi_states_node->add_child_nocopy (*midi_input_states_node); + + XMLNode* midi_output_states_node = new XMLNode ("MidiOutputs" ); + MidiPortStateList::const_iterator midi_output_state_iter = _midi_outputs.begin (); + for (; midi_output_state_iter != _midi_outputs.end (); ++midi_output_state_iter) { + XMLNode* midi_output_node = new XMLNode ("output" ); midi_output_node->add_property ("name", midi_output_state_iter->name); midi_output_node->add_property ("active", midi_output_state_iter->active ? "yes" : "no"); midi_output_node->add_property ("scene_connected", midi_output_state_iter->scene_connected ? "yes" : "no"); midi_output_node->add_property ("mtc-in", midi_output_state_iter->mtc_in ? "yes" : "no"); - midi_output_states_node->add_child_nocopy(*midi_output_node); + midi_output_states_node->add_child_nocopy (*midi_output_node); } - midi_states_node->add_child_nocopy(*midi_output_states_node); + midi_states_node->add_child_nocopy (*midi_output_states_node); - audio_midi_settings_node->add_child_nocopy(*midi_states_node); + audio_midi_settings_node->add_child_nocopy (*midi_states_node); } bool -EngineStateController::_apply_state(const StatePtr& state) +EngineStateController::_apply_state (const StatePtr& state) { bool applied = false; - - if (set_new_backend_as_current(state->backend_name) ) { - applied = set_new_device_as_current(state->device_name); + + if (set_new_backend_as_current (state->backend_name)) { + applied = set_new_device_as_current (state->device_name); } - + return applied; } void -EngineStateController::_do_initial_engine_setup() +EngineStateController::_do_initial_engine_setup () { bool state_applied = false; - + // if we have no saved state load default values - if (!_states.empty() ) { - + if (!_states.empty ()) { + // look for last active state first - StateList::const_iterator state_iter = _states.begin(); - for (; state_iter != _states.end(); ++state_iter) { + StateList::const_iterator state_iter = _states.begin (); + for (; state_iter != _states.end (); ++state_iter) { if ( (*state_iter)->active ) { - state_applied = _apply_state(*state_iter); + state_applied = _apply_state (*state_iter); break; } } - + // last active state was not applied // try others if (!state_applied) { - StateList::const_iterator state_iter = _states.begin(); - for (; state_iter != _states.end(); ++state_iter) { - state_applied = _apply_state(*state_iter); + StateList::const_iterator state_iter = _states.begin (); + for (; state_iter != _states.end (); ++state_iter) { + state_applied = _apply_state (*state_iter); break; } } } if (!state_applied ){ - std::vector backends = AudioEngine::instance()->available_backends(); - - if (!backends.empty() ) { - - if (!set_new_backend_as_current(backends.front()->name ) ) { - std::cerr << "\tfailed to set backend [" << backends.front()->name << "]\n"; + std::vector backends = AudioEngine::instance ()->available_backends (); + + if (!backends.empty ()) { + + if (!set_new_backend_as_current (backends.front ()->name )) { + std::cerr << "\tfailed to set backend [" << backends.front ()->name << "]\n"; } } - + } } bool -EngineStateController::_validate_current_device_state() +EngineStateController::_validate_current_device_state () { - boost::shared_ptr backend = AudioEngine::instance()->current_backend(); - assert(backend); - + boost::shared_ptr backend = AudioEngine::instance ()->current_backend (); + assert (backend); + // check if device parameters from the state record are still valid // validate sample rate std::vector sample_rates = backend->available_sample_rates (_current_state->device_name); - - if (sample_rates.empty() ) { + + if (sample_rates.empty ()) { return false; } // check if session desired sample rate (if it's set) could be used with this device if (_session != 0) { - - if ( !set_new_sample_rate_in_controller (_session->nominal_frame_rate ()) ) { - if ( !set_new_sample_rate_in_controller (backend->default_sample_rate() ) ) { - if (!set_new_sample_rate_in_controller (sample_rates.front() ) ) { + + if ( !set_new_sample_rate_in_controller (_session->nominal_frame_rate ())) { + if ( !set_new_sample_rate_in_controller (backend->default_sample_rate ()) ) { + if (!set_new_sample_rate_in_controller (sample_rates.front ()) ) { return false; } } } - + } else { // check if current sample rate is supported because we have no session desired sample rate value - if ( !set_new_sample_rate_in_controller (_current_state->sample_rate) ) { - if ( !set_new_sample_rate_in_controller (backend->default_sample_rate() ) ) { - if (!set_new_sample_rate_in_controller (sample_rates.front() ) ) { + if ( !set_new_sample_rate_in_controller (_current_state->sample_rate)) { + if ( !set_new_sample_rate_in_controller (backend->default_sample_rate ()) ) { + if (!set_new_sample_rate_in_controller (sample_rates.front ()) ) { return false; } } } } - + // validate buffer size std::vector buffer_sizes = backend->available_buffer_sizes (_current_state->device_name); // check if buffer size is supported - std::vector::iterator bs_iter = std::find (buffer_sizes.begin(), buffer_sizes.end(), _current_state->buffer_size); + std::vector::iterator bs_iter = std::find (buffer_sizes.begin (), buffer_sizes.end (), _current_state->buffer_size); // if current is not found switch to default if is supported - if (bs_iter == buffer_sizes.end() ) { - bs_iter = std::find (buffer_sizes.begin(), buffer_sizes.end(), backend->default_buffer_size () ); - - if (bs_iter != buffer_sizes.end() ) { - _current_state->buffer_size = backend->default_buffer_size (); + if (bs_iter == buffer_sizes.end ()) { + bs_iter = std::find (buffer_sizes.begin (), buffer_sizes.end (), backend->default_buffer_size (_current_state->device_name)); + + if (bs_iter != buffer_sizes.end ()) { + _current_state->buffer_size = backend->default_buffer_size (_current_state->device_name); } else { - if (!buffer_sizes.empty() ) { - _current_state->buffer_size = buffer_sizes.front(); + if (!buffer_sizes.empty ()) { + _current_state->buffer_size = buffer_sizes.front (); } } @@ -598,247 +598,326 @@ EngineStateController::_validate_current_device_state() } +void +EngineStateController::_update_ltc_source_port () +{ + // this method is called if the list of ports is changed + + // check that ltc-in port from Config still exists + if (_audio_input_port_exists (get_ltc_source_port ())) { + // audio port, that was saved in Config, exists + return ; + } + + //otherwise set first available audio port + if (!_current_state->input_channel_states.empty ()) { + set_ltc_source_port (_current_state->input_channel_states.front ().name); + return ; + } + + // no available audio-in ports + set_ltc_source_port (""); +} + +void +EngineStateController::_update_ltc_output_port () +{ + // this method is called if the list of ports is changed + + // check that ltc-out port from Config still exists + if (_audio_output_port_exists (get_ltc_output_port ())) { + // audio port, that was saved in Config, exists + return ; + } + + PortStateList* output_states; + if (Config->get_output_auto_connect () & AutoConnectMaster) { + output_states = &_current_state->stereo_out_channel_states; + } else { + output_states = &_current_state->multi_out_channel_states; + } + + //otherwise set first available audio port + if (!output_states->empty ()) { + set_ltc_output_port (output_states->front ().name); + return ; + } + + // no available audio-out ports + set_ltc_output_port (""); +} + + +bool +EngineStateController::_audio_input_port_exists (const std::string& port_name) +{ + PortStateList::const_iterator iter = _current_state->input_channel_states.begin (); + for (; iter != _current_state->input_channel_states.end (); ++iter ) { + if (iter->name == port_name) + return true; + } + return false; +} + +bool +EngineStateController::_audio_output_port_exists (const std::string& port_name) +{ + PortStateList* output_states; + if (Config->get_output_auto_connect () & AutoConnectMaster) { + output_states = &_current_state->stereo_out_channel_states; + } else { + output_states = &_current_state->multi_out_channel_states; + } + + PortStateList::const_iterator iter = output_states->begin (); + for (; iter != output_states->end (); ++iter ) { + if (iter->name == port_name) + return true; + } + return false; +} + + const std::string& -EngineStateController::get_current_backend_name() const +EngineStateController::get_current_backend_name () const { return _current_state->backend_name; } const std::string& -EngineStateController::get_current_device_name() const +EngineStateController::get_current_device_name () const { return _current_state->device_name; } void -EngineStateController::available_backends(std::vector& available_backends) +EngineStateController::available_backends (std::vector& available_backends) { - available_backends = AudioEngine::instance()->available_backends(); + available_backends = AudioEngine::instance ()->available_backends (); } void EngineStateController::enumerate_devices (std::vector& device_vector) const { - boost::shared_ptr backend = AudioEngine::instance()->current_backend(); - assert(backend); - device_vector = backend->enumerate_devices(); + boost::shared_ptr backend = AudioEngine::instance ()->current_backend (); + assert (backend); + device_vector = backend->enumerate_devices (); } framecnt_t -EngineStateController::get_current_sample_rate() const +EngineStateController::get_current_sample_rate () const { return _current_state->sample_rate; } framecnt_t -EngineStateController::get_default_sample_rate() const +EngineStateController::get_default_sample_rate () const { - boost::shared_ptr backend = AudioEngine::instance()->current_backend(); - assert(backend); - return backend->default_sample_rate(); + boost::shared_ptr backend = AudioEngine::instance ()->current_backend (); + assert (backend); + return backend->default_sample_rate (); } void -EngineStateController::available_sample_rates_for_current_device(std::vector& sample_rates) const +EngineStateController::available_sample_rates_for_current_device (std::vector& sample_rates) const { - boost::shared_ptr backend = AudioEngine::instance()->current_backend(); - assert(backend); + boost::shared_ptr backend = AudioEngine::instance ()->current_backend (); + assert (backend); sample_rates = backend->available_sample_rates (_current_state->device_name); } uint32_t -EngineStateController::get_current_buffer_size() const +EngineStateController::get_current_buffer_size () const { return _current_state->buffer_size; } uint32_t -EngineStateController::get_default_buffer_size() const +EngineStateController::get_default_buffer_size () const { - boost::shared_ptr backend = AudioEngine::instance()->current_backend(); - assert(backend); - return backend->default_buffer_size(); + boost::shared_ptr backend = AudioEngine::instance ()->current_backend (); + assert (backend); + return backend->default_buffer_size (_current_state->device_name); } void -EngineStateController::available_buffer_sizes_for_current_device(std::vector& buffer_sizes) const +EngineStateController::available_buffer_sizes_for_current_device (std::vector& buffer_sizes) const { - boost::shared_ptr backend = AudioEngine::instance()->current_backend(); - assert(backend); + boost::shared_ptr backend = AudioEngine::instance ()->current_backend (); + assert (backend); buffer_sizes = backend->available_buffer_sizes (_current_state->device_name); } bool -EngineStateController::set_new_backend_as_current(const std::string& backend_name) +EngineStateController::set_new_backend_as_current (const std::string& backend_name) { - if (backend_name == AudioEngine::instance()->current_backend_name () ) { + if (backend_name == AudioEngine::instance ()->current_backend_name ()) { return true; } - - boost::shared_ptr backend = AudioEngine::instance()->set_backend (backend_name, PROGRAM_NAME, ""); + + boost::shared_ptr backend = AudioEngine::instance ()->set_backend (backend_name, PROGRAM_NAME, ""); if (backend) { if (_current_state != NULL) { _current_state->active = false; } - - StateList::iterator found_state_iter = find_if (_states.begin(), _states.end(), - State::StatePredicate(backend_name, "None") ); - - if (found_state_iter != _states.end() ) { + + StateList::iterator found_state_iter = find_if (_states.begin (), _states.end (), + State::StatePredicate (backend_name, "None")); + + if (found_state_iter != _states.end ()) { // we found a record for new engine with None device - switch to it _current_state = *found_state_iter; - _validate_current_device_state(); + _validate_current_device_state (); } else { // create new record for this engine with default device - _current_state = boost::shared_ptr(new State() ); + _current_state = boost::shared_ptr(new State ()); _current_state->backend_name = backend_name; _current_state->device_name = "None"; - _validate_current_device_state(); - _states.push_front(_current_state); + _validate_current_device_state (); + _states.push_front (_current_state); } - - push_current_state_to_backend(false); - + + push_current_state_to_backend (false); + return true; } - + return false; } bool -EngineStateController::set_new_device_as_current(const std::string& device_name) +EngineStateController::set_new_device_as_current (const std::string& device_name) { if (_current_state->device_name == device_name) { return true; } - - boost::shared_ptr backend = AudioEngine::instance()->current_backend(); - assert(backend); - - std::vector device_vector = backend->enumerate_devices(); - + + boost::shared_ptr backend = AudioEngine::instance ()->current_backend (); + assert (backend); + + std::vector device_vector = backend->enumerate_devices (); + // validate the device std::vector::iterator device_iter; - device_iter = std::find_if (device_vector.begin(), device_vector.end(), DevicePredicate(device_name) ); - + device_iter = std::find_if (device_vector.begin (), device_vector.end (), DevicePredicate (device_name)); + // device is available - if (device_iter != device_vector.end() ) { - + if (device_iter != device_vector.end ()) { + boost::shared_ptr previous_state (_current_state); - + // look through state list and find the record for this device and current engine - StateList::iterator found_state_iter = find_if (_states.begin(), _states.end(), - State::StatePredicate(backend->name(), device_name) ); - - if (found_state_iter != _states.end() ) + StateList::iterator found_state_iter = find_if (_states.begin (), _states.end (), + State::StatePredicate (backend->name (), device_name)); + + if (found_state_iter != _states.end ()) { // we found a record for current engine and provided device name - switch to it - + _current_state = *found_state_iter; - - if (!_validate_current_device_state() ) { + + if (!_validate_current_device_state ()) { _current_state = previous_state; return false; } - + } else { - + // the record is not found, create new one - _current_state = boost::shared_ptr(new State() ); - - _current_state->backend_name = backend->name(); + _current_state = boost::shared_ptr(new State ()); + + _current_state->backend_name = backend->name (); _current_state->device_name = device_name; - - if (!_validate_current_device_state() ) { + + if (!_validate_current_device_state ()) { _current_state = previous_state; return false; } - - _states.push_front(_current_state); + + _states.push_front (_current_state); } - + if (previous_state != NULL) { previous_state->active = false; } - - push_current_state_to_backend(false); - _last_used_real_device.clear(); - + push_current_state_to_backend (false); + + _last_used_real_device.clear (); + if (device_name != "None") { _last_used_real_device = device_name; } - + return true; } - + // device is not supported by current backend return false; } - bool -EngineStateController::set_new_sample_rate_in_controller(framecnt_t sample_rate) +EngineStateController::set_new_sample_rate_in_controller (framecnt_t sample_rate) { - boost::shared_ptr backend = AudioEngine::instance()->current_backend(); - assert(backend); - + boost::shared_ptr backend = AudioEngine::instance ()->current_backend (); + assert (backend); + std::vector sample_rates = backend->available_sample_rates (_current_state->device_name); - std::vector::iterator iter = std::find (sample_rates.begin(), sample_rates.end(), (float)sample_rate); - - if (iter != sample_rates.end() ) { + std::vector::iterator iter = std::find (sample_rates.begin (), sample_rates.end (), (float)sample_rate); + + if (iter != sample_rates.end ()) { _current_state->sample_rate = sample_rate; return true; } - + return false; } bool -EngineStateController::set_new_buffer_size_in_controller(pframes_t buffer_size) -{ - boost::shared_ptr backend = AudioEngine::instance()->current_backend(); - assert(backend); - +EngineStateController::set_new_buffer_size_in_controller (pframes_t buffer_size) +{ + boost::shared_ptr backend = AudioEngine::instance ()->current_backend (); + assert (backend); + std::vector buffer_sizes = backend->available_buffer_sizes (_current_state->device_name); - std::vector::iterator iter = std::find (buffer_sizes.begin(), buffer_sizes.end(), buffer_size); + std::vector::iterator iter = std::find (buffer_sizes.begin (), buffer_sizes.end (), buffer_size); - if (iter != buffer_sizes.end() ) { + if (iter != buffer_sizes.end ()) { _current_state->buffer_size = buffer_size; return true; } - + return false; } uint32_t -EngineStateController::get_available_inputs_count() const +EngineStateController::get_available_inputs_count () const { uint32_t available_channel_count = 0; - - PortStateList::const_iterator iter = _current_state->input_channel_states.begin(); - - for (; iter != _current_state->input_channel_states.end(); ++iter) { + + PortStateList::const_iterator iter = _current_state->input_channel_states.begin (); + + for (; iter != _current_state->input_channel_states.end (); ++iter) { if (iter->active) { ++available_channel_count; } } - + return available_channel_count; } @@ -847,58 +926,58 @@ uint32_t EngineStateController::get_available_outputs_count () const { uint32_t available_channel_count = 0; - + PortStateList* output_states; - if (Config->get_output_auto_connect() & AutoConnectMaster) { + if (Config->get_output_auto_connect () & AutoConnectMaster) { output_states = &_current_state->stereo_out_channel_states; } else { output_states = &_current_state->multi_out_channel_states; } - - PortStateList::const_iterator iter = output_states->begin(); - - for (; iter != output_states->end(); ++iter) { + + PortStateList::const_iterator iter = output_states->begin (); + + for (; iter != output_states->end (); ++iter) { if (iter->active) { ++available_channel_count; } } - + return available_channel_count; } void -EngineStateController::get_physical_audio_inputs(std::vector& port_names) +EngineStateController::get_physical_audio_inputs (std::vector& port_names) { - port_names.clear(); - + port_names.clear (); + PortStateList &input_states = _current_state->input_channel_states; - - PortStateList::iterator iter = input_states.begin(); - for (; iter != input_states.end(); ++iter) { + + PortStateList::iterator iter = input_states.begin (); + for (; iter != input_states.end (); ++iter) { if (iter->active) { - port_names.push_back(iter->name); + port_names.push_back (iter->name); } } } void -EngineStateController::get_physical_audio_outputs(std::vector& port_names) +EngineStateController::get_physical_audio_outputs (std::vector& port_names) { - port_names.clear(); - + port_names.clear (); + PortStateList* output_states; - if (Config->get_output_auto_connect() & AutoConnectMaster) { + if (Config->get_output_auto_connect () & AutoConnectMaster) { output_states = &_current_state->stereo_out_channel_states; } else { output_states = &_current_state->multi_out_channel_states; } - - PortStateList::iterator iter = output_states->begin(); - for (; iter != output_states->end(); ++iter) { + + PortStateList::iterator iter = output_states->begin (); + for (; iter != output_states->end (); ++iter) { if (iter->active) { - port_names.push_back(iter->name); + port_names.push_back (iter->name); } } } @@ -907,12 +986,12 @@ EngineStateController::get_physical_audio_outputs(std::vector& port void EngineStateController::get_physical_midi_inputs (std::vector& port_names) { - port_names.clear(); - - MidiPortStateList::iterator iter = _midi_inputs.begin(); - for (; iter != _midi_inputs.end(); ++iter) { + port_names.clear (); + + MidiPortStateList::iterator iter = _midi_inputs.begin (); + for (; iter != _midi_inputs.end (); ++iter) { if (iter->available && iter->active) { - port_names.push_back(iter->name); + port_names.push_back (iter->name); } } } @@ -921,77 +1000,77 @@ EngineStateController::get_physical_midi_inputs (std::vector& port_ void EngineStateController::get_physical_midi_outputs (std::vector& port_names) { - port_names.clear(); - - MidiPortStateList::iterator iter = _midi_outputs.begin(); - for (; iter != _midi_outputs.end(); ++iter) { + port_names.clear (); + + MidiPortStateList::iterator iter = _midi_outputs.begin (); + for (; iter != _midi_outputs.end (); ++iter) { if (iter->available && iter->active) { - port_names.push_back(iter->name); + port_names.push_back (iter->name); } } } void -EngineStateController::set_physical_audio_input_state(const std::string& port_name, bool state) +EngineStateController::set_physical_audio_input_state (const std::string& port_name, bool state) { PortStateList &input_states = _current_state->input_channel_states; PortStateList::iterator found_state_iter; - found_state_iter = std::find(input_states.begin(), input_states.end(), PortState(port_name) ); - - if (found_state_iter != input_states.end() && found_state_iter->active != state ) { + found_state_iter = std::find (input_states.begin (), input_states.end (), PortState (port_name)); + + if (found_state_iter != input_states.end () && found_state_iter->active != state ) { found_state_iter->active = state; - AudioEngine::instance()->reconnect_session_routes(true, false); - - InputConfigChanged(); + AudioEngine::instance ()->reconnect_session_routes (true, false); + + InputConfigChanged (); } } void -EngineStateController::set_physical_audio_output_state(const std::string& port_name, bool state) +EngineStateController::set_physical_audio_output_state (const std::string& port_name, bool state) { PortStateList* output_states; - if (Config->get_output_auto_connect() & AutoConnectMaster) { + if (Config->get_output_auto_connect () & AutoConnectMaster) { output_states = &_current_state->stereo_out_channel_states; } else { output_states = &_current_state->multi_out_channel_states; } - + PortStateList::iterator target_state_iter; - target_state_iter = std::find(output_states->begin(), output_states->end(), PortState(port_name) ); - - if (target_state_iter != output_states->end() && target_state_iter->active != state ) { + target_state_iter = std::find (output_states->begin (), output_states->end (), PortState (port_name)); + + if (target_state_iter != output_states->end () && target_state_iter->active != state ) { target_state_iter->active = state; - + // if StereoOut mode is used - if (Config->get_output_auto_connect() & AutoConnectMaster) { - + if (Config->get_output_auto_connect () & AutoConnectMaster) { + // get next element - PortStateList::iterator next_state_iter(target_state_iter); - + PortStateList::iterator next_state_iter (target_state_iter); + // loopback - if (++next_state_iter == output_states->end() ) { - next_state_iter = output_states->begin(); + if (++next_state_iter == output_states->end ()) { + next_state_iter = output_states->begin (); } - - + + // only two outputs should be enabled - if (output_states->size() <= 2) { - + if (output_states->size () <= 2) { + target_state_iter->active = true; next_state_iter->active = true; - + } else { - + // if current was set to active - activate next and disable the rest if (target_state_iter->active ) { next_state_iter->active = true; } else { // if current was deactivated but the next is active if (next_state_iter->active) { - if (++next_state_iter == output_states->end() ) { - next_state_iter = output_states->begin(); + if (++next_state_iter == output_states->end ()) { + next_state_iter = output_states->begin (); } next_state_iter->active = true; } else { @@ -1001,63 +1080,63 @@ EngineStateController::set_physical_audio_output_state(const std::string& port_n target_state_iter->active = true; } } - + // now deactivate the rest while (++next_state_iter != target_state_iter) { - - if (next_state_iter == output_states->end() ) { - next_state_iter = output_states->begin(); + + if (next_state_iter == output_states->end ()) { + next_state_iter = output_states->begin (); // we jumped, so additional check is required if (next_state_iter == target_state_iter) { break; } } - + next_state_iter->active = false; } - + } } - - AudioEngine::instance()->reconnect_session_routes(false, true); - OutputConfigChanged(); + + AudioEngine::instance ()->reconnect_session_routes (false, true); + OutputConfigChanged (); } } bool -EngineStateController::get_physical_audio_input_state(const std::string& port_name) +EngineStateController::get_physical_audio_input_state (const std::string& port_name) { bool state = false; - + PortStateList &input_states = _current_state->input_channel_states; PortStateList::iterator found_state_iter; - found_state_iter = std::find(input_states.begin(), input_states.end(), PortState(port_name) ); - - if (found_state_iter != input_states.end() ) { + found_state_iter = std::find (input_states.begin (), input_states.end (), PortState (port_name)); + + if (found_state_iter != input_states.end ()) { state = found_state_iter->active; } - + return state; } bool -EngineStateController::get_physical_audio_output_state(const std::string& port_name) +EngineStateController::get_physical_audio_output_state (const std::string& port_name) { bool state = false; - + PortStateList* output_states; - if (Config->get_output_auto_connect() & AutoConnectMaster) { + if (Config->get_output_auto_connect () & AutoConnectMaster) { output_states = &_current_state->stereo_out_channel_states; } else { output_states = &_current_state->multi_out_channel_states; } - + PortStateList::iterator found_state_iter; - found_state_iter = std::find(output_states->begin(), output_states->end(), PortState(port_name) ); - - if (found_state_iter != output_states->end() ) { + found_state_iter = std::find (output_states->begin (), output_states->end (), PortState (port_name)); + + if (found_state_iter != output_states->end ()) { state = found_state_iter->active; } @@ -1066,260 +1145,264 @@ EngineStateController::get_physical_audio_output_state(const std::string& port_n void -EngineStateController::set_physical_midi_input_state(const std::string& port_name, bool state) { - +EngineStateController::set_physical_midi_input_state (const std::string& port_name, bool state) { + MidiPortStateList::iterator found_state_iter; - found_state_iter = std::find(_midi_inputs.begin(), _midi_inputs.end(), MidiPortState(port_name) ); - - if (found_state_iter != _midi_inputs.end() && found_state_iter->available && found_state_iter->active != state ) { + found_state_iter = std::find (_midi_inputs.begin (), _midi_inputs.end (), MidiPortState (port_name)); + + if (found_state_iter != _midi_inputs.end () && found_state_iter->available && found_state_iter->active != state ) { found_state_iter->active = state; - + if (_session) { // reconnect MTC inputs as well if (found_state_iter->mtc_in) { _session->reconnect_mtc_ports (); } - _session->reconnect_mmc_ports(true); + _session->reconnect_mmc_ports (true); } - - MIDIInputConfigChanged(); + + MIDIInputConfigChanged (); } } void -EngineStateController::set_physical_midi_output_state(const std::string& port_name, bool state) { - +EngineStateController::set_physical_midi_output_state (const std::string& port_name, bool state) { + MidiPortStateList::iterator found_state_iter; - found_state_iter = std::find(_midi_outputs.begin(), _midi_outputs.end(), MidiPortState(port_name) ); - - if (found_state_iter != _midi_outputs.end() && found_state_iter->available && found_state_iter->active != state ) { + found_state_iter = std::find (_midi_outputs.begin (), _midi_outputs.end (), MidiPortState (port_name)); + + if (found_state_iter != _midi_outputs.end () && found_state_iter->available && found_state_iter->active != state ) { found_state_iter->active = state; - + if (_session) { - _session->reconnect_mmc_ports(false); + _session->reconnect_mmc_ports (false); } - - MIDIOutputConfigChanged(); + + MIDIOutputConfigChanged (); } } bool -EngineStateController::get_physical_midi_input_state(const std::string& port_name, bool& scene_connected) { - +EngineStateController::get_physical_midi_input_state (const std::string& port_name, bool& scene_connected) { + bool state = false; - + MidiPortStateList::iterator found_state_iter; - found_state_iter = std::find(_midi_inputs.begin(), _midi_inputs.end(), MidiPortState(port_name) ); - - if (found_state_iter != _midi_inputs.end() && found_state_iter->available) { + found_state_iter = std::find (_midi_inputs.begin (), _midi_inputs.end (), MidiPortState (port_name)); + + if (found_state_iter != _midi_inputs.end () && found_state_iter->available) { state = found_state_iter->active; scene_connected = found_state_iter->scene_connected; } - + return state; } bool -EngineStateController::get_physical_midi_output_state(const std::string& port_name, bool& scene_connected) { - +EngineStateController::get_physical_midi_output_state (const std::string& port_name, bool& scene_connected) { + bool state = false; - + MidiPortStateList::iterator found_state_iter; - found_state_iter = std::find(_midi_outputs.begin(), _midi_outputs.end(), MidiPortState(port_name) ); - - if (found_state_iter != _midi_outputs.end() && found_state_iter->available) { + found_state_iter = std::find (_midi_outputs.begin (), _midi_outputs.end (), MidiPortState (port_name)); + + if (found_state_iter != _midi_outputs.end () && found_state_iter->available) { state = found_state_iter->active; scene_connected = found_state_iter->scene_connected; } - + return state; } void -EngineStateController::set_physical_midi_scene_in_connection_state(const std::string& port_name, bool state) { - +EngineStateController::set_physical_midi_scene_in_connection_state (const std::string& port_name, bool state) { + MidiPortStateList::iterator found_state_iter; - found_state_iter = std::find(_midi_inputs.begin(), _midi_inputs.end(), MidiPortState(port_name) ); - - if (found_state_iter != _midi_inputs.end() && found_state_iter->available && found_state_iter->active ) { + found_state_iter = std::find (_midi_inputs.begin (), _midi_inputs.end (), MidiPortState (port_name)); + + if (found_state_iter != _midi_inputs.end () && found_state_iter->available && found_state_iter->active ) { found_state_iter->scene_connected = state; - + std::vector ports; - ports.push_back(port_name); - MIDISceneInputConnectionChanged(ports, state); + ports.push_back (port_name); + MIDISceneInputConnectionChanged (ports, state); } } void -EngineStateController::set_physical_midi_scenen_out_connection_state(const std::string& port_name, bool state) { - +EngineStateController::set_physical_midi_scenen_out_connection_state (const std::string& port_name, bool state) { + MidiPortStateList::iterator found_state_iter; - found_state_iter = std::find(_midi_outputs.begin(), _midi_outputs.end(), MidiPortState(port_name) ); - - if (found_state_iter != _midi_outputs.end() && found_state_iter->available && found_state_iter->active ) { + found_state_iter = std::find (_midi_outputs.begin (), _midi_outputs.end (), MidiPortState (port_name)); + + if (found_state_iter != _midi_outputs.end () && found_state_iter->available && found_state_iter->active ) { found_state_iter->scene_connected = state; - + std::vector ports; - ports.push_back(port_name); - MIDISceneOutputConnectionChanged(ports, state); + ports.push_back (port_name); + MIDISceneOutputConnectionChanged (ports, state); } } void -EngineStateController::set_all_midi_scene_inputs_disconnected() +EngineStateController::set_all_midi_scene_inputs_disconnected () { - MidiPortStateList::iterator iter = _midi_inputs.begin(); - for (; iter != _midi_inputs.end(); ++iter) { + MidiPortStateList::iterator iter = _midi_inputs.begin (); + for (; iter != _midi_inputs.end (); ++iter) { iter->scene_connected = false; } std::vector ports; - MIDISceneInputConnectionChanged(ports, false); + MIDISceneInputConnectionChanged (ports, false); } void -EngineStateController::set_all_midi_scene_outputs_disconnected() +EngineStateController::set_all_midi_scene_outputs_disconnected () { - MidiPortStateList::iterator iter = _midi_outputs.begin(); - for (; iter != _midi_outputs.end(); ++iter) { + MidiPortStateList::iterator iter = _midi_outputs.begin (); + for (; iter != _midi_outputs.end (); ++iter) { iter->scene_connected = false; } - + std::vector ports; - MIDISceneOutputConnectionChanged(ports, false); + MIDISceneOutputConnectionChanged (ports, false); } void -EngineStateController::set_mtc_input(const std::string& port_name) +EngineStateController::set_mtc_source_port (const std::string& port_name) { - MidiPortStateList::iterator iter = _midi_inputs.begin(); - for (; iter != _midi_inputs.end(); ++iter) { + MidiPortStateList::iterator iter = _midi_inputs.begin (); + for (; iter != _midi_inputs.end (); ++iter) { iter->mtc_in = false; - + if (iter->name == port_name) { iter->mtc_in = true; - + if (_session) { _session->reconnect_mtc_ports (); } } } - - MTCInputChanged(port_name); + + if (_session && port_name.empty ()) { + _session->reconnect_mtc_ports (); + } + + MTCInputChanged (port_name); } void -EngineStateController::set_state_to_all_inputs(bool state) +EngineStateController::set_state_to_all_inputs (bool state) { bool something_changed = false; - - PortStateList::iterator iter = _current_state->input_channel_states.begin(); - for (; iter != _current_state->input_channel_states.end(); ++iter) { + + PortStateList::iterator iter = _current_state->input_channel_states.begin (); + for (; iter != _current_state->input_channel_states.end (); ++iter) { if (iter->active != state) { iter->active = state; something_changed = true; } } - + if (something_changed) { - AudioEngine::instance()->reconnect_session_routes(true, false); - InputConfigChanged(); + AudioEngine::instance ()->reconnect_session_routes (true, false); + InputConfigChanged (); } } void -EngineStateController::set_state_to_all_outputs(bool state) +EngineStateController::set_state_to_all_outputs (bool state) { // unapplicable in Stereo Out mode, just return - if (Config->get_output_auto_connect() & AutoConnectMaster) { + if (Config->get_output_auto_connect () & AutoConnectMaster) { return; } - + bool something_changed = false; - - PortStateList::iterator iter = _current_state->multi_out_channel_states.begin(); - for (; iter != _current_state->multi_out_channel_states.end(); ++iter) { + + PortStateList::iterator iter = _current_state->multi_out_channel_states.begin (); + for (; iter != _current_state->multi_out_channel_states.end (); ++iter) { if (iter->active != state) { iter->active = state; something_changed = true; } } - + if (something_changed) { - AudioEngine::instance()->reconnect_session_routes(false, true); - OutputConfigChanged(); + AudioEngine::instance ()->reconnect_session_routes (false, true); + OutputConfigChanged (); } } void -EngineStateController::get_physical_audio_input_states(std::vector& channel_states) +EngineStateController::get_physical_audio_input_states (std::vector& channel_states) { PortStateList &input_states = _current_state->input_channel_states; - channel_states.assign(input_states.begin(), input_states.end()); + channel_states.assign (input_states.begin (), input_states.end ()); } void -EngineStateController::get_physical_audio_output_states(std::vector& channel_states) +EngineStateController::get_physical_audio_output_states (std::vector& channel_states) { PortStateList* output_states; - if (Config->get_output_auto_connect() & AutoConnectMaster) { + if (Config->get_output_auto_connect () & AutoConnectMaster) { output_states = &_current_state->stereo_out_channel_states; } else { output_states = &_current_state->multi_out_channel_states; } - - channel_states.assign(output_states->begin(), output_states->end()); + + channel_states.assign (output_states->begin (), output_states->end ()); } void EngineStateController::get_physical_midi_input_states (std::vector& channel_states) { - channel_states.clear(); - - MidiPortStateList::iterator iter = _midi_inputs.begin(); - - for (; iter != _midi_inputs.end(); ++iter ) { + channel_states.clear (); + + MidiPortStateList::iterator iter = _midi_inputs.begin (); + + for (; iter != _midi_inputs.end (); ++iter ) { if (iter->available) { - MidiPortState state(iter->name); + MidiPortState state (iter->name); state.active = iter->active; state.available = true; state.scene_connected = iter->scene_connected; state.mtc_in = iter->mtc_in; - channel_states.push_back(state); + channel_states.push_back (state); } - } + } } void EngineStateController::get_physical_midi_output_states (std::vector& channel_states) { - channel_states.clear(); - - MidiPortStateList::iterator iter = _midi_outputs.begin(); - - for (; iter != _midi_outputs.end(); ++iter ) { + channel_states.clear (); + + MidiPortStateList::iterator iter = _midi_outputs.begin (); + + for (; iter != _midi_outputs.end (); ++iter ) { if (iter->available) { - MidiPortState state(iter->name); + MidiPortState state (iter->name); state.active = iter->active; state.available = true; state.scene_connected = iter->scene_connected; state.mtc_in = iter->mtc_in; - channel_states.push_back(state); + channel_states.push_back (state); } } } @@ -1331,199 +1414,203 @@ EngineStateController::_on_session_loaded () if (!_session) { return; } - - AudioEngine::instance()->reconnect_session_routes(true, true); + + AudioEngine::instance ()->reconnect_session_routes (true, true); _session->reconnect_mtc_ports (); _session->reconnect_mmc_ports (true); _session->reconnect_mmc_ports (false); - + + // This is done during session construction + // _session->reconnect_ltc_input (); + // _session->reconnect_ltc_output (); + framecnt_t desired_sample_rate = _session->nominal_frame_rate (); - if ( desired_sample_rate > 0 && set_new_sample_rate_in_controller(desired_sample_rate) ) + if ( desired_sample_rate > 0 && set_new_sample_rate_in_controller (desired_sample_rate)) { - push_current_state_to_backend(false); - SampleRateChanged(); // emit a signal + push_current_state_to_backend (false); + SampleRateChanged (); // emit a signal } } void -EngineStateController::_on_sample_rate_change(framecnt_t new_sample_rate) +EngineStateController::_on_sample_rate_change (framecnt_t new_sample_rate) { if (_current_state->sample_rate != new_sample_rate) { - + // if sample rate has been changed framecnt_t sample_rate_to_set = new_sample_rate; - if (AudioEngine::instance()->session() ) { + if (AudioEngine::instance ()->session ()) { // and we have current session we should restore it back to the one tracks uses - sample_rate_to_set = AudioEngine::instance()->session()->frame_rate (); + sample_rate_to_set = AudioEngine::instance ()->session ()->frame_rate (); } - - if ( !set_new_sample_rate_in_controller (sample_rate_to_set) ) { + + if ( !set_new_sample_rate_in_controller (sample_rate_to_set)) { // if sample rate can't be set // switch to NONE device set_new_device_as_current ("None"); - DeviceListChanged(false); - DeviceError(); + DeviceListChanged (false); + DeviceError (); } } - - SampleRateChanged(); // emit a signal + + SampleRateChanged (); // emit a signal } void -EngineStateController::_on_buffer_size_change(pframes_t new_buffer_size) +EngineStateController::_on_buffer_size_change (pframes_t new_buffer_size) { if (_current_state->buffer_size != new_buffer_size) { _current_state->buffer_size = new_buffer_size; } - - BufferSizeChanged(); // emit a signal + + BufferSizeChanged (); // emit a signal } void -EngineStateController::_on_device_list_change() +EngineStateController::_on_device_list_change () { bool current_device_disconnected = false; - - boost::shared_ptr backend = AudioEngine::instance()->current_backend(); - assert(backend); - - std::vector device_vector = backend->enumerate_devices(); - + + boost::shared_ptr backend = AudioEngine::instance ()->current_backend (); + assert (backend); + + std::vector device_vector = backend->enumerate_devices (); + // find out out if current device is still available if it's not None if (_current_state->device_name != "None") { std::vector::iterator device_iter; - device_iter = std::find_if (device_vector.begin(), device_vector.end(), DevicePredicate(_current_state->device_name) ); - + device_iter = std::find_if (device_vector.begin (), device_vector.end (), DevicePredicate (_current_state->device_name)); + // if current device is not available any more - switch to None device - if (device_iter == device_vector.end() ) { - - StateList::iterator found_state_iter = find_if (_states.begin(), _states.end(), - State::StatePredicate(_current_state->backend_name, "None") ); - - if (found_state_iter != _states.end() ) { + if (device_iter == device_vector.end ()) { + + StateList::iterator found_state_iter = find_if (_states.begin (), _states.end (), + State::StatePredicate (_current_state->backend_name, "None")); + + if (found_state_iter != _states.end ()) { // found the record - switch to it _current_state = *found_state_iter; - _validate_current_device_state(); + _validate_current_device_state (); } else { // create new record for this engine with default device - _current_state = boost::shared_ptr(new State() ); - _current_state->backend_name = backend->name(); + _current_state = boost::shared_ptr(new State ()); + _current_state->backend_name = backend->name (); _current_state->device_name = "None"; - _validate_current_device_state(); - _states.push_front(_current_state); + _validate_current_device_state (); + _states.push_front (_current_state); } - - push_current_state_to_backend(true); + + push_current_state_to_backend (true); current_device_disconnected = true; } } else { // if the device which was active before is available now - switch to it - + std::vector::iterator device_iter; - device_iter = std::find_if (device_vector.begin(), device_vector.end(), DevicePredicate(_last_used_real_device) ); - - if (device_iter != device_vector.end() ) { - StateList::iterator found_state_iter = find_if (_states.begin(), _states.end(), - State::StatePredicate(_current_state->backend_name, - _last_used_real_device) ); - - if (found_state_iter != _states.end() ) { - + device_iter = std::find_if (device_vector.begin (), device_vector.end (), DevicePredicate (_last_used_real_device)); + + if (device_iter != device_vector.end ()) { + StateList::iterator found_state_iter = find_if (_states.begin (), _states.end (), + State::StatePredicate (_current_state->backend_name, + _last_used_real_device)); + + if (found_state_iter != _states.end ()) { + boost::shared_ptr previous_state (_current_state); _current_state = *found_state_iter; - - if (_validate_current_device_state() ) { - push_current_state_to_backend(false); + + if (_validate_current_device_state ()) { + push_current_state_to_backend (false); } else { // cannot use this device right now - _last_used_real_device.clear(); + _last_used_real_device.clear (); _current_state = previous_state; } } } } - - DeviceListChanged(current_device_disconnected); // emit a signal + + DeviceListChanged (current_device_disconnected); // emit a signal } void -EngineStateController::_update_device_channels_state() +EngineStateController::_update_device_channels_state () { - boost::shared_ptr backend = AudioEngine::instance()->current_backend(); - assert(backend); - + boost::shared_ptr backend = AudioEngine::instance ()->current_backend (); + assert (backend); + // update audio input states std::vector phys_audio_inputs; - backend->get_physical_inputs(DataType::AUDIO, phys_audio_inputs); - + backend->get_physical_inputs (DataType::AUDIO, phys_audio_inputs); + PortStateList new_input_states; PortStateList &input_states = _current_state->input_channel_states; - - std::vector::const_iterator input_iter = phys_audio_inputs.begin(); - for (; input_iter != phys_audio_inputs.end(); ++input_iter) { - - PortState state(*input_iter); + + std::vector::const_iterator input_iter = phys_audio_inputs.begin (); + for (; input_iter != phys_audio_inputs.end (); ++input_iter) { + + PortState state (*input_iter); state.active = true; - PortStateList::const_iterator found_state_iter = std::find(input_states.begin(), input_states.end(), state); - - if (found_state_iter != input_states.end() ) { - new_input_states.push_back(*found_state_iter); + PortStateList::const_iterator found_state_iter = std::find (input_states.begin (), input_states.end (), state); + + if (found_state_iter != input_states.end ()) { + new_input_states.push_back (*found_state_iter); } else { - new_input_states.push_back(state); + new_input_states.push_back (state); } } _current_state->input_channel_states = new_input_states; - + // update audio output states (multi out mode) std::vector phys_audio_outputs; - backend->get_physical_outputs(DataType::AUDIO, phys_audio_outputs); - + backend->get_physical_outputs (DataType::AUDIO, phys_audio_outputs); + PortStateList new_output_states; PortStateList &output_multi_states = _current_state->multi_out_channel_states; - - std::vector::const_iterator output_iter = phys_audio_outputs.begin(); - for (; output_iter != phys_audio_outputs.end(); ++output_iter) { - - PortState state(*output_iter); + + std::vector::const_iterator output_iter = phys_audio_outputs.begin (); + for (; output_iter != phys_audio_outputs.end (); ++output_iter) { + + PortState state (*output_iter); state.active = true; - PortStateList::const_iterator found_state_iter = std::find(output_multi_states.begin(), output_multi_states.end(), state); - - if (found_state_iter != output_multi_states.end() ) { - new_output_states.push_back(*found_state_iter); + PortStateList::const_iterator found_state_iter = std::find (output_multi_states.begin (), output_multi_states.end (), state); + + if (found_state_iter != output_multi_states.end ()) { + new_output_states.push_back (*found_state_iter); } else { - new_output_states.push_back(state); + new_output_states.push_back (state); } } - + _current_state->multi_out_channel_states = new_output_states; - + // update audio output states (stereo out mode) - new_output_states.clear(); + new_output_states.clear (); PortStateList &output_stereo_states = _current_state->stereo_out_channel_states; - - output_iter = phys_audio_outputs.begin(); - for (; output_iter != phys_audio_outputs.end(); ++output_iter) { - - PortState state(*output_iter); + + output_iter = phys_audio_outputs.begin (); + for (; output_iter != phys_audio_outputs.end (); ++output_iter) { + + PortState state (*output_iter); state.active = true; - PortStateList::const_iterator found_state_iter = std::find(output_stereo_states.begin(), output_stereo_states.end(), state); - - if (found_state_iter != output_stereo_states.end() ) { - new_output_states.push_back(*found_state_iter); + PortStateList::const_iterator found_state_iter = std::find (output_stereo_states.begin (), output_stereo_states.end (), state); + + if (found_state_iter != output_stereo_states.end ()) { + new_output_states.push_back (*found_state_iter); } else { - new_output_states.push_back(state); + new_output_states.push_back (state); } } _current_state->stereo_out_channel_states = new_output_states; - _refresh_stereo_out_channel_states(); - - + _refresh_stereo_out_channel_states (); + + // update midi ports: unlike audio ports which states are saved per device // each midi port state is saved individualy // so get all midi ports from the backend @@ -1531,82 +1618,82 @@ EngineStateController::_update_device_channels_state() // if physical port is new, add it to our state list // if physical port is present in our state list - mark it available // if there is no corresponding physical port to one we have in a list - leave it unavailable - MidiPortStateList::iterator iter = _midi_inputs.begin(); - for (; iter != _midi_inputs.end(); ++iter) { + MidiPortStateList::iterator iter = _midi_inputs.begin (); + for (; iter != _midi_inputs.end (); ++iter) { iter->available = false; } - - for (iter = _midi_outputs.begin(); iter != _midi_outputs.end(); ++iter) { + + for (iter = _midi_outputs.begin (); iter != _midi_outputs.end (); ++iter) { iter->available = false; } - + // update midi input ports std::vector phys_midi_inputs; - backend->get_physical_inputs(DataType::MIDI, phys_midi_inputs); - - std::vector::const_iterator midi_input_iter = phys_midi_inputs.begin(); - for (; midi_input_iter != phys_midi_inputs.end(); ++midi_input_iter) { - - MidiPortState state(*midi_input_iter); + backend->get_physical_inputs (DataType::MIDI, phys_midi_inputs); + + std::vector::const_iterator midi_input_iter = phys_midi_inputs.begin (); + for (; midi_input_iter != phys_midi_inputs.end (); ++midi_input_iter) { + + MidiPortState state (*midi_input_iter); state.active = false; state.available = true; - MidiPortStateList::iterator found_state_iter = std::find(_midi_inputs.begin(), _midi_inputs.end(), state); - - if (found_state_iter != _midi_inputs.end() ) { + MidiPortStateList::iterator found_state_iter = std::find (_midi_inputs.begin (), _midi_inputs.end (), state); + + if (found_state_iter != _midi_inputs.end ()) { found_state_iter->available = true; } else { - _midi_inputs.push_back(state); + _midi_inputs.push_back (state); } } - + // update midi output ports std::vector phys_midi_outputs; - backend->get_physical_outputs(DataType::MIDI, phys_midi_outputs); - - std::vector::const_iterator midi_output_iter = phys_midi_outputs.begin(); - for (; midi_output_iter != phys_midi_outputs.end(); ++midi_output_iter) { - - MidiPortState state(*midi_output_iter); + backend->get_physical_outputs (DataType::MIDI, phys_midi_outputs); + + std::vector::const_iterator midi_output_iter = phys_midi_outputs.begin (); + for (; midi_output_iter != phys_midi_outputs.end (); ++midi_output_iter) { + + MidiPortState state (*midi_output_iter); state.active = false; state.available = true; - MidiPortStateList::iterator found_state_iter = std::find(_midi_outputs.begin(), _midi_outputs.end(), state); - - if (found_state_iter != _midi_outputs.end() ) { + MidiPortStateList::iterator found_state_iter = std::find (_midi_outputs.begin (), _midi_outputs.end (), state); + + if (found_state_iter != _midi_outputs.end ()) { found_state_iter->available = true; } else { - _midi_outputs.push_back(state); + _midi_outputs.push_back (state); } } } void -EngineStateController::_refresh_stereo_out_channel_states() +EngineStateController::_refresh_stereo_out_channel_states () { PortStateList &output_states = _current_state->stereo_out_channel_states; - PortStateList::iterator active_iter = output_states.begin(); + PortStateList::iterator active_iter = output_states.begin (); - for (; active_iter != output_states.end(); ++active_iter) { + for (; active_iter != output_states.end (); ++active_iter) { if (active_iter->active) { break; } } - + uint32_t pending_active_channels = 2; - PortStateList::iterator iter = output_states.begin(); + PortStateList::iterator iter = output_states.begin (); // if found active - if (active_iter != output_states.end() ) { + if (active_iter != output_states.end ()) { iter = active_iter; - if (++iter == output_states.end() ) { - iter = output_states.begin(); + if (++iter == output_states.end ()) { + iter = output_states.begin (); } - + (iter++)->active = true; pending_active_channels = 0; } // drop the rest of the states to false (until we reach the end or first existing active channel) - for (; iter != output_states.end() && iter != active_iter; ++iter) { + for (; iter != output_states.end () && iter != active_iter; ++iter) { if (pending_active_channels) { iter->active = true; --pending_active_channels; @@ -1620,34 +1707,34 @@ EngineStateController::_refresh_stereo_out_channel_states() void EngineStateController::_on_engine_running () { - AudioEngine::instance()->reconnect_session_routes(true, true); + AudioEngine::instance ()->reconnect_session_routes (true, true); _current_state->active = true; - - EngineRunning(); // emit a signal + + EngineRunning (); // emit a signal } void EngineStateController::_on_engine_stopped () { - EngineStopped(); + EngineStopped (); } void EngineStateController::_on_engine_halted () { - EngineHalted(); + EngineHalted (); } void -EngineStateController::_on_device_error() +EngineStateController::_on_device_error () { set_new_device_as_current ("None"); - push_current_state_to_backend(true); - DeviceListChanged(false); - DeviceError(); + push_current_state_to_backend (true); + DeviceListChanged (false); + DeviceError (); } @@ -1655,10 +1742,10 @@ void EngineStateController::_on_parameter_changed (const std::string& parameter_name) { if (parameter_name == "output-auto-connect") { - - AudioEngine::instance()->reconnect_session_routes(false, true); - OutputConfigChanged(); // emit a signal - OutputConnectionModeChanged(); // emit signal + + AudioEngine::instance ()->reconnect_session_routes (false, true); + OutputConfigChanged (); // emit a signal + OutputConnectionModeChanged (); // emit signal } } @@ -1666,44 +1753,59 @@ EngineStateController::_on_parameter_changed (const std::string& parameter_name) void EngineStateController::_on_ports_registration_update () { - _update_device_channels_state(); - + _update_device_channels_state (); + // update MIDI connections if (_session) { _session->reconnect_midi_scene_ports (true); _session->reconnect_midi_scene_ports (false); - + _session->reconnect_mtc_ports (); - + _session->reconnect_mmc_ports (true); _session->reconnect_mmc_ports (false); + + _session->reconnect_ltc_input (); + _session->reconnect_ltc_output (); } - - PortRegistrationChanged(); // emit a signal + + _update_ltc_source_port (); + _update_ltc_output_port (); + + PortRegistrationChanged (); // emit a signal } bool -EngineStateController::push_current_state_to_backend(bool start) +EngineStateController::push_current_state_to_backend (bool start) { - boost::shared_ptr backend = AudioEngine::instance()->current_backend(); - + boost::shared_ptr backend = AudioEngine::instance ()->current_backend (); + if (!backend) { return false; } - + // check if anything changed - bool state_changed = (_current_state->device_name != backend->device_name() ) || - (_current_state->sample_rate != backend->sample_rate() ) || - (_current_state->buffer_size != backend->buffer_size() ); - - bool was_running = AudioEngine::instance()->running(); - - Glib::Threads::RecMutex::Lock sl (AudioEngine::instance()->state_lock() ); + bool state_changed = (_current_state->device_name != backend->device_name ()) || + (_current_state->sample_rate != backend->sample_rate ()) || + (_current_state->buffer_size != backend->buffer_size ()); + + bool was_running = AudioEngine::instance ()->running (); + + Glib::Threads::RecMutex::Lock sl (AudioEngine::instance ()->state_lock ()); if (state_changed) { if (was_running) { - if (AudioEngine::instance()->stop () ) { + + if (_current_state->device_name != backend->device_name ()) { + // device has been changed + // the list of ports has been changed too + // current ltc_source_port and ltc_output_port aren't available + set_ltc_source_port (""); + set_ltc_output_port (""); + } + + if (AudioEngine::instance ()->stop ()) { return false; } } @@ -1711,56 +1813,95 @@ EngineStateController::push_current_state_to_backend(bool start) int result = 0; { std::cout << "EngineStateController::Setting device: " << _current_state->device_name << std::endl; - if ((_current_state->device_name != backend->device_name()) && (result = backend->set_device_name (_current_state->device_name)) ) { - error << string_compose (_("Cannot set device name to %1"), get_current_device_name()) << endmsg; + if ((_current_state->device_name != backend->device_name ()) && (result = backend->set_device_name (_current_state->device_name))) { + error << string_compose (_("Cannot set device name to %1"), get_current_device_name ()) << endmsg; } - + if (!result ) { std::cout << "EngineStateController::Setting device sample rate " << _current_state->sample_rate << std::endl; result = backend->set_sample_rate (_current_state->sample_rate); - + if (result) { - error << string_compose (_("Cannot set sample rate to %1"), get_current_sample_rate()) << endmsg; + error << string_compose (_("Cannot set sample rate to %1"), get_current_sample_rate ()) << endmsg; } } - + if (!result ) { std::cout << "EngineStateController::Setting device buffer size " << _current_state->buffer_size << std::endl; result = backend->set_buffer_size (_current_state->buffer_size); if (result) { - error << string_compose (_("Cannot set buffer size to %1"), get_current_buffer_size()) << endmsg; + error << string_compose (_("Cannot set buffer size to %1"), get_current_buffer_size ()) << endmsg; } } } - + if (result) // error during device setup { //switch to None device and notify about the issue set_new_device_as_current ("None"); - DeviceListChanged(false); - DeviceError(); + DeviceListChanged (false); + DeviceError (); } - if (AudioEngine::instance()->backend_reset_requested() ) { + if (AudioEngine::instance ()->backend_reset_requested ()) { // device asked for reset, do not start engine now // free sate lock and let Engine reset the device as it's required return true; } } - - if(start || (was_running && state_changed) ) { - if (AudioEngine::instance()->start () && !AudioEngine::instance()->is_reset_requested() ) { + + if (start || (was_running && state_changed)) { + if (AudioEngine::instance ()->start () && !AudioEngine::instance ()->is_reset_requested ()) { //switch to None device and notify about the issue set_new_device_as_current ("None"); - AudioEngine::instance()->start (); - DeviceListChanged(false); - DeviceError(); + AudioEngine::instance ()->start (); + DeviceListChanged (false); + DeviceError (); return false; } } - - save_audio_midi_settings(); - + + save_audio_midi_settings (); + return true; } + + +std::string +EngineStateController::get_mtc_source_port () +{ + MidiPortStateList::const_iterator state_iter = _midi_inputs.begin (); + for (; state_iter != _midi_inputs.end (); ++state_iter) { + if (state_iter->available && state_iter->mtc_in) { + return (state_iter->name); + } + } + + return ""; +} + +void +EngineStateController::set_ltc_source_port (const std::string& port) +{ + Config->set_ltc_source_port (port); +} + +std::string +EngineStateController::get_ltc_source_port () +{ + return Config->get_ltc_source_port (); +} + +void +EngineStateController::set_ltc_output_port (const std::string& port) +{ + Config->set_ltc_output_port (port); +} + +std::string +EngineStateController::get_ltc_output_port () +{ + return Config->get_ltc_output_port (); +} +