diff options
Diffstat (limited to 'libs/ardour')
-rw-r--r-- | libs/ardour/SConscript | 2 | ||||
-rw-r--r-- | libs/ardour/ardour/ardour.h | 3 | ||||
-rw-r--r-- | libs/ardour/ardour/basic_ui.h | 34 | ||||
-rw-r--r-- | libs/ardour/ardour/configuration.h | 3 | ||||
-rw-r--r-- | libs/ardour/ardour/control_protocol.h | 48 | ||||
-rw-r--r-- | libs/ardour/ardour/control_protocol_manager.h | 11 | ||||
-rw-r--r-- | libs/ardour/ardour/session.h | 2 | ||||
-rw-r--r-- | libs/ardour/basic_ui.cc | 189 | ||||
-rw-r--r-- | libs/ardour/configuration.cc | 7 | ||||
-rw-r--r-- | libs/ardour/control_protocol.cc | 214 | ||||
-rw-r--r-- | libs/ardour/control_protocol_manager.cc | 69 | ||||
-rw-r--r-- | libs/ardour/globals.cc | 18 | ||||
-rw-r--r-- | libs/ardour/session_state.cc | 13 | ||||
-rw-r--r-- | libs/ardour/session_transport.cc | 10 |
14 files changed, 357 insertions, 266 deletions
diff --git a/libs/ardour/SConscript b/libs/ardour/SConscript index 572851d2f2..3d83b3e276 100644 --- a/libs/ardour/SConscript +++ b/libs/ardour/SConscript @@ -29,6 +29,7 @@ audioregion.cc auditioner.cc automation.cc automation_event.cc +basic_ui.cc configuration.cc connection.cc control_protocol.cc @@ -99,6 +100,7 @@ if ardour['VST']: ardour.Append(CCFLAGS="-D_REENTRANT -D_LARGEFILE_SOURCE -D_LARGEFILE64_SOURCE") ardour.Append(CXXFLAGS="-DDATA_DIR=\\\""+final_prefix+"/share\\\"") +ardour.Append(CXXFLAGS="-DMODULE_DIR=\\\""+final_prefix+"/lib\\\"") ardour.Append(CXXFLAGS="-DCONFIG_DIR=\\\""+final_config_prefix+"\\\"") ardour.Append(CXXFLAGS="-DLOCALEDIR=\\\""+final_prefix+"/share/locale\\\"") diff --git a/libs/ardour/ardour/ardour.h b/libs/ardour/ardour/ardour.h index 45b45ecd06..28c5f07fce 100644 --- a/libs/ardour/ardour/ardour.h +++ b/libs/ardour/ardour/ardour.h @@ -50,7 +50,8 @@ namespace ARDOUR { std::string get_user_ardour_path (); - std::string get_system_ardour_path (); + std::string get_system_data_path (); + std::string get_system_module_path (); std::string find_config_file (std::string name); std::string find_data_file (std::string name, std::string subdir = "" ); diff --git a/libs/ardour/ardour/basic_ui.h b/libs/ardour/ardour/basic_ui.h new file mode 100644 index 0000000000..aba8090add --- /dev/null +++ b/libs/ardour/ardour/basic_ui.h @@ -0,0 +1,34 @@ +#ifndef __ardour_basic_ui_h__ +#define __ardour_basic_ui_h__ + +namespace ARDOUR { + class Session; +} + +class BasicUI { + public: + BasicUI (ARDOUR::Session&); + virtual ~BasicUI (); + + void loop_toggle (); + void goto_start (); + void goto_end (); + void add_marker (); + void rewind (); + void ffwd (); + void transport_stop (); + void transport_play (); + void rec_enable_toggle (); + void save_state (); + void prev_marker (); + void next_marker (); + void move_at (float speed); + void undo (); + void redo (); + void toggle_all_rec_enables (); + + protected: + ARDOUR::Session& session; +}; + +#endif /* __ardour_basic_ui_h__ */ diff --git a/libs/ardour/ardour/configuration.h b/libs/ardour/ardour/configuration.h index d067bc6e61..60b5e8a2c3 100644 --- a/libs/ardour/ardour/configuration.h +++ b/libs/ardour/ardour/configuration.h @@ -60,6 +60,8 @@ class Configuration : public Stateful int set_state (const XMLNode&); XMLNode& get_state (void); + XMLNode* control_protocol_state () { return _control_protocol_state; } + /* define accessor methods */ #undef CONFIG_VARIABLE @@ -88,6 +90,7 @@ class Configuration : public Stateful #undef CONFIG_VARIABLE_SPECIAL bool user_configuration; + XMLNode* _control_protocol_state; XMLNode& state (bool user_only); }; diff --git a/libs/ardour/ardour/control_protocol.h b/libs/ardour/ardour/control_protocol.h index 64658fc199..70c7d2dc0d 100644 --- a/libs/ardour/ardour/control_protocol.h +++ b/libs/ardour/ardour/control_protocol.h @@ -5,37 +5,25 @@ #include <list> #include <sigc++/sigc++.h> +#include <ardour/basic_ui.h> + namespace ARDOUR { class Route; class Session; -class ControlProtocol : public sigc::trackable { +class ControlProtocol : public sigc::trackable, public BasicUI { public: ControlProtocol (Session&, std::string name); virtual ~ControlProtocol(); - virtual int init () { return 0; } - - sigc::signal<void> ActiveChanged; - - enum SendWhat { - SendRoute, - SendGlobal - }; - std::string name() const { return _name; } - void set_send (SendWhat); - void set_active (bool yn); - bool get_active() const { return active_thread > 0; } + virtual int set_active (bool yn) = 0; + bool get_active() const { return _active; } - bool send() const { return _send != 0; } - bool send_route_feedback () const { return _send & SendRoute; } - bool send_global_feedback () const { return _send & SendGlobal; } + sigc::signal<void> ActiveChanged; - virtual void send_route_feedback (std::list<Route*>&) {} - virtual void send_global_feedback () {} /* signals that a control protocol can emit and other (presumably graphical) user interfaces can respond to @@ -48,30 +36,8 @@ class ControlProtocol : public sigc::trackable { static sigc::signal<void,float> ScrollTimeline; protected: - - ARDOUR::Session& session; - SendWhat _send; std::string _name; - int active_thread; - int thread_request_pipe[2]; - pthread_t _thread; - - static void* _thread_work (void *); - void* thread_work (); - - struct ThreadRequest { - enum Type { - Start, - Stop, - Quit - }; - }; - - int init_thread(); - int start_thread (); - int stop_thread (); - void terminate_thread (); - int poke_thread (ThreadRequest::Type); + bool _active; }; extern "C" { diff --git a/libs/ardour/ardour/control_protocol_manager.h b/libs/ardour/ardour/control_protocol_manager.h index b06c3024b6..c19649e38b 100644 --- a/libs/ardour/ardour/control_protocol_manager.h +++ b/libs/ardour/ardour/control_protocol_manager.h @@ -8,6 +8,8 @@ #include <pbd/lockmonitor.h> +#include <ardour/stateful.h> + namespace ARDOUR { class ControlProtocol; @@ -19,9 +21,10 @@ struct ControlProtocolInfo { ControlProtocol* protocol; std::string name; std::string path; + bool requested; }; - class ControlProtocolManager : public sigc::trackable + class ControlProtocolManager : public sigc::trackable, public Stateful { public: ControlProtocolManager (); @@ -38,6 +41,11 @@ struct ControlProtocolInfo { std::list<ControlProtocolInfo*> control_protocol_info; + static const std::string state_node_name; + + int set_state (const XMLNode&); + XMLNode& get_state (void); + private: static ControlProtocolManager* _instance; @@ -49,6 +57,7 @@ struct ControlProtocolInfo { int control_protocol_discover (std::string path); ControlProtocolDescriptor* get_descriptor (std::string path); + ControlProtocolInfo* cpi_by_name (std::string); }; } // namespace diff --git a/libs/ardour/ardour/session.h b/libs/ardour/ardour/session.h index 924a482936..57f01bf690 100644 --- a/libs/ardour/ardour/session.h +++ b/libs/ardour/ardour/session.h @@ -245,7 +245,7 @@ class Session : public sigc::trackable, public Stateful std::string dead_sound_dir () const; std::string automation_dir () const; - static string suffixed_search_path (std::string suffix); + static string suffixed_search_path (std::string suffix, bool data); static string control_protocol_path (); static string template_path (); static string template_dir (); diff --git a/libs/ardour/basic_ui.cc b/libs/ardour/basic_ui.cc new file mode 100644 index 0000000000..fcbd672cf4 --- /dev/null +++ b/libs/ardour/basic_ui.cc @@ -0,0 +1,189 @@ +/* + Copyright (C) 2006 Paul Davis + + 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. + + $Id$ +*/ + +#include <ardour/basic_ui.h> +#include <ardour/session.h> +#include <ardour/location.h> + +#include "i18n.h" + +using namespace ARDOUR; + +BasicUI::BasicUI (Session& s) + : session (s) +{ +} + +BasicUI::~BasicUI () +{ + +} + +void +BasicUI::loop_toggle () +{ + if (session.get_auto_loop()) { + session.request_auto_loop (false); + } else { + session.request_auto_loop (true); + if (!session.transport_rolling()) { + session.request_transport_speed (1.0); + } + } +} + +void +BasicUI::goto_start () +{ + session.goto_start (); +} + +void +BasicUI::goto_end () +{ + session.goto_end (); +} + +void +BasicUI::add_marker () +{ + jack_nframes_t when = session.audible_frame(); + session.locations()->add (new Location (when, when, _("unnamed"), Location::IsMark)); +} + +void +BasicUI::rewind () +{ + session.request_transport_speed (-2.0f); +} + +void +BasicUI::ffwd () +{ + session.request_transport_speed (2.0f); +} + +void +BasicUI::transport_stop () +{ + session.request_transport_speed (0.0); +} + +void +BasicUI::transport_play () +{ + bool rolling = session.transport_rolling (); + + if (session.get_auto_loop()) { + session.request_auto_loop (false); + } + + if (session.get_play_range ()) { + session.request_play_range (false); + } + + if (rolling) { + session.request_locate (session.last_transport_start(), true); + + } + + session.request_transport_speed (1.0f); +} + +void +BasicUI::rec_enable_toggle () +{ + switch (session.record_status()) { + case Session::Disabled: + if (session.ntracks() == 0) { + // string txt = _("Please create 1 or more track\nbefore trying to record.\nCheck the Session menu."); + // MessageDialog msg (*editor, txt); + // msg.run (); + return; + } + session.maybe_enable_record (); + break; + case Session::Recording: + case Session::Enabled: + session.disable_record (true); + } +} + +void +BasicUI::save_state () +{ + session.save_state (""); +} + +void +BasicUI::prev_marker () +{ + Location *location = session.locations()->first_location_before (session.transport_frame()); + + if (location) { + session.request_locate (location->start(), session.transport_rolling()); + } else { + session.goto_start (); + } +} + +void +BasicUI::next_marker () +{ + Location *location = session.locations()->first_location_after (session.transport_frame()); + + if (location) { + session.request_locate (location->start(), session.transport_rolling()); + } else { + session.request_locate (session.current_end_frame()); + } +} + +void +BasicUI::move_at (float speed) +{ + session.request_transport_speed (speed); +} + +void +BasicUI::undo () +{ + session.undo (1); +} + +void +BasicUI::redo () +{ + session.redo (1); +} + +void +BasicUI::toggle_all_rec_enables () +{ + if (session.get_record_enabled()) { + session.record_disenable_all (); + } else { + session.record_enable_all (); + } +} + + + + diff --git a/libs/ardour/configuration.cc b/libs/ardour/configuration.cc index 1581e5216e..b7b1d65815 100644 --- a/libs/ardour/configuration.cc +++ b/libs/ardour/configuration.cc @@ -28,6 +28,7 @@ #include <ardour/configuration.h> #include <ardour/diskstream.h> #include <ardour/destructive_filesource.h> +#include <ardour/control_protocol_manager.h> #include "i18n.h" @@ -55,6 +56,7 @@ Configuration::Configuration () user_configuration (false) { + _control_protocol_state = 0; } Configuration::~Configuration () @@ -174,6 +176,8 @@ Configuration::state (bool user_only) root->add_child_copy (*_extra_xml); } + root->add_child_nocopy (ControlProtocolManager::instance().get_state()); + return *root; } @@ -221,6 +225,9 @@ Configuration::set_state (const XMLNode& root) } else if (node->name() == "extra") { _extra_xml = new XMLNode (*node); + + } else if (node->name() == ControlProtocolManager::state_node_name) { + _control_protocol_state = new XMLNode (*node); } } diff --git a/libs/ardour/control_protocol.cc b/libs/ardour/control_protocol.cc index 1e4bd8efc9..b7004a0ffa 100644 --- a/libs/ardour/control_protocol.cc +++ b/libs/ardour/control_protocol.cc @@ -18,22 +18,11 @@ $Id$ */ -#include <unistd.h> -#include <fcntl.h> -#include <errno.h> -#include <poll.h> - -#include <pbd/pthread_utils.h> -#include <pbd/error.h> #include <ardour/control_protocol.h> -#include <ardour/configuration.h> -#include <ardour/session.h> using namespace ARDOUR; using namespace std; -#include "i18n.h" - sigc::signal<void> ControlProtocol::ZoomToSession; sigc::signal<void> ControlProtocol::ZoomOut; sigc::signal<void> ControlProtocol::ZoomIn; @@ -41,212 +30,13 @@ sigc::signal<void> ControlProtocol::Enter; sigc::signal<void,float> ControlProtocol::ScrollTimeline; ControlProtocol::ControlProtocol (Session& s, string str) - : session (s), + : BasicUI (s), _name (str) { - active_thread = 1; - thread_request_pipe[0] = -1; - thread_request_pipe[1] = -1; + _active = false; } ControlProtocol::~ControlProtocol () { - terminate_thread (); - - if (thread_request_pipe[0] >= 0) { - close (thread_request_pipe[0]); - close (thread_request_pipe[1]); - } -} - -void -ControlProtocol::set_send (SendWhat sw) -{ - _send = sw; -} - -int -ControlProtocol::init_thread () -{ - if (pipe (thread_request_pipe) != 0) { - error << string_compose (_("%1: cannot create thread request pipe (%1)"), _name, strerror (errno)) - << endmsg; - return -1; - } - - if (fcntl (thread_request_pipe[0], F_SETFL, O_NONBLOCK)) { - error << string_compose(_("%1: cannot set O_NONBLOCK on read pipe (%2)"), _name, strerror (errno)) << endmsg; - return -1; - } - - if (fcntl (thread_request_pipe[1], F_SETFL, O_NONBLOCK)) { - error << string_compose(_("%1: cannot set O_NONBLOCK on signal write pipe (%2)"), _name, strerror (errno)) << endmsg; - return -1; - } - - if (pthread_create_and_store ("tranzport delivery", &_thread, 0, _thread_work, this)) { - error << string_compose (_("%1: could not create thread"), _name) << endmsg; - return -1; - } - - return 0; -} - -int -ControlProtocol::poke_thread (ThreadRequest::Type why) -{ - char c = (char) why; - return !(write (thread_request_pipe[1], &c, 1) == 1); } -int -ControlProtocol::start_thread () -{ - return poke_thread (ThreadRequest::Start); -} - -int -ControlProtocol::stop_thread () -{ - return poke_thread (ThreadRequest::Stop); -} - -void -ControlProtocol::set_active (bool yn) -{ - if (yn != active_thread) { - - if (yn) { - /* make sure the feedback thread is alive */ - start_thread (); - } else { - /* maybe put the feedback thread to sleep */ - stop_thread (); - } - - ActiveChanged (); - } -} - -void -ControlProtocol::terminate_thread () -{ - void* status; - poke_thread (ThreadRequest::Quit); - pthread_join (_thread, &status); -} - -void* -ControlProtocol::_thread_work (void* arg) -{ - return static_cast<ControlProtocol*> (arg)->thread_work (); -} - -void* -ControlProtocol::thread_work () -{ - PBD::ThreadCreated (pthread_self(), _name); - - struct pollfd pfd[1]; - int timeout; - - struct sched_param rtparam; - int err; - - cerr << _name << " receiver thread running\n"; - - memset (&rtparam, 0, sizeof (rtparam)); - rtparam.sched_priority = 3; /* XXX should be relative to audio (JACK) thread */ - - if ((err = pthread_setschedparam (pthread_self(), SCHED_FIFO, &rtparam)) != 0) { - // do we care? not particularly. - info << string_compose (_("%1: delivery thread not running with realtime scheduling (%2)"), _name, strerror (errno)) << endmsg; - } - - pthread_setcancelstate (PTHREAD_CANCEL_ENABLE, 0); - pthread_setcanceltype (PTHREAD_CANCEL_ASYNCHRONOUS, 0); - - - if (active_thread) { - timeout = 10; // max (5, (int) Config->get_feedback_interval_ms()); - } else { - timeout = -1; - } - - while (1) { - - pfd[0].fd = thread_request_pipe[0]; - pfd[0].events = POLLIN|POLLHUP|POLLERR; - - if (poll (pfd, 1, timeout) < 0) { - if (errno == EINTR) { - continue; - } - error << string_compose (_("Protocol \"%1\" thread: poll failed (%2)"), _name, strerror (errno)) - << endmsg; - break; - } - - if (pfd[0].revents & ~POLLIN) { - error << string_compose (_("Error thread request pipe for protocol \"%1\""), _name) << endmsg; - break; - } - - if (pfd[0].revents & POLLIN) { - - char req; - - /* empty the pipe of all current requests */ - - while (1) { - size_t nread = read (thread_request_pipe[0], &req, sizeof (req)); - - if (nread == 1) { - switch ((ThreadRequest::Type) req) { - - case ThreadRequest::Start: - timeout = 10; // max (5, (int) Config->get_feedback_interval_ms()); - active_thread++; - break; - - case ThreadRequest::Stop: - timeout = -1; - if (active_thread) { - active_thread--; - } - break; - - case ThreadRequest::Quit: - pthread_exit_pbd (0); - /*NOTREACHED*/ - break; - - default: - break; - } - - } else if (nread == 0) { - break; - } else if (errno == EAGAIN) { - break; - } else { - fatal << string_compose (_("Error reading from thread request pipe for protocol \"%1\""), _name) << endmsg; - /*NOTREACHED*/ - } - } - } - - if (!active_thread) { - continue; - } - - if (send_route_feedback ()) { - list<Route*> routes = session.get_routes(); /* copies the routes */ - send_route_feedback (routes); - } - - send_global_feedback (); - } - - return 0; -} diff --git a/libs/ardour/control_protocol_manager.cc b/libs/ardour/control_protocol_manager.cc index 893124f0f5..ed33d0b6ee 100644 --- a/libs/ardour/control_protocol_manager.cc +++ b/libs/ardour/control_protocol_manager.cc @@ -15,6 +15,7 @@ using namespace std; #include "i18n.h" ControlProtocolManager* ControlProtocolManager::_instance = 0; +const string ControlProtocolManager::state_node_name = X_("ControlProtocols"); ControlProtocolManager::ControlProtocolManager () { @@ -42,6 +43,13 @@ ControlProtocolManager::set_session (Session& s) { _session = &s; _session->going_away.connect (mem_fun (*this, &ControlProtocolManager::drop_session)); + + for (list<ControlProtocolInfo*>::iterator i = control_protocol_info.begin(); i != control_protocol_info.end(); ++i) { + if ((*i)->requested) { + instantiate (**i); + (*i)->requested = false; + } + } } void @@ -122,6 +130,8 @@ ControlProtocolManager::discover_control_protocols (string path) vector<string *> *found; PathScanner scanner; + cerr << "looking for control protocols in " << path << endl; + found = scanner (path, protocol_filter, 0, false, true); for (vector<string*>::iterator i = found->begin(); i != found->end(); ++i) { @@ -145,9 +155,12 @@ ControlProtocolManager::control_protocol_discover (string path) info->name = descriptor->name; info->path = path; info->protocol = 0; + info->requested = false; control_protocol_info.push_back (info); + cerr << "discovered control surface protocol \"" << info->name << '"' << endl; + dlclose (descriptor->module); } @@ -195,3 +208,59 @@ ControlProtocolManager::foreach_known_protocol (sigc::slot<void,const ControlPro method (*i); } } + +ControlProtocolInfo* +ControlProtocolManager::cpi_by_name (string name) +{ + for (list<ControlProtocolInfo*>::iterator i = control_protocol_info.begin(); i != control_protocol_info.end(); ++i) { + if (name == (*i)->name) { + return *i; + } + } + return 0; +} + +int +ControlProtocolManager::set_state (const XMLNode& node) +{ + XMLNodeList clist; + XMLNodeConstIterator citer; + XMLProperty* prop; + + clist = node.children(); + + for (citer = clist.begin(); citer != clist.end(); ++citer) { + if ((*citer)->name() == X_("Protocol")) { + if ((prop = (*citer)->property (X_("active"))) != 0) { + if (prop->value() == X_("yes")) { + if ((prop = (*citer)->property (X_("name"))) != 0) { + ControlProtocolInfo* cpi = cpi_by_name (prop->value()); + if (cpi) { + if (_session) { + instantiate (*cpi); + } else { + cpi->requested = true; + } + } + } + } + } + } + } +} + +XMLNode& +ControlProtocolManager::get_state (void) +{ + XMLNode* root = new XMLNode (state_node_name); + LockMonitor lm (protocols_lock, __LINE__, __FILE__); + + for (list<ControlProtocolInfo*>::iterator i = control_protocol_info.begin(); i != control_protocol_info.end(); ++i) { + XMLNode* child = new XMLNode (X_("Protocol")); + child->add_property (X_("name"), (*i)->name); + child->add_property (X_("active"), (*i)->protocol ? "yes" : "no"); + root->add_child_nocopy (*child); + } + + return *root; +} diff --git a/libs/ardour/globals.cc b/libs/ardour/globals.cc index 5fca7f07eb..a6f9d6b2e5 100644 --- a/libs/ardour/globals.cc +++ b/libs/ardour/globals.cc @@ -269,6 +269,11 @@ ARDOUR::init (AudioEngine& engine, bool use_vst, bool try_optimization, void (*s /* singleton - first object is "it" */ new ControlProtocolManager (); ControlProtocolManager::instance().discover_control_protocols (Session::control_protocol_path()); + + XMLNode* node; + if ((node = Config->control_protocol_state()) != 0) { + ControlProtocolManager::instance().set_state (*node); + } BoundsChanged = Change (StartChanged|PositionChanged|LengthChanged); @@ -325,7 +330,7 @@ ARDOUR::get_user_ardour_path () } string -ARDOUR::get_system_ardour_path () +ARDOUR::get_system_data_path () { string path; @@ -335,6 +340,17 @@ ARDOUR::get_system_ardour_path () return path; } +string +ARDOUR::get_system_module_path () +{ + string path; + + path += MODULE_DIR; + path += "/ardour2/"; + + return path; +} + static string find_file (string name, string dir, string subdir = "") { diff --git a/libs/ardour/session_state.cc b/libs/ardour/session_state.cc index 6f1d20d17f..0cab0fd28d 100644 --- a/libs/ardour/session_state.cc +++ b/libs/ardour/session_state.cc @@ -2293,7 +2293,7 @@ Session::template_dir () } string -Session::suffixed_search_path (string suffix) +Session::suffixed_search_path (string suffix, bool data) { string path; @@ -2301,7 +2301,12 @@ Session::suffixed_search_path (string suffix) if (path[path.length()-1] != ':') { path += ':'; } - path += get_system_ardour_path(); + + if (data) { + path += get_system_data_path(); + } else { + path += get_system_module_path(); + } vector<string> split_path; @@ -2324,13 +2329,13 @@ Session::suffixed_search_path (string suffix) string Session::template_path () { - return suffixed_search_path (X_("templates")); + return suffixed_search_path (X_("templates"), true); } string Session::control_protocol_path () { - return suffixed_search_path (X_("surfaces")); + return suffixed_search_path (X_("surfaces"), false); } int diff --git a/libs/ardour/session_transport.cc b/libs/ardour/session_transport.cc index bf8b236600..6e756b28b7 100644 --- a/libs/ardour/session_transport.cc +++ b/libs/ardour/session_transport.cc @@ -946,17 +946,17 @@ Session::set_slave_source (SlaveSource src, jack_nframes_t frame) bool reverse = false; bool non_rt_required = false; + if (src == _slave_type) { + return 0; + } + if (_transport_speed) { error << _("please stop the transport before adjusting slave settings") << endmsg; /* help out non-MVC friendly UI's by telling them the slave type changed */ - ControlChanged (SlaveType); /* EMIT SIGNAL */ + ControlChanged (SlaveType); /* EMIT SIGNAL */ return 0; } - if (src == _slave_type) { - return 0; - } - // if (src == JACK && Config->get_jack_time_master()) { // return -1; // } |