2 Copyright (C) 2000 Paul Davis
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 2 of the License, or
7 (at your option) any later version.
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, write to the Free Software
16 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 #include "libardour-config.h"
27 #include <cstdio> // Needed so that libraptor (included in lrdf) won't complain
30 #include <sys/types.h>
32 #ifndef PLATFORM_WINDOWS
33 #include <sys/resource.h>
40 #ifdef PLATFORM_WINDOWS
41 #include <windows.h> // for LARGE_INTEGER
44 #ifdef WINDOWS_VST_SUPPORT
49 #include "ardour/linux_vst_support.h"
52 #ifdef AUDIOUNIT_SUPPORT
53 #include "ardour/audio_unit.h"
56 #if defined(__SSE__) || defined(USE_XMMINTRIN)
57 #include <xmmintrin.h>
61 #undef check /* stupid Apple and their un-namespaced, generic Carbon macros */
64 #include <glibmm/convert.h>
65 #include <glibmm/fileutils.h>
66 #include <glibmm/miscutils.h>
73 #include "pbd/error.h"
76 #include "pbd/strsplit.h"
78 #include "pbd/file_utils.h"
79 #include "pbd/enumwriter.h"
80 #include "pbd/basename.h"
82 #include "midi++/port.h"
83 #include "midi++/mmc.h"
85 #include "ardour/analyser.h"
86 #include "ardour/audio_library.h"
87 #include "ardour/audio_backend.h"
88 #include "ardour/audioengine.h"
89 #include "ardour/audioplaylist.h"
90 #include "ardour/audioregion.h"
91 #include "ardour/buffer_manager.h"
92 #include "ardour/control_protocol_manager.h"
93 #include "ardour/directory_names.h"
94 #include "ardour/event_type_map.h"
95 #include "ardour/filesystem_paths.h"
96 #include "ardour/midi_region.h"
97 #include "ardour/midiport_manager.h"
98 #include "ardour/mix.h"
99 #include "ardour/operations.h"
100 #include "ardour/panner_manager.h"
101 #include "ardour/plugin_manager.h"
102 #include "ardour/process_thread.h"
103 #include "ardour/profile.h"
104 #include "ardour/rc_configuration.h"
105 #include "ardour/region.h"
106 #include "ardour/route_group.h"
107 #include "ardour/runtime_functions.h"
108 #include "ardour/session_event.h"
109 #include "ardour/source_factory.h"
110 #include "ardour/uri_map.h"
112 #include "audiographer/routines.h"
114 #if defined (__APPLE__)
115 #include <Carbon/Carbon.h> // For Gestalt
120 ARDOUR::RCConfiguration* ARDOUR::Config = 0;
121 ARDOUR::RuntimeProfile* ARDOUR::Profile = 0;
122 ARDOUR::AudioLibrary* ARDOUR::Library = 0;
124 using namespace ARDOUR;
128 bool libardour_initialized = false;
130 compute_peak_t ARDOUR::compute_peak = 0;
131 find_peaks_t ARDOUR::find_peaks = 0;
132 apply_gain_to_buffer_t ARDOUR::apply_gain_to_buffer = 0;
133 mix_buffers_with_gain_t ARDOUR::mix_buffers_with_gain = 0;
134 mix_buffers_no_gain_t ARDOUR::mix_buffers_no_gain = 0;
135 copy_vector_t ARDOUR::copy_vector = 0;
137 PBD::Signal1<void,std::string> ARDOUR::BootMessage;
138 PBD::Signal3<void,std::string,std::string,bool> ARDOUR::PluginScanMessage;
139 PBD::Signal1<void,int> ARDOUR::PluginScanTimeout;
140 PBD::Signal0<void> ARDOUR::GUIIdle;
141 PBD::Signal3<bool,std::string,std::string,int> ARDOUR::CopyConfigurationFiles;
143 static bool have_old_configuration_files = false;
146 extern void setup_enum_writer ();
149 /* this is useful for quite a few things that want to check
150 if any bounds-related property has changed
152 PBD::PropertyChange ARDOUR::bounds_change;
155 setup_hardware_optimization (bool try_optimization)
157 bool generic_mix_functions = true;
159 if (try_optimization) {
163 #if defined (ARCH_X86) && defined (BUILD_SSE_OPTIMIZATIONS)
167 info << "Using AVX optimized routines" << endmsg;
170 compute_peak = x86_sse_avx_compute_peak;
171 find_peaks = x86_sse_avx_find_peaks;
172 apply_gain_to_buffer = x86_sse_avx_apply_gain_to_buffer;
173 mix_buffers_with_gain = x86_sse_avx_mix_buffers_with_gain;
174 mix_buffers_no_gain = x86_sse_avx_mix_buffers_no_gain;
175 copy_vector = x86_sse_avx_copy_vector;
177 generic_mix_functions = false;
179 } else if (fpu.has_sse()) {
181 info << "Using SSE optimized routines" << endmsg;
184 compute_peak = x86_sse_compute_peak;
185 find_peaks = x86_sse_find_peaks;
186 apply_gain_to_buffer = x86_sse_apply_gain_to_buffer;
187 mix_buffers_with_gain = x86_sse_mix_buffers_with_gain;
188 mix_buffers_no_gain = x86_sse_mix_buffers_no_gain;
189 copy_vector = default_copy_vector;
191 generic_mix_functions = false;
195 #elif defined (__APPLE__) && defined (BUILD_VECLIB_OPTIMIZATIONS)
196 SInt32 sysVersion = 0;
198 if (noErr != Gestalt(gestaltSystemVersion, &sysVersion))
201 if (sysVersion >= 0x00001040) { // Tiger at least
202 compute_peak = veclib_compute_peak;
203 find_peaks = veclib_find_peaks;
204 apply_gain_to_buffer = veclib_apply_gain_to_buffer;
205 mix_buffers_with_gain = veclib_mix_buffers_with_gain;
206 mix_buffers_no_gain = veclib_mix_buffers_no_gain;
207 copy_vector = default_copy_vector;
209 generic_mix_functions = false;
211 info << "Apple VecLib H/W specific optimizations in use" << endmsg;
215 /* consider FPU denormal handling to be "h/w optimization" */
220 if (generic_mix_functions) {
222 compute_peak = default_compute_peak;
223 find_peaks = default_find_peaks;
224 apply_gain_to_buffer = default_apply_gain_to_buffer;
225 mix_buffers_with_gain = default_mix_buffers_with_gain;
226 mix_buffers_no_gain = default_mix_buffers_no_gain;
227 copy_vector = default_copy_vector;
229 info << "No H/W specific optimizations in use" << endmsg;
232 AudioGrapher::Routines::override_compute_peak (compute_peak);
233 AudioGrapher::Routines::override_apply_gain_to_buffer (apply_gain_to_buffer);
237 lotsa_files_please ()
239 #ifndef PLATFORM_WINDOWS
242 if (getrlimit (RLIMIT_NOFILE, &rl) == 0) {
245 /* See the COMPATIBILITY note on the Apple setrlimit() man page */
246 rl.rlim_cur = min ((rlim_t) OPEN_MAX, rl.rlim_max);
248 rl.rlim_cur = rl.rlim_max;
251 if (setrlimit (RLIMIT_NOFILE, &rl) != 0) {
252 if (rl.rlim_cur == RLIM_INFINITY) {
253 error << _("Could not set system open files limit to \"unlimited\"") << endmsg;
255 error << string_compose (_("Could not set system open files limit to %1"), rl.rlim_cur) << endmsg;
258 if (rl.rlim_cur != RLIM_INFINITY) {
259 info << string_compose (_("Your system is configured to limit %1 to only %2 open files"), PROGRAM_NAME, rl.rlim_cur) << endmsg;
263 error << string_compose (_("Could not get system open files limit (%1)"), strerror (errno)) << endmsg;
269 copy_configuration_files (string const & old_dir, string const & new_dir, int old_version)
274 /* ensure target directory exists */
276 if (g_mkdir_with_parents (new_dir.c_str(), 0755)) {
280 if (old_version == 3) {
282 old_name = Glib::build_filename (old_dir, X_("recent"));
283 new_name = Glib::build_filename (new_dir, X_("recent"));
285 copy_file (old_name, new_name);
287 old_name = Glib::build_filename (old_dir, X_("sfdb"));
288 new_name = Glib::build_filename (new_dir, X_("sfdb"));
290 copy_file (old_name, new_name);
292 /* can only copy ardour.rc/config - UI config is not compatible */
294 /* users who have been using git/nightlies since the last
295 * release of 3.5 will have $CONFIG/config rather than
296 * $CONFIG/ardour.rc. Pick up the newer "old" config file,
297 * to avoid confusion.
300 string old_name = Glib::build_filename (old_dir, X_("config"));
302 if (!Glib::file_test (old_name, Glib::FILE_TEST_EXISTS)) {
303 old_name = Glib::build_filename (old_dir, X_("ardour.rc"));
306 new_name = Glib::build_filename (new_dir, X_("config"));
308 copy_file (old_name, new_name);
310 /* copy templates and route templates */
312 old_name = Glib::build_filename (old_dir, X_("templates"));
313 new_name = Glib::build_filename (new_dir, X_("templates"));
315 copy_recurse (old_name, new_name);
317 old_name = Glib::build_filename (old_dir, X_("route_templates"));
318 new_name = Glib::build_filename (new_dir, X_("route_templates"));
320 copy_recurse (old_name, new_name);
324 old_name = Glib::build_filename (old_dir, X_("presets"));
325 new_name = Glib::build_filename (new_dir, X_("presets"));
327 copy_recurse (old_name, new_name);
331 old_name = Glib::build_filename (old_dir, X_("plugin_statuses"));
332 new_name = Glib::build_filename (new_dir, X_("plugin_statuses"));
334 copy_file (old_name, new_name);
338 old_name = Glib::build_filename (old_dir, export_formats_dir_name);
339 new_name = Glib::build_filename (new_dir, export_formats_dir_name);
341 vector<string> export_formats;
342 g_mkdir_with_parents (Glib::build_filename (new_dir, export_formats_dir_name).c_str(), 0755);
343 find_files_matching_pattern (export_formats, old_name, X_("*.format"));
344 for (vector<string>::iterator i = export_formats.begin(); i != export_formats.end(); ++i) {
345 std::string from = *i;
346 std::string to = Glib::build_filename (new_name, Glib::path_get_basename (*i));
347 copy_file (from, to);
355 ARDOUR::check_for_old_configuration_files ()
357 int current_version = atoi (X_(PROGRAM_VERSION));
359 if (current_version <= 1) {
363 int old_version = current_version - 1;
365 string old_config_dir = user_config_directory (old_version);
366 /* pass in the current version explicitly to avoid creation */
367 string current_config_dir = user_config_directory (current_version);
369 if (!Glib::file_test (current_config_dir, Glib::FILE_TEST_IS_DIR)) {
370 if (Glib::file_test (old_config_dir, Glib::FILE_TEST_IS_DIR)) {
371 have_old_configuration_files = true;
377 ARDOUR::handle_old_configuration_files (boost::function<bool (std::string const&, std::string const&, int)> ui_handler)
379 if (have_old_configuration_files) {
380 int current_version = atoi (X_(PROGRAM_VERSION));
381 assert (current_version > 1); // established in check_for_old_configuration_files ()
382 int old_version = current_version - 1;
383 string old_config_dir = user_config_directory (old_version);
384 string current_config_dir = user_config_directory (current_version);
386 if (ui_handler (old_config_dir, current_config_dir, old_version)) {
387 copy_configuration_files (old_config_dir, current_config_dir, old_version);
395 ARDOUR::init (bool use_windows_vst, bool try_optimization, const char* localedir)
397 if (libardour_initialized) {
401 if (!PBD::init()) return false;
404 (void) bindtextdomain(PACKAGE, localedir);
405 (void) bind_textdomain_codeset (PACKAGE, "UTF-8");
408 SessionEvent::init_event_pool ();
410 Operations::make_operations_quarks ();
411 SessionObject::make_property_quarks ();
412 Region::make_property_quarks ();
413 MidiRegion::make_property_quarks ();
414 AudioRegion::make_property_quarks ();
415 RouteGroup::make_property_quarks ();
416 Playlist::make_property_quarks ();
417 AudioPlaylist::make_property_quarks ();
419 /* this is a useful ready to use PropertyChange that many
420 things need to check. This avoids having to compose
421 it every time we want to check for any of the relevant
425 bounds_change.add (ARDOUR::Properties::start);
426 bounds_change.add (ARDOUR::Properties::position);
427 bounds_change.add (ARDOUR::Properties::length);
429 /* provide a state version for the few cases that need it and are not
430 driven by reading state from disk (e.g. undo/redo)
433 Stateful::current_state_version = CURRENT_SESSION_FILE_VERSION;
435 ARDOUR::setup_enum_writer ();
437 // allow ardour the absolute maximum number of open files
438 lotsa_files_please ();
443 Library = new AudioLibrary;
445 BootMessage (_("Loading configuration"));
447 Config = new RCConfiguration;
449 if (Config->load_state ()) {
453 Config->set_use_windows_vst (use_windows_vst);
455 Config->set_use_lxvst(true);
458 Profile = new RuntimeProfile;
461 #ifdef WINDOWS_VST_SUPPORT
462 if (Config->get_use_windows_vst() && fst_init (0)) {
468 if (Config->get_use_lxvst() && vstfx_init (0)) {
473 #ifdef AUDIOUNIT_SUPPORT
474 AUPluginInfo::load_cached_info ();
477 setup_hardware_optimization (try_optimization);
479 SourceFactory::init ();
482 /* singletons - first object is "it" */
483 (void) PluginManager::instance();
485 (void) URIMap::instance();
487 (void) EventTypeMap::instance();
489 ProcessThread::init ();
490 /* the + 4 is a bit of a handwave. i don't actually know
491 how many more per-thread buffer sets we need above
492 the h/w concurrency, but its definitely > 1 more.
494 BufferManager::init (hardware_concurrency() + 4);
496 PannerManager::instance().discover_panners();
498 ARDOUR::AudioEngine::create ();
500 libardour_initialized = true;
506 ARDOUR::init_post_engine ()
508 ControlProtocolManager::instance().discover_control_protocols ();
511 if ((node = Config->control_protocol_state()) != 0) {
512 ControlProtocolManager::instance().set_state (*node, Stateful::loading_state_version);
517 ARDOUR::PluginManager::instance().refresh (!Config->get_discover_vst_on_start());
523 if (!libardour_initialized) {
527 ARDOUR::AudioEngine::destroy ();
533 delete &ControlProtocolManager::instance();
534 #ifdef WINDOWS_VST_SUPPORT
541 delete &PluginManager::instance();
549 ARDOUR::find_bindings_files (map<string,string>& files)
551 vector<std::string> found;
552 Searchpath spath = ardour_config_search_path();
554 if (getenv ("ARDOUR_SAE")) {
555 find_files_matching_pattern (found, spath, "*SAE-*.bindings");
557 find_files_matching_pattern (found, spath, "*.bindings");
564 for (vector<std::string>::iterator x = found.begin(); x != found.end(); ++x) {
565 std::string path(*x);
566 pair<string,string> namepath;
567 namepath.second = path;
568 namepath.first = PBD::basename_nosuffix (path);
569 files.insert (namepath);
574 ARDOUR::no_auto_connect()
576 return getenv ("ARDOUR_NO_AUTOCONNECT") != 0;
583 if (getenv ("ARDOUR_RUNNING_UNDER_VALGRIND")) {
584 // valgrind doesn't understand this assembler stuff
585 // September 10th, 2007
589 #if defined(ARCH_X86) && defined(USE_XMMINTRIN)
594 /* XXX use real code to determine if the processor supports
595 DenormalsAreZero and FlushToZero
598 if (!fpu.has_flush_to_zero() && !fpu.has_denormals_are_zero()) {
602 MXCSR = _mm_getcsr();
604 #ifdef DEBUG_DENORMAL_EXCEPTION
605 /* This will raise a FP exception if a denormal is detected */
606 MXCSR &= ~_MM_MASK_DENORM;
609 switch (Config->get_denormal_model()) {
611 MXCSR &= ~(_MM_FLUSH_ZERO_ON | 0x40);
615 if (fpu.has_flush_to_zero()) {
616 MXCSR |= _MM_FLUSH_ZERO_ON;
621 MXCSR &= ~_MM_FLUSH_ZERO_ON;
622 if (fpu.has_denormals_are_zero()) {
628 if (fpu.has_flush_to_zero()) {
629 if (fpu.has_denormals_are_zero()) {
630 MXCSR |= _MM_FLUSH_ZERO_ON | 0x40;
632 MXCSR |= _MM_FLUSH_ZERO_ON;
643 /* this can be changed to modify the translation behaviour for
644 cases where the user has never expressed a preference.
646 static const bool translate_by_default = true;
649 ARDOUR::translation_enable_path ()
651 return Glib::build_filename (user_config_directory(), ".translate");
655 ARDOUR::translations_are_enabled ()
657 int fd = ::open (Glib::locale_from_utf8 (ARDOUR::translation_enable_path()).c_str(), O_RDONLY);
660 return translate_by_default;
666 if (::read (fd, &c, 1) == 1 && c == '1') {
676 ARDOUR::set_translations_enabled (bool yn)
678 string i18n_enabler = ARDOUR::translation_enable_path();
679 int fd = ::open (Glib::locale_from_utf8 (i18n_enabler).c_str(), O_WRONLY|O_CREAT|O_TRUNC, 0644);
693 (void) ::write (fd, &c, 1);
701 ARDOUR::get_available_sync_options ()
703 vector<SyncSource> ret;
705 boost::shared_ptr<AudioBackend> backend = AudioEngine::instance()->current_backend();
706 if (backend && backend->name() == "JACK") {
707 ret.push_back (Engine);
711 ret.push_back (MIDIClock);
717 /** Return a monotonic value for the number of microseconds that have elapsed
718 * since an arbitrary zero origin.
722 /* Thanks Apple for not implementing this basic SUSv2, POSIX.1-2001 function
724 #include <mach/mach_time.h>
725 #define CLOCK_REALTIME 0
726 #define CLOCK_MONOTONIC 0
728 clock_gettime (int /*clk_id*/, struct timespec *t)
730 static bool initialized = false;
731 static mach_timebase_info_data_t timebase;
733 mach_timebase_info(&timebase);
737 time = mach_absolute_time();
738 double nseconds = ((double)time * (double)timebase.numer)/((double)timebase.denom);
739 double seconds = ((double)time * (double)timebase.numer)/((double)timebase.denom * 1e9);
741 t->tv_nsec = nseconds;
747 ARDOUR::get_microseconds ()
749 #ifdef PLATFORM_WINDOWS
750 microseconds_t ret = 0;
751 LARGE_INTEGER freq, time;
753 if (QueryPerformanceFrequency(&freq))
754 if (QueryPerformanceCounter(&time))
755 ret = (microseconds_t)((time.QuadPart * 1000000) / freq.QuadPart);
760 if (clock_gettime (CLOCK_MONOTONIC, &ts) != 0) {
764 return (microseconds_t) ts.tv_sec * 1000000 + (ts.tv_nsec/1000);
768 /** Return the number of bits per sample for a given sample format.
770 * This is closely related to sndfile_data_width() but does NOT
771 * return a "magic" value to differentiate between 32 bit integer
772 * and 32 bit floating point values.
776 ARDOUR::format_data_width (ARDOUR::SampleFormat format)
782 case ARDOUR::FormatInt16:
784 case ARDOUR::FormatInt24: