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>
41 #include <glib/gstdio.h>
43 #ifdef PLATFORM_WINDOWS
44 #include <windows.h> // for LARGE_INTEGER
47 #ifdef WINDOWS_VST_SUPPORT
52 #include "ardour/linux_vst_support.h"
55 #ifdef AUDIOUNIT_SUPPORT
56 #include "ardour/audio_unit.h"
59 #if defined(__SSE__) || defined(USE_XMMINTRIN)
60 #include <xmmintrin.h>
64 #undef check /* stupid Apple and their un-namespaced, generic Carbon macros */
67 #include <glibmm/fileutils.h>
68 #include <glibmm/miscutils.h>
75 #include "pbd/error.h"
78 #include "pbd/strsplit.h"
80 #include "pbd/file_utils.h"
81 #include "pbd/enumwriter.h"
82 #include "pbd/basename.h"
84 #include "midi++/port.h"
85 #include "midi++/mmc.h"
87 #include "ardour/analyser.h"
88 #include "ardour/audio_library.h"
89 #include "ardour/audio_backend.h"
90 #include "ardour/audioengine.h"
91 #include "ardour/audioplaylist.h"
92 #include "ardour/audioregion.h"
93 #include "ardour/buffer_manager.h"
94 #include "ardour/control_protocol_manager.h"
95 #include "ardour/directory_names.h"
96 #include "ardour/event_type_map.h"
97 #include "ardour/filesystem_paths.h"
98 #include "ardour/midi_region.h"
99 #include "ardour/midiport_manager.h"
100 #include "ardour/mix.h"
101 #include "ardour/operations.h"
102 #include "ardour/panner_manager.h"
103 #include "ardour/plugin_manager.h"
104 #include "ardour/process_thread.h"
105 #include "ardour/profile.h"
106 #include "ardour/rc_configuration.h"
107 #include "ardour/region.h"
108 #include "ardour/route_group.h"
109 #include "ardour/runtime_functions.h"
110 #include "ardour/session_event.h"
111 #include "ardour/source_factory.h"
112 #include "ardour/uri_map.h"
114 #include "audiographer/routines.h"
116 #if defined (__APPLE__)
117 #include <Carbon/Carbon.h> // For Gestalt
122 ARDOUR::RCConfiguration* ARDOUR::Config = 0;
123 ARDOUR::RuntimeProfile* ARDOUR::Profile = 0;
124 ARDOUR::AudioLibrary* ARDOUR::Library = 0;
126 using namespace ARDOUR;
130 bool libardour_initialized = false;
132 compute_peak_t ARDOUR::compute_peak = 0;
133 find_peaks_t ARDOUR::find_peaks = 0;
134 apply_gain_to_buffer_t ARDOUR::apply_gain_to_buffer = 0;
135 mix_buffers_with_gain_t ARDOUR::mix_buffers_with_gain = 0;
136 mix_buffers_no_gain_t ARDOUR::mix_buffers_no_gain = 0;
137 copy_vector_t ARDOUR::copy_vector = 0;
139 PBD::Signal1<void,std::string> ARDOUR::BootMessage;
140 PBD::Signal3<void,std::string,std::string,bool> ARDOUR::PluginScanMessage;
141 PBD::Signal1<void,int> ARDOUR::PluginScanTimeout;
142 PBD::Signal0<void> ARDOUR::GUIIdle;
143 PBD::Signal3<bool,std::string,std::string,int> ARDOUR::CopyConfigurationFiles;
145 static bool have_old_configuration_files = false;
148 extern void setup_enum_writer ();
151 /* this is useful for quite a few things that want to check
152 if any bounds-related property has changed
154 PBD::PropertyChange ARDOUR::bounds_change;
157 setup_hardware_optimization (bool try_optimization)
159 bool generic_mix_functions = true;
161 if (try_optimization) {
165 #if defined (ARCH_X86) && defined (BUILD_SSE_OPTIMIZATIONS)
167 #if 0 /* AVX code doesn't compile on Linux yet, don't use generic code instead */
171 info << "Using AVX optimized routines" << endmsg;
174 compute_peak = x86_sse_avx_compute_peak;
175 find_peaks = x86_sse_avx_find_peaks;
176 apply_gain_to_buffer = x86_sse_avx_apply_gain_to_buffer;
177 mix_buffers_with_gain = x86_sse_avx_mix_buffers_with_gain;
178 mix_buffers_no_gain = x86_sse_avx_mix_buffers_no_gain;
179 copy_vector = x86_sse_avx_copy_vector;
181 generic_mix_functions = false;
187 info << "Using SSE optimized routines" << endmsg;
190 compute_peak = x86_sse_compute_peak;
191 find_peaks = x86_sse_find_peaks;
192 apply_gain_to_buffer = x86_sse_apply_gain_to_buffer;
193 mix_buffers_with_gain = x86_sse_mix_buffers_with_gain;
194 mix_buffers_no_gain = x86_sse_mix_buffers_no_gain;
195 copy_vector = default_copy_vector;
197 generic_mix_functions = false;
201 #elif defined (__APPLE__) && defined (BUILD_VECLIB_OPTIMIZATIONS)
202 SInt32 sysVersion = 0;
204 if (noErr != Gestalt(gestaltSystemVersion, &sysVersion))
207 if (sysVersion >= 0x00001040) { // Tiger at least
208 compute_peak = veclib_compute_peak;
209 find_peaks = veclib_find_peaks;
210 apply_gain_to_buffer = veclib_apply_gain_to_buffer;
211 mix_buffers_with_gain = veclib_mix_buffers_with_gain;
212 mix_buffers_no_gain = veclib_mix_buffers_no_gain;
213 copy_vector = default_copy_vector;
215 generic_mix_functions = false;
217 info << "Apple VecLib H/W specific optimizations in use" << endmsg;
221 /* consider FPU denormal handling to be "h/w optimization" */
226 if (generic_mix_functions) {
228 compute_peak = default_compute_peak;
229 find_peaks = default_find_peaks;
230 apply_gain_to_buffer = default_apply_gain_to_buffer;
231 mix_buffers_with_gain = default_mix_buffers_with_gain;
232 mix_buffers_no_gain = default_mix_buffers_no_gain;
233 copy_vector = default_copy_vector;
235 info << "No H/W specific optimizations in use" << endmsg;
238 AudioGrapher::Routines::override_compute_peak (compute_peak);
239 AudioGrapher::Routines::override_apply_gain_to_buffer (apply_gain_to_buffer);
243 lotsa_files_please ()
245 #ifndef PLATFORM_WINDOWS
248 if (getrlimit (RLIMIT_NOFILE, &rl) == 0) {
251 /* See the COMPATIBILITY note on the Apple setrlimit() man page */
252 rl.rlim_cur = min ((rlim_t) OPEN_MAX, rl.rlim_max);
254 rl.rlim_cur = rl.rlim_max;
257 if (setrlimit (RLIMIT_NOFILE, &rl) != 0) {
258 if (rl.rlim_cur == RLIM_INFINITY) {
259 error << _("Could not set system open files limit to \"unlimited\"") << endmsg;
261 error << string_compose (_("Could not set system open files limit to %1"), rl.rlim_cur) << endmsg;
264 if (rl.rlim_cur != RLIM_INFINITY) {
265 info << string_compose (_("Your system is configured to limit %1 to only %2 open files"), PROGRAM_NAME, rl.rlim_cur) << endmsg;
269 error << string_compose (_("Could not get system open files limit (%1)"), strerror (errno)) << endmsg;
275 copy_configuration_files (string const & old_dir, string const & new_dir, int old_version)
280 /* ensure target directory exists */
282 if (g_mkdir_with_parents (new_dir.c_str(), 0755)) {
286 if (old_version == 3) {
288 old_name = Glib::build_filename (old_dir, X_("recent"));
289 new_name = Glib::build_filename (new_dir, X_("recent"));
291 copy_file (old_name, new_name);
293 old_name = Glib::build_filename (old_dir, X_("sfdb"));
294 new_name = Glib::build_filename (new_dir, X_("sfdb"));
296 copy_file (old_name, new_name);
298 /* can only copy ardour.rc/config - UI config is not compatible */
300 /* users who have been using git/nightlies since the last
301 * release of 3.5 will have $CONFIG/config rather than
302 * $CONFIG/ardour.rc. Pick up the newer "old" config file,
303 * to avoid confusion.
306 string old_name = Glib::build_filename (old_dir, X_("config"));
308 if (!Glib::file_test (old_name, Glib::FILE_TEST_EXISTS)) {
309 old_name = Glib::build_filename (old_dir, X_("ardour.rc"));
312 new_name = Glib::build_filename (new_dir, X_("config"));
314 copy_file (old_name, new_name);
316 /* copy templates and route templates */
318 old_name = Glib::build_filename (old_dir, X_("templates"));
319 new_name = Glib::build_filename (new_dir, X_("templates"));
321 copy_recurse (old_name, new_name);
323 old_name = Glib::build_filename (old_dir, X_("route_templates"));
324 new_name = Glib::build_filename (new_dir, X_("route_templates"));
326 copy_recurse (old_name, new_name);
330 old_name = Glib::build_filename (old_dir, X_("presets"));
331 new_name = Glib::build_filename (new_dir, X_("presets"));
333 copy_recurse (old_name, new_name);
337 old_name = Glib::build_filename (old_dir, X_("plugin_statuses"));
338 new_name = Glib::build_filename (new_dir, X_("plugin_statuses"));
340 copy_file (old_name, new_name);
344 old_name = Glib::build_filename (old_dir, export_formats_dir_name);
345 new_name = Glib::build_filename (new_dir, export_formats_dir_name);
347 vector<string> export_formats;
348 g_mkdir_with_parents (Glib::build_filename (new_dir, export_formats_dir_name).c_str(), 0755);
349 find_files_matching_pattern (export_formats, old_name, X_("*.format"));
350 for (vector<string>::iterator i = export_formats.begin(); i != export_formats.end(); ++i) {
351 std::string from = *i;
352 std::string to = Glib::build_filename (new_name, Glib::path_get_basename (*i));
353 copy_file (from, to);
361 ARDOUR::check_for_old_configuration_files ()
363 int current_version = atoi (X_(PROGRAM_VERSION));
365 if (current_version <= 1) {
369 int old_version = current_version - 1;
371 string old_config_dir = user_config_directory (old_version);
372 /* pass in the current version explicitly to avoid creation */
373 string current_config_dir = user_config_directory (current_version);
375 if (!Glib::file_test (current_config_dir, Glib::FILE_TEST_IS_DIR)) {
376 if (Glib::file_test (old_config_dir, Glib::FILE_TEST_IS_DIR)) {
377 have_old_configuration_files = true;
383 ARDOUR::handle_old_configuration_files (boost::function<bool (std::string const&, std::string const&, int)> ui_handler)
385 if (have_old_configuration_files) {
386 int current_version = atoi (X_(PROGRAM_VERSION));
387 assert (current_version > 1); // established in check_for_old_configuration_files ()
388 int old_version = current_version - 1;
389 string old_config_dir = user_config_directory (old_version);
390 string current_config_dir = user_config_directory (current_version);
392 if (ui_handler (old_config_dir, current_config_dir, old_version)) {
393 copy_configuration_files (old_config_dir, current_config_dir, old_version);
401 ARDOUR::init (bool use_windows_vst, bool try_optimization, const char* localedir)
403 if (libardour_initialized) {
407 if (!PBD::init()) return false;
410 (void) bindtextdomain(PACKAGE, localedir);
411 (void) bind_textdomain_codeset (PACKAGE, "UTF-8");
414 SessionEvent::init_event_pool ();
416 Operations::make_operations_quarks ();
417 SessionObject::make_property_quarks ();
418 Region::make_property_quarks ();
419 MidiRegion::make_property_quarks ();
420 AudioRegion::make_property_quarks ();
421 RouteGroup::make_property_quarks ();
422 Playlist::make_property_quarks ();
423 AudioPlaylist::make_property_quarks ();
425 /* this is a useful ready to use PropertyChange that many
426 things need to check. This avoids having to compose
427 it every time we want to check for any of the relevant
431 bounds_change.add (ARDOUR::Properties::start);
432 bounds_change.add (ARDOUR::Properties::position);
433 bounds_change.add (ARDOUR::Properties::length);
435 /* provide a state version for the few cases that need it and are not
436 driven by reading state from disk (e.g. undo/redo)
439 Stateful::current_state_version = CURRENT_SESSION_FILE_VERSION;
441 ARDOUR::setup_enum_writer ();
443 // allow ardour the absolute maximum number of open files
444 lotsa_files_please ();
449 Library = new AudioLibrary;
451 BootMessage (_("Loading configuration"));
453 Config = new RCConfiguration;
455 if (Config->load_state ()) {
459 Config->set_use_windows_vst (use_windows_vst);
461 Config->set_use_lxvst(true);
464 Profile = new RuntimeProfile;
467 #ifdef WINDOWS_VST_SUPPORT
468 if (Config->get_use_windows_vst() && fst_init (0)) {
474 if (Config->get_use_lxvst() && vstfx_init (0)) {
479 #ifdef AUDIOUNIT_SUPPORT
480 AUPluginInfo::load_cached_info ();
483 setup_hardware_optimization (try_optimization);
485 SourceFactory::init ();
488 /* singletons - first object is "it" */
489 (void) PluginManager::instance();
491 (void) URIMap::instance();
493 (void) EventTypeMap::instance();
495 ProcessThread::init ();
496 /* the + 4 is a bit of a handwave. i don't actually know
497 how many more per-thread buffer sets we need above
498 the h/w concurrency, but its definitely > 1 more.
500 BufferManager::init (hardware_concurrency() + 4);
502 PannerManager::instance().discover_panners();
504 ARDOUR::AudioEngine::create ();
506 libardour_initialized = true;
512 ARDOUR::init_post_engine ()
514 ControlProtocolManager::instance().discover_control_protocols ();
517 if ((node = Config->control_protocol_state()) != 0) {
518 ControlProtocolManager::instance().set_state (*node, Stateful::loading_state_version);
523 ARDOUR::PluginManager::instance().refresh (!Config->get_discover_vst_on_start());
529 if (!libardour_initialized) {
533 ARDOUR::AudioEngine::destroy ();
539 delete &ControlProtocolManager::instance();
540 #ifdef WINDOWS_VST_SUPPORT
547 delete &PluginManager::instance();
555 ARDOUR::find_bindings_files (map<string,string>& files)
557 vector<std::string> found;
558 Searchpath spath = ardour_config_search_path();
560 if (getenv ("ARDOUR_SAE")) {
561 find_files_matching_pattern (found, spath, "*SAE-*.bindings");
563 find_files_matching_pattern (found, spath, "*.bindings");
570 for (vector<std::string>::iterator x = found.begin(); x != found.end(); ++x) {
571 std::string path(*x);
572 pair<string,string> namepath;
573 namepath.second = path;
574 namepath.first = PBD::basename_nosuffix (path);
575 files.insert (namepath);
580 ARDOUR::no_auto_connect()
582 return getenv ("ARDOUR_NO_AUTOCONNECT") != 0;
589 if (getenv ("ARDOUR_RUNNING_UNDER_VALGRIND")) {
590 // valgrind doesn't understand this assembler stuff
591 // September 10th, 2007
595 #if defined(ARCH_X86) && defined(USE_XMMINTRIN)
600 /* XXX use real code to determine if the processor supports
601 DenormalsAreZero and FlushToZero
604 if (!fpu.has_flush_to_zero() && !fpu.has_denormals_are_zero()) {
608 MXCSR = _mm_getcsr();
610 #ifdef DEBUG_DENORMAL_EXCEPTION
611 /* This will raise a FP exception if a denormal is detected */
612 MXCSR &= ~_MM_MASK_DENORM;
615 switch (Config->get_denormal_model()) {
617 MXCSR &= ~(_MM_FLUSH_ZERO_ON | 0x40);
621 if (fpu.has_flush_to_zero()) {
622 MXCSR |= _MM_FLUSH_ZERO_ON;
627 MXCSR &= ~_MM_FLUSH_ZERO_ON;
628 if (fpu.has_denormals_are_zero()) {
634 if (fpu.has_flush_to_zero()) {
635 if (fpu.has_denormals_are_zero()) {
636 MXCSR |= _MM_FLUSH_ZERO_ON | 0x40;
638 MXCSR |= _MM_FLUSH_ZERO_ON;
649 /* this can be changed to modify the translation behaviour for
650 cases where the user has never expressed a preference.
652 static const bool translate_by_default = true;
655 ARDOUR::translation_enable_path ()
657 return Glib::build_filename (user_config_directory(), ".translate");
661 ARDOUR::translations_are_enabled ()
663 int fd = g_open (ARDOUR::translation_enable_path().c_str(), O_RDONLY, 0444);
666 return translate_by_default;
672 if (::read (fd, &c, 1) == 1 && c == '1') {
682 ARDOUR::set_translations_enabled (bool yn)
684 string i18n_enabler = ARDOUR::translation_enable_path();
685 int fd = g_open (i18n_enabler.c_str(), O_WRONLY|O_CREAT|O_TRUNC, 0644);
699 (void) ::write (fd, &c, 1);
707 ARDOUR::get_available_sync_options ()
709 vector<SyncSource> ret;
711 boost::shared_ptr<AudioBackend> backend = AudioEngine::instance()->current_backend();
712 if (backend && backend->name() == "JACK") {
713 ret.push_back (Engine);
717 ret.push_back (MIDIClock);
723 /** Return a monotonic value for the number of microseconds that have elapsed
724 * since an arbitrary zero origin.
728 /* Thanks Apple for not implementing this basic SUSv2, POSIX.1-2001 function
730 #include <mach/mach_time.h>
731 #define CLOCK_REALTIME 0
732 #define CLOCK_MONOTONIC 0
734 clock_gettime (int /*clk_id*/, struct timespec *t)
736 static bool initialized = false;
737 static mach_timebase_info_data_t timebase;
739 mach_timebase_info(&timebase);
743 time = mach_absolute_time();
744 double nseconds = ((double)time * (double)timebase.numer)/((double)timebase.denom);
745 double seconds = ((double)time * (double)timebase.numer)/((double)timebase.denom * 1e9);
747 t->tv_nsec = nseconds;
753 ARDOUR::get_microseconds ()
755 #ifdef PLATFORM_WINDOWS
756 microseconds_t ret = 0;
757 LARGE_INTEGER freq, time;
759 if (QueryPerformanceFrequency(&freq))
760 if (QueryPerformanceCounter(&time))
761 ret = (microseconds_t)((time.QuadPart * 1000000) / freq.QuadPart);
766 if (clock_gettime (CLOCK_MONOTONIC, &ts) != 0) {
770 return (microseconds_t) ts.tv_sec * 1000000 + (ts.tv_nsec/1000);
774 /** Return the number of bits per sample for a given sample format.
776 * This is closely related to sndfile_data_width() but does NOT
777 * return a "magic" value to differentiate between 32 bit integer
778 * and 32 bit floating point values.
782 ARDOUR::format_data_width (ARDOUR::SampleFormat format)
788 case ARDOUR::FormatInt16:
790 case ARDOUR::FormatInt24: