summaryrefslogtreecommitdiff
path: root/libs
diff options
context:
space:
mode:
Diffstat (limited to 'libs')
-rw-r--r--libs/ardour/ardour/audioengine.h3
-rw-r--r--libs/ardour/ardour/route.h1
-rw-r--r--libs/ardour/ardour/session.h3
-rw-r--r--libs/ardour/audioengine.cc52
-rw-r--r--libs/ardour/gettext.h2
-rw-r--r--libs/ardour/ladspa_plugin.cc1
-rw-r--r--libs/ardour/playlist.cc48
-rw-r--r--libs/ardour/route.cc20
-rw-r--r--libs/ardour/session.cc18
-rw-r--r--libs/ardour/session_state.cc6
-rw-r--r--libs/ardour/session_transport.cc5
-rw-r--r--libs/ardour/wscript8
-rw-r--r--libs/gtkmm2ext/gettext.h2
-rw-r--r--libs/gtkmm2ext/gtk_ui.cc2
-rw-r--r--libs/gtkmm2ext/gtkmm2ext/gtk_ui.h2
-rw-r--r--libs/gtkmm2ext/keyboard.cc3
16 files changed, 149 insertions, 27 deletions
diff --git a/libs/ardour/ardour/audioengine.h b/libs/ardour/ardour/audioengine.h
index 63f9afeb2b..5e2657c56c 100644
--- a/libs/ardour/ardour/audioengine.h
+++ b/libs/ardour/ardour/audioengine.h
@@ -224,7 +224,7 @@ _ the regular process() call to session->process() is not made.
/* this signal is sent if JACK ever disconnects us */
- PBD::Signal0<void> Halted;
+ PBD::Signal1<void,const char*> Halted;
/* these two are emitted when the engine itself is
started and stopped
@@ -306,6 +306,7 @@ _ the regular process() call to session->process() is not made.
int connect_to_jack (std::string client_name, std::string session_uuid);
static void halted (void *);
+ static void halted_info (jack_status_t,const char*,void *);
void meter_thread ();
void start_metering_thread ();
diff --git a/libs/ardour/ardour/route.h b/libs/ardour/ardour/route.h
index e5a1a4a145..ae514e2f18 100644
--- a/libs/ardour/ardour/route.h
+++ b/libs/ardour/ardour/route.h
@@ -188,6 +188,7 @@ class Route : public SessionObject, public AutomatableControls, public RouteGrou
bool processor_is_prefader (boost::shared_ptr<Processor> p);
+ bool has_io_processor_named (const std::string&);
ChanCount max_processor_streams () const { return processor_max_streams; }
/* special processors */
diff --git a/libs/ardour/ardour/session.h b/libs/ardour/ardour/session.h
index 81536169a6..ed1dc68f43 100644
--- a/libs/ardour/ardour/session.h
+++ b/libs/ardour/ardour/session.h
@@ -240,6 +240,7 @@ class Session : public PBD::StatefulDestructible, public PBD::ScopedConnectionLi
template<class T> void foreach_route (T *obj, void (T::*func)(boost::shared_ptr<Route>));
template<class T, class A> void foreach_route (T *obj, void (T::*func)(Route&, A), A arg);
+ bool io_name_is_legal (const std::string&);
boost::shared_ptr<Route> route_by_name (std::string);
boost::shared_ptr<Route> route_by_id (PBD::ID);
boost::shared_ptr<Route> route_by_remote_id (uint32_t id);
@@ -356,7 +357,7 @@ class Session : public PBD::StatefulDestructible, public PBD::ScopedConnectionLi
#ifdef HAVE_JACK_SESSION
void jack_session_event (jack_session_event_t* event);
#endif
- int save_state (std::string snapshot_name, bool pending = false);
+ int save_state (std::string snapshot_name, bool pending = false, bool switch_to_snapshot = false);
int restore_state (std::string snapshot_name);
int save_template (std::string template_name);
int save_history (std::string snapshot_name = "");
diff --git a/libs/ardour/audioengine.cc b/libs/ardour/audioengine.cc
index 47704224cb..a16f268edd 100644
--- a/libs/ardour/audioengine.cc
+++ b/libs/ardour/audioengine.cc
@@ -145,6 +145,19 @@ _thread_init_callback (void * /*arg*/)
MIDI::JACK_MidiPort::set_process_thread (pthread_self());
}
+typedef void (*_JackInfoShutdownCallback)(jack_status_t code, const char* reason, void *arg);
+
+static void (*on_info_shutdown)(jack_client_t*, _JackInfoShutdownCallback, void *);
+extern void jack_on_info_shutdown (jack_client_t*, _JackInfoShutdownCallback, void *) __attribute__((weak));
+
+static void check_jack_symbols () __attribute__((constructor));
+
+void check_jack_symbols ()
+{
+ /* use weak linking to see if we really have various late-model JACK function */
+ on_info_shutdown = jack_on_info_shutdown;
+}
+
static void
ardour_jack_error (const char* msg)
{
@@ -183,7 +196,11 @@ AudioEngine::start ()
_processed_frames = 0;
last_monitor_check = 0;
- jack_on_shutdown (_priv_jack, halted, this);
+ if (on_info_shutdown) {
+ jack_on_info_shutdown (_priv_jack, halted_info, this);
+ } else {
+ jack_on_shutdown (_priv_jack, halted, this);
+ }
jack_set_graph_order_callback (_priv_jack, _graph_order_callback, this);
jack_set_thread_init_callback (_priv_jack, _thread_init_callback, this);
// jack_set_process_callback (_priv_jack, _process_callback, this);
@@ -969,6 +986,36 @@ AudioEngine::get_ports (const string& port_name_pattern, const string& type_name
}
void
+AudioEngine::halted_info (jack_status_t code, const char* reason, void *arg)
+{
+ /* called from jack shutdown handler */
+
+ AudioEngine* ae = static_cast<AudioEngine *> (arg);
+ bool was_running = ae->_running;
+
+ ae->stop_metering_thread ();
+
+ ae->_running = false;
+ ae->_buffer_size = 0;
+ ae->_frame_rate = 0;
+ ae->_jack = 0;
+
+ if (was_running) {
+#ifdef HAVE_JACK_ON_INFO_SHUTDOWN
+ switch (code) {
+ case JackBackendError:
+ ae->Halted(reason); /* EMIT SIGNAL */
+ break;
+ default:
+ ae->Halted(""); /* EMIT SIGNAL */
+ }
+#else
+ ae->Halted(""); /* EMIT SIGNAL */
+#endif
+ }
+}
+
+void
AudioEngine::halted (void *arg)
{
cerr << "HALTED by JACK\n";
@@ -983,9 +1030,10 @@ AudioEngine::halted (void *arg)
ae->_running = false;
ae->_buffer_size = 0;
ae->_frame_rate = 0;
+ ae->_jack = 0;
if (was_running) {
- ae->Halted(); /* EMIT SIGNAL */
+ ae->Halted(""); /* EMIT SIGNAL */
MIDI::JACK_MidiPort::JackHalted (); /* EMIT SIGNAL */
}
}
diff --git a/libs/ardour/gettext.h b/libs/ardour/gettext.h
index 339c74ffe7..2645402e95 100644
--- a/libs/ardour/gettext.h
+++ b/libs/ardour/gettext.h
@@ -20,7 +20,7 @@
#define _LIBGETTEXT_H 1
/* NLS can be disabled through the configure --disable-nls option. */
-#if ENABLE_NLS
+#ifdef ENABLE_NLS
/* Get declarations of GNU message catalog functions. */
# include <libintl.h>
diff --git a/libs/ardour/ladspa_plugin.cc b/libs/ardour/ladspa_plugin.cc
index 81cdff9618..d9a1ad074b 100644
--- a/libs/ardour/ladspa_plugin.cc
+++ b/libs/ardour/ladspa_plugin.cc
@@ -691,6 +691,7 @@ LadspaPluginInfo::load (Session& session)
if ((module = dlopen (path.c_str(), RTLD_NOW)) == 0) {
error << string_compose(_("LADSPA: cannot load module from \"%1\""), path) << endmsg;
error << dlerror() << endmsg;
+ return PluginPtr ((Plugin*) 0);
} else {
plugin.reset (new LadspaPlugin (module, session.engine(), session, index, session.frame_rate()));
}
diff --git a/libs/ardour/playlist.cc b/libs/ardour/playlist.cc
index 57f49a68d5..6fc7fdc2cf 100644
--- a/libs/ardour/playlist.cc
+++ b/libs/ardour/playlist.cc
@@ -1004,7 +1004,7 @@ Playlist::partition_internal (framepos_t start, framepos_t end, bool cutting, Re
current->suspend_property_changes ();
thawlist.push_back (current);
- current->cut_end (pos2, this);
+ current->cut_end (pos2 - 1, this);
} else if (overlap == OverlapEnd) {
@@ -1043,7 +1043,7 @@ Playlist::partition_internal (framepos_t start, framepos_t end, bool cutting, Re
current->suspend_property_changes ();
thawlist.push_back (current);
- current->cut_end (pos2, this);
+ current->cut_end (pos2 - 1, this);
} else if (overlap == OverlapStart) {
@@ -2490,22 +2490,48 @@ void
Playlist::raise_region_to_top (boost::shared_ptr<Region> region)
{
/* does nothing useful if layering mode is later=higher */
- if ((_session.config.get_layer_model() == MoveAddHigher) ||
- (_session.config.get_layer_model() == AddHigher)) {
- timestamp_layer_op (region);
- relayer ();
+ switch (_session.config.get_layer_model()) {
+ case LaterHigher:
+ return;
+ default:
+ break;
}
+
+ layer_t top = regions.size() - 1;
+
+ if (region->layer() >= top) {
+ /* already on the top */
+ return;
+ }
+
+ move_region_to_layer (top, region, 1);
+ /* mark the region's last_layer_op as now, so that it remains on top when
+ doing future relayers (until something else takes over)
+ */
+ timestamp_layer_op (region);
}
void
Playlist::lower_region_to_bottom (boost::shared_ptr<Region> region)
{
/* does nothing useful if layering mode is later=higher */
- if ((_session.config.get_layer_model() == MoveAddHigher) ||
- (_session.config.get_layer_model() == AddHigher)) {
- region->set_last_layer_op (0);
- relayer ();
+ switch (_session.config.get_layer_model()) {
+ case LaterHigher:
+ return;
+ default:
+ break;
+ }
+
+ if (region->layer() == 0) {
+ /* already on the bottom */
+ return;
}
+
+ move_region_to_layer (0, region, -1);
+ /* force region's last layer op to zero so that it stays at the bottom
+ when doing future relayers
+ */
+ region->set_last_layer_op (0);
}
int
@@ -2688,8 +2714,6 @@ Playlist::set_frozen (bool yn)
void
Playlist::timestamp_layer_op (boost::shared_ptr<Region> region)
{
-// struct timeval tv;
-// gettimeofday (&tv, 0);
region->set_last_layer_op (++layer_op_counter);
}
diff --git a/libs/ardour/route.cc b/libs/ardour/route.cc
index a29dab5365..01242cd80e 100644
--- a/libs/ardour/route.cc
+++ b/libs/ardour/route.cc
@@ -269,7 +269,7 @@ Route::ensure_track_or_route_name(string name, Session &session)
{
string newname = name;
- while (session.route_by_name (newname) != NULL) {
+ while (!session.io_name_is_legal (newname)) {
newname = bump_name_once (newname);
}
@@ -3252,3 +3252,21 @@ Route::nth_send (uint32_t n)
return boost::shared_ptr<Processor> ();
}
+
+bool
+Route::has_io_processor_named (const string& name)
+{
+ Glib::RWLock::ReaderLock lm (_processor_lock);
+ ProcessorList::iterator i;
+
+ for (i = _processors.begin(); i != _processors.end(); ++i) {
+ if (boost::dynamic_pointer_cast<Send> (*i) ||
+ boost::dynamic_pointer_cast<PortInsert> (*i)) {
+ if ((*i)->name() == name) {
+ return true;
+ }
+ }
+ }
+
+ return false;
+}
diff --git a/libs/ardour/session.cc b/libs/ardour/session.cc
index 90e5809890..7f316c953a 100644
--- a/libs/ardour/session.cc
+++ b/libs/ardour/session.cc
@@ -2304,6 +2304,24 @@ Session::get_routes_with_internal_returns() const
return rl;
}
+bool
+Session::io_name_is_legal (const std::string& name)
+{
+ shared_ptr<RouteList> r = routes.reader ();
+
+ for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
+ if ((*i)->name() == name) {
+ return false;
+ }
+
+ if ((*i)->has_io_processor_named (name)) {
+ return false;
+ }
+ }
+
+ return true;
+}
+
shared_ptr<Route>
Session::route_by_name (string name)
{
diff --git a/libs/ardour/session_state.cc b/libs/ardour/session_state.cc
index d32f61774d..9f1adcfe99 100644
--- a/libs/ardour/session_state.cc
+++ b/libs/ardour/session_state.cc
@@ -748,7 +748,7 @@ Session::jack_session_event (jack_session_event_t * event)
#endif
int
-Session::save_state (string snapshot_name, bool pending)
+Session::save_state (string snapshot_name, bool pending, bool switch_to_snapshot)
{
XMLTree tree;
sys::path xml_path(_session_dir->root_path());
@@ -773,7 +773,9 @@ Session::save_state (string snapshot_name, bool pending)
if (snapshot_name.empty()) {
snapshot_name = _current_snapshot_name;
- }
+ } else if (switch_to_snapshot) {
+ _current_snapshot_name = snapshot_name;
+ }
if (!pending) {
diff --git a/libs/ardour/session_transport.cc b/libs/ardour/session_transport.cc
index 686ca4ce73..c5e6795325 100644
--- a/libs/ardour/session_transport.cc
+++ b/libs/ardour/session_transport.cc
@@ -230,8 +230,9 @@ Session::realtime_stop (bool abort, bool clear_state)
_clear_event_type (SessionEvent::RangeStop);
_clear_event_type (SessionEvent::RangeLocate);
- disable_record (true);
-
+ /* if we're going to clear loop state, then force disabling record BUT only if we're not doing latched rec-enable */
+ disable_record (true, (!Config->get_latched_record_enable() && clear_state));
+
reset_slave_state ();
_transport_speed = 0;
diff --git a/libs/ardour/wscript b/libs/ardour/wscript
index 32127b6f7f..1aceb24e56 100644
--- a/libs/ardour/wscript
+++ b/libs/ardour/wscript
@@ -244,7 +244,13 @@ def configure(conf):
conf.check(header_name='wordexp.h', define_name='HAVE_WORDEXP')
conf.check(header_name='jack/session.h', define_name='HAVE_JACK_SESSION')
-
+
+ conf.check_cc(fragment = "#include <jack/jack.h>\nvoid callback (int code, const char* reason, void* arg) { return; }\nint main(int argc, char **argv) { jack_client_t* c; jack_on_info_shutdown (c, callback, (void*) 0); return 0; }\n",
+ linkflags = ['-ljack'],
+ msg = 'Checking for jack_on_info_shutdown',
+ define_name = 'HAVE_JACK_ON_INFO_SHUTDOWN',
+ okmsg = 'ok')
+
if flac_supported():
conf.define ('HAVE_FLAC', 1)
autowaf.display_msg(conf, 'Checking for FLAC support', True)
diff --git a/libs/gtkmm2ext/gettext.h b/libs/gtkmm2ext/gettext.h
index 339c74ffe7..2645402e95 100644
--- a/libs/gtkmm2ext/gettext.h
+++ b/libs/gtkmm2ext/gettext.h
@@ -20,7 +20,7 @@
#define _LIBGETTEXT_H 1
/* NLS can be disabled through the configure --disable-nls option. */
-#if ENABLE_NLS
+#ifdef ENABLE_NLS
/* Get declarations of GNU message catalog functions. */
# include <libintl.h>
diff --git a/libs/gtkmm2ext/gtk_ui.cc b/libs/gtkmm2ext/gtk_ui.cc
index 7695892a82..cfcc0df91a 100644
--- a/libs/gtkmm2ext/gtk_ui.cc
+++ b/libs/gtkmm2ext/gtk_ui.cc
@@ -602,7 +602,7 @@ UI::handle_fatal (const char *message)
}
void
-UI::popup_error (const char *text)
+UI::popup_error (const string& text)
{
PopUp *pup;
diff --git a/libs/gtkmm2ext/gtkmm2ext/gtk_ui.h b/libs/gtkmm2ext/gtkmm2ext/gtk_ui.h
index 2484b1e620..a0ea1e86ad 100644
--- a/libs/gtkmm2ext/gtkmm2ext/gtk_ui.h
+++ b/libs/gtkmm2ext/gtkmm2ext/gtk_ui.h
@@ -109,7 +109,7 @@ class UI : public Receiver, public AbstractUI<UIRequest>
void run (Receiver &old_receiver);
void set_state (Gtk::Widget *w, Gtk::StateType state);
- void popup_error (const char *text);
+ void popup_error (const std::string& text);
void flush_pending ();
void toggle_errors ();
void touch_display (Touchable *);
diff --git a/libs/gtkmm2ext/keyboard.cc b/libs/gtkmm2ext/keyboard.cc
index da51d4e412..8c13e2e18b 100644
--- a/libs/gtkmm2ext/keyboard.cc
+++ b/libs/gtkmm2ext/keyboard.cc
@@ -81,7 +81,7 @@ std::string Keyboard::user_keybindings_path;
bool Keyboard::can_save_keybindings = false;
bool Keyboard::bindings_changed_after_save_became_legal = false;
map<string,string> Keyboard::binding_files;
-string Keyboard::_current_binding_name = _("Unknown");
+string Keyboard::_current_binding_name;
map<AccelKey,pair<string,string>,Keyboard::AccelKeyLess> Keyboard::release_keys;
/* set this to initially contain the modifiers we care about, then track changes in ::set_edit_modifier() etc. */
@@ -110,6 +110,7 @@ Keyboard::Keyboard ()
{
if (_the_keyboard == 0) {
_the_keyboard = this;
+ _current_binding_name = _("Unknown");
}
RelevantModifierKeyMask = (GdkModifierType) gtk_accelerator_get_default_mod_mask ();