X-Git-Url: https://main.carlh.net/gitweb/?a=blobdiff_plain;f=libs%2Fardour%2Fglobals.cc;h=e42c0d5ca9fc26b5b67ff8c20c801f76365c1433;hb=2f91bdfa5390bdf992ab7044488b5afb21716661;hp=4951161a72f91681cbfb869d6c5f6318e0a85f9b;hpb=3a69ff680e190bb9377e4bc13e65cb3981c64c60;p=ardour.git diff --git a/libs/ardour/globals.cc b/libs/ardour/globals.cc index 4951161a72..e42c0d5ca9 100644 --- a/libs/ardour/globals.cc +++ b/libs/ardour/globals.cc @@ -38,9 +38,10 @@ #include #include -#include +#include "pbd/gstdio_compat.h" #ifdef PLATFORM_WINDOWS +#include // for _setmaxstdio #include // for LARGE_INTEGER #endif @@ -62,7 +63,7 @@ #ifdef check #undef check /* stupid Apple and their un-namespaced, generic Carbon macros */ -#endif +#endif #include #include @@ -79,11 +80,12 @@ #include "pbd/fpu.h" #include "pbd/file_utils.h" #include "pbd/enumwriter.h" -#include "pbd/basename.h" #include "midi++/port.h" #include "midi++/mmc.h" +#include "LuaBridge/LuaBridge.h" + #include "ardour/analyser.h" #include "ardour/audio_library.h" #include "ardour/audio_backend.h" @@ -96,11 +98,13 @@ #include "ardour/event_type_map.h" #include "ardour/filesystem_paths.h" #include "ardour/midi_region.h" +#include "ardour/midi_ui.h" #include "ardour/midiport_manager.h" #include "ardour/mix.h" #include "ardour/operations.h" #include "ardour/panner_manager.h" #include "ardour/plugin_manager.h" +#include "ardour/presentation_info.h" #include "ardour/process_thread.h" #include "ardour/profile.h" #include "ardour/rc_configuration.h" @@ -109,15 +113,17 @@ #include "ardour/runtime_functions.h" #include "ardour/session_event.h" #include "ardour/source_factory.h" +#include "ardour/transport_master_manager.h" +#ifdef LV2_SUPPORT #include "ardour/uri_map.h" - +#endif #include "audiographer/routines.h" #if defined (__APPLE__) - #include // For Gestalt +#include #endif -#include "i18n.h" +#include "pbd/i18n.h" ARDOUR::RCConfiguration* ARDOUR::Config = 0; ARDOUR::RuntimeProfile* ARDOUR::Profile = 0; @@ -134,7 +140,7 @@ find_peaks_t ARDOUR::find_peaks = 0; apply_gain_to_buffer_t ARDOUR::apply_gain_to_buffer = 0; mix_buffers_with_gain_t ARDOUR::mix_buffers_with_gain = 0; mix_buffers_no_gain_t ARDOUR::mix_buffers_no_gain = 0; -copy_vector_t ARDOUR::copy_vector = 0; +copy_vector_t ARDOUR::copy_vector = 0; PBD::Signal1 ARDOUR::BootMessage; PBD::Signal3 ARDOUR::PluginScanMessage; @@ -142,6 +148,8 @@ PBD::Signal1 ARDOUR::PluginScanTimeout; PBD::Signal0 ARDOUR::GUIIdle; PBD::Signal3 ARDOUR::CopyConfigurationFiles; +std::map ARDOUR::reserved_io_names; + static bool have_old_configuration_files = false; namespace ARDOUR { @@ -153,6 +161,8 @@ extern void setup_enum_writer (); */ PBD::PropertyChange ARDOUR::bounds_change; +static PBD::ScopedConnection engine_startup_connection; + void setup_hardware_optimization (bool try_optimization) { @@ -164,10 +174,15 @@ setup_hardware_optimization (bool try_optimization) #if defined (ARCH_X86) && defined (BUILD_SSE_OPTIMIZATIONS) -#if 0 /* AVX code doesn't compile on Linux yet, don't use generic code instead */ - +#ifdef PLATFORM_WINDOWS + /* We have AVX-optimized code for Windows */ + if (fpu->has_avx()) { - +#else + /* AVX code doesn't compile on Linux yet */ + + if (false) { +#endif info << "Using AVX optimized routines" << endmsg; // AVX SET @@ -180,9 +195,7 @@ setup_hardware_optimization (bool try_optimization) generic_mix_functions = false; - } else -#endif - if (fpu->has_sse()) { + } else if (fpu->has_sse()) { info << "Using SSE optimized routines" << endmsg; @@ -199,12 +212,8 @@ setup_hardware_optimization (bool try_optimization) } #elif defined (__APPLE__) && defined (BUILD_VECLIB_OPTIMIZATIONS) - SInt32 sysVersion = 0; - - if (noErr != Gestalt(gestaltSystemVersion, &sysVersion)) - sysVersion = 0; - if (sysVersion >= 0x00001040) { // Tiger at least + if (floor (kCFCoreFoundationVersionNumber) > kCFCoreFoundationVersionNumber10_4) { /* at least Tiger */ compute_peak = veclib_compute_peak; find_peaks = veclib_find_peaks; apply_gain_to_buffer = veclib_apply_gain_to_buffer; @@ -262,12 +271,27 @@ lotsa_files_please () } } else { if (rl.rlim_cur != RLIM_INFINITY) { - info << string_compose (_("Your system is configured to limit %1 to only %2 open files"), PROGRAM_NAME, rl.rlim_cur) << endmsg; + info << string_compose (_("Your system is configured to limit %1 to %2 open files"), PROGRAM_NAME, rl.rlim_cur) << endmsg; } } } else { error << string_compose (_("Could not get system open files limit (%1)"), strerror (errno)) << endmsg; } +#else + /* this only affects stdio. 2048 is the maxium possible (512 the default). + * + * If we want more, we'll have to replaces the POSIX I/O interfaces with + * Win32 API calls (CreateFile, WriteFile, etc) which allows for 16K. + * + * see http://stackoverflow.com/questions/870173/is-there-a-limit-on-number-of-open-files-in-windows + * and http://bugs.mysql.com/bug.php?id=24509 + */ + int newmax = _setmaxstdio (2048); + if (newmax > 0) { + info << string_compose (_("Your system is configured to limit %1 to %2 open files"), PROGRAM_NAME, newmax) << endmsg; + } else { + error << string_compose (_("Could not set system open files limit. Current limit is %1 open files"), _getmaxstdio()) << endmsg; + } #endif } @@ -282,9 +306,9 @@ copy_configuration_files (string const & old_dir, string const & new_dir, int ol if (g_mkdir_with_parents (new_dir.c_str(), 0755)) { return -1; } - - if (old_version == 3) { - + + if (old_version >= 3) { + old_name = Glib::build_filename (old_dir, X_("recent")); new_name = Glib::build_filename (new_dir, X_("recent")); @@ -302,7 +326,7 @@ copy_configuration_files (string const & old_dir, string const & new_dir, int ol * $CONFIG/ardour.rc. Pick up the newer "old" config file, * to avoid confusion. */ - + string old_name = Glib::build_filename (old_dir, X_("config")); if (!Glib::file_test (old_name, Glib::FILE_TEST_EXISTS)) { @@ -329,21 +353,31 @@ copy_configuration_files (string const & old_dir, string const & new_dir, int ol old_name = Glib::build_filename (old_dir, X_("presets")); new_name = Glib::build_filename (new_dir, X_("presets")); - + copy_recurse (old_name, new_name); - /* presets */ + /* plugin status */ + g_mkdir_with_parents (Glib::build_filename (new_dir, plugin_metadata_dir_name).c_str(), 0755); - old_name = Glib::build_filename (old_dir, X_("plugin_statuses")); - new_name = Glib::build_filename (new_dir, X_("plugin_statuses")); + old_name = Glib::build_filename (old_dir, X_("plugin_statuses")); /* until 6.0 */ + new_name = Glib::build_filename (new_dir, plugin_metadata_dir_name, X_("plugin_statuses")); + copy_file (old_name, new_name); /* can fail silently */ + old_name = Glib::build_filename (old_dir, plugin_metadata_dir_name, X_("plugin_statuses")); copy_file (old_name, new_name); - + + /* plugin tags */ + + old_name = Glib::build_filename (old_dir, plugin_metadata_dir_name, X_("plugin_tags")); + new_name = Glib::build_filename (new_dir, plugin_metadata_dir_name, X_("plugin_tags")); + + copy_file (old_name, new_name); + /* export formats */ old_name = Glib::build_filename (old_dir, export_formats_dir_name); new_name = Glib::build_filename (new_dir, export_formats_dir_name); - + vector export_formats; g_mkdir_with_parents (Glib::build_filename (new_dir, export_formats_dir_name).c_str(), 0755); find_files_matching_pattern (export_formats, old_name, X_("*.format")); @@ -361,7 +395,7 @@ void ARDOUR::check_for_old_configuration_files () { int current_version = atoi (X_(PROGRAM_VERSION)); - + if (current_version <= 1) { return; } @@ -404,9 +438,15 @@ ARDOUR::init (bool use_windows_vst, bool try_optimization, const char* localedir return true; } +#ifndef NDEBUG + if (getenv("LUA_METATABLES")) { + luabridge::Security::setHideMetatables (false); + } +#endif + if (!PBD::init()) return false; -#ifdef ENABLE_NLS +#if ENABLE_NLS (void) bindtextdomain(PACKAGE, localedir); (void) bind_textdomain_codeset (PACKAGE, "UTF-8"); #endif @@ -421,6 +461,8 @@ ARDOUR::init (bool use_windows_vst, bool try_optimization, const char* localedir RouteGroup::make_property_quarks (); Playlist::make_property_quarks (); AudioPlaylist::make_property_quarks (); + PresentationInfo::make_property_quarks (); + TransportMaster::make_property_quarks (); /* this is a useful ready to use PropertyChange that many things need to check. This avoids having to compose @@ -492,51 +534,105 @@ ARDOUR::init (bool use_windows_vst, bool try_optimization, const char* localedir #endif (void) EventTypeMap::instance(); + ControlProtocolManager::instance().discover_control_protocols (); + + /* for each control protocol, check for a request buffer factory method + and if it exists, store it in the EventLoop list of such + methods. This allows the relevant threads to register themselves + with EventLoops so that signal emission can be RT-safe. + */ + + ControlProtocolManager::instance().register_request_buffer_factories (); + /* it would be nice if this could auto-register itself in the + constructor, since MidiControlUI is a singleton, but it can't be + created until after the engine is running. Therefore we have to + explicitly register it here. + */ + EventLoop::register_request_buffer_factory (X_("midiUI"), MidiControlUI::request_factory); + ProcessThread::init (); /* the + 4 is a bit of a handwave. i don't actually know how many more per-thread buffer sets we need above the h/w concurrency, but its definitely > 1 more. */ - BufferManager::init (hardware_concurrency() + 4); + BufferManager::init (hardware_concurrency() + 4); PannerManager::instance().discover_panners(); ARDOUR::AudioEngine::create (); + /* it is unfortunate that we need to include reserved names here that + refer to control surfaces. But there's no way to ensure a complete + lack of collisions without doing this, since the control surface + support may not even be active. Without adding an API to control + surface support that would list their port names, we do have to + list them here. + + We also need to know if the given I/O is an actual route. + For routes (e.g. "master"), bus creation needs to be allowed the first time, + while for pure I/O (e.g. "Click") track/bus creation must always fail. + */ + + reserved_io_names[_("Monitor")] = true; + reserved_io_names[_("Master")] = true; + reserved_io_names["auditioner"] = true; // auditioner.cc Track (s, "auditioner",...) + + /* pure I/O */ + reserved_io_names[X_("Click")] = false; // session.cc ClickIO (*this, X_("Click") + reserved_io_names[_("Control")] = false; + reserved_io_names[_("Mackie")] = false; + reserved_io_names[_("FaderPort Recv")] = false; + reserved_io_names[_("FaderPort Send")] = false; + reserved_io_names[_("FaderPort2 Recv")] = false; + reserved_io_names[_("FaderPort2 Send")] = false; + reserved_io_names[_("FaderPort8 Recv")] = false; + reserved_io_names[_("FaderPort8 Send")] = false; + reserved_io_names[_("FaderPort16 Recv")] = false; + reserved_io_names[_("FaderPort16 Send")] = false; + libardour_initialized = true; return true; } void -ARDOUR::init_post_engine () +ARDOUR::init_post_engine (uint32_t start_cnt) { - ControlProtocolManager::instance().discover_control_protocols (); - XMLNode* node; - if ((node = Config->control_protocol_state()) != 0) { - ControlProtocolManager::instance().set_state (*node, Stateful::loading_state_version); + + if (start_cnt == 0) { + + /* find plugins */ + + ARDOUR::PluginManager::instance().refresh (!Config->get_discover_vst_on_start()); } - /* find plugins */ + if (start_cnt == 0) { - ARDOUR::PluginManager::instance().refresh (!Config->get_discover_vst_on_start()); + if ((node = Config->control_protocol_state()) != 0) { + ControlProtocolManager::instance().set_state (*node, 0 /* here: global-config state */); + } + + TransportMasterManager::instance().restart (); + } } void -ARDOUR::cleanup () +ARDOUR::cleanup () { if (!libardour_initialized) { return; } + engine_startup_connection.disconnect (); + + delete &ControlProtocolManager::instance(); ARDOUR::AudioEngine::destroy (); delete Library; #ifdef HAVE_LRDF lrdf_cleanup (); #endif - delete &ControlProtocolManager::instance(); #ifdef WINDOWS_VST_SUPPORT fst_exit (); #endif @@ -551,31 +647,6 @@ ARDOUR::cleanup () return; } -void -ARDOUR::find_bindings_files (map& files) -{ - vector found; - Searchpath spath = ardour_config_search_path(); - - if (getenv ("ARDOUR_SAE")) { - find_files_matching_pattern (found, spath, "*SAE-*.bindings"); - } else { - find_files_matching_pattern (found, spath, "*.bindings"); - } - - if (found.empty()) { - return; - } - - for (vector::iterator x = found.begin(); x != found.end(); ++x) { - std::string path(*x); - pair namepath; - namepath.second = path; - namepath.first = PBD::basename_nosuffix (path); - files.insert (namepath); - } -} - bool ARDOUR::no_auto_connect() { @@ -586,7 +657,7 @@ void ARDOUR::setup_fpu () { FPU* fpu = FPU::instance (); - + if (getenv ("ARDOUR_RUNNING_UNDER_VALGRIND")) { // valgrind doesn't understand this assembler stuff // September 10th, 2007 @@ -606,7 +677,7 @@ ARDOUR::setup_fpu () #ifdef DEBUG_DENORMAL_EXCEPTION /* This will raise a FP exception if a denormal is detected */ MXCSR &= ~_MM_MASK_DENORM; -#endif +#endif switch (Config->get_denormal_model()) { case DenormalNone: @@ -683,18 +754,19 @@ ARDOUR::set_translations_enabled (bool yn) if (fd < 0) { return false; } - + char c; - + if (yn) { c = '1'; } else { c = '0'; } - + (void) ::write (fd, &c, 1); (void) ::close (fd); + Config->ParameterChanged ("enable-translation"); return true; } @@ -726,7 +798,7 @@ ARDOUR::get_available_sync_options () #include #define CLOCK_REALTIME 0 #define CLOCK_MONOTONIC 0 -int +int clock_gettime (int /*clk_id*/, struct timespec *t) { static bool initialized = false; @@ -744,7 +816,7 @@ clock_gettime (int /*clk_id*/, struct timespec *t) return 0; } #endif - + microseconds_t ARDOUR::get_microseconds () {