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)
169 info << "Using AVX optimized routines" << endmsg;
172 compute_peak = x86_sse_avx_compute_peak;
173 find_peaks = x86_sse_avx_find_peaks;
174 apply_gain_to_buffer = x86_sse_avx_apply_gain_to_buffer;
175 mix_buffers_with_gain = x86_sse_avx_mix_buffers_with_gain;
176 mix_buffers_no_gain = x86_sse_avx_mix_buffers_no_gain;
177 copy_vector = x86_sse_avx_copy_vector;
179 generic_mix_functions = false;
181 } else if (fpu.has_sse()) {
183 info << "Using SSE optimized routines" << endmsg;
186 compute_peak = x86_sse_compute_peak;
187 find_peaks = x86_sse_find_peaks;
188 apply_gain_to_buffer = x86_sse_apply_gain_to_buffer;
189 mix_buffers_with_gain = x86_sse_mix_buffers_with_gain;
190 mix_buffers_no_gain = x86_sse_mix_buffers_no_gain;
191 copy_vector = default_copy_vector;
193 generic_mix_functions = false;
197 #elif defined (__APPLE__) && defined (BUILD_VECLIB_OPTIMIZATIONS)
198 SInt32 sysVersion = 0;
200 if (noErr != Gestalt(gestaltSystemVersion, &sysVersion))
203 if (sysVersion >= 0x00001040) { // Tiger at least
204 compute_peak = veclib_compute_peak;
205 find_peaks = veclib_find_peaks;
206 apply_gain_to_buffer = veclib_apply_gain_to_buffer;
207 mix_buffers_with_gain = veclib_mix_buffers_with_gain;
208 mix_buffers_no_gain = veclib_mix_buffers_no_gain;
209 copy_vector = default_copy_vector;
211 generic_mix_functions = false;
213 info << "Apple VecLib H/W specific optimizations in use" << endmsg;
217 /* consider FPU denormal handling to be "h/w optimization" */
222 if (generic_mix_functions) {
224 compute_peak = default_compute_peak;
225 find_peaks = default_find_peaks;
226 apply_gain_to_buffer = default_apply_gain_to_buffer;
227 mix_buffers_with_gain = default_mix_buffers_with_gain;
228 mix_buffers_no_gain = default_mix_buffers_no_gain;
229 copy_vector = default_copy_vector;
231 info << "No H/W specific optimizations in use" << endmsg;
234 AudioGrapher::Routines::override_compute_peak (compute_peak);
235 AudioGrapher::Routines::override_apply_gain_to_buffer (apply_gain_to_buffer);
239 lotsa_files_please ()
241 #ifndef PLATFORM_WINDOWS
244 if (getrlimit (RLIMIT_NOFILE, &rl) == 0) {
247 /* See the COMPATIBILITY note on the Apple setrlimit() man page */
248 rl.rlim_cur = min ((rlim_t) OPEN_MAX, rl.rlim_max);
250 rl.rlim_cur = rl.rlim_max;
253 if (setrlimit (RLIMIT_NOFILE, &rl) != 0) {
254 if (rl.rlim_cur == RLIM_INFINITY) {
255 error << _("Could not set system open files limit to \"unlimited\"") << endmsg;
257 error << string_compose (_("Could not set system open files limit to %1"), rl.rlim_cur) << endmsg;
260 if (rl.rlim_cur != RLIM_INFINITY) {
261 info << string_compose (_("Your system is configured to limit %1 to only %2 open files"), PROGRAM_NAME, rl.rlim_cur) << endmsg;
265 error << string_compose (_("Could not get system open files limit (%1)"), strerror (errno)) << endmsg;
271 copy_configuration_files (string const & old_dir, string const & new_dir, int old_version)
276 /* ensure target directory exists */
278 if (g_mkdir_with_parents (new_dir.c_str(), 0755)) {
282 if (old_version == 3) {
284 old_name = Glib::build_filename (old_dir, X_("recent"));
285 new_name = Glib::build_filename (new_dir, X_("recent"));
287 copy_file (old_name, new_name);
289 old_name = Glib::build_filename (old_dir, X_("sfdb"));
290 new_name = Glib::build_filename (new_dir, X_("sfdb"));
292 copy_file (old_name, new_name);
294 /* can only copy ardour.rc/config - UI config is not compatible */
296 /* users who have been using git/nightlies since the last
297 * release of 3.5 will have $CONFIG/config rather than
298 * $CONFIG/ardour.rc. Pick up the newer "old" config file,
299 * to avoid confusion.
302 string old_name = Glib::build_filename (old_dir, X_("config"));
304 if (!Glib::file_test (old_name, Glib::FILE_TEST_EXISTS)) {
305 old_name = Glib::build_filename (old_dir, X_("ardour.rc"));
308 new_name = Glib::build_filename (new_dir, X_("config"));
310 copy_file (old_name, new_name);
312 /* copy templates and route templates */
314 old_name = Glib::build_filename (old_dir, X_("templates"));
315 new_name = Glib::build_filename (new_dir, X_("templates"));
317 copy_recurse (old_name, new_name);
319 old_name = Glib::build_filename (old_dir, X_("route_templates"));
320 new_name = Glib::build_filename (new_dir, X_("route_templates"));
322 copy_recurse (old_name, new_name);
326 old_name = Glib::build_filename (old_dir, X_("presets"));
327 new_name = Glib::build_filename (new_dir, X_("presets"));
329 copy_recurse (old_name, new_name);
333 old_name = Glib::build_filename (old_dir, X_("plugin_statuses"));
334 new_name = Glib::build_filename (new_dir, X_("plugin_statuses"));
336 copy_file (old_name, new_name);
340 old_name = Glib::build_filename (old_dir, export_formats_dir_name);
341 new_name = Glib::build_filename (new_dir, export_formats_dir_name);
343 vector<string> export_formats;
344 g_mkdir_with_parents (Glib::build_filename (new_dir, export_formats_dir_name).c_str(), 0755);
345 find_files_matching_pattern (export_formats, old_name, X_("*.format"));
346 for (vector<string>::iterator i = export_formats.begin(); i != export_formats.end(); ++i) {
347 std::string from = *i;
348 std::string to = Glib::build_filename (new_name, Glib::path_get_basename (*i));
349 copy_file (from, to);
357 ARDOUR::check_for_old_configuration_files ()
359 int current_version = atoi (X_(PROGRAM_VERSION));
361 if (current_version <= 1) {
365 int old_version = current_version - 1;
367 string old_config_dir = user_config_directory (old_version);
368 /* pass in the current version explicitly to avoid creation */
369 string current_config_dir = user_config_directory (current_version);
371 if (!Glib::file_test (current_config_dir, Glib::FILE_TEST_IS_DIR)) {
372 if (Glib::file_test (old_config_dir, Glib::FILE_TEST_IS_DIR)) {
373 have_old_configuration_files = true;
379 ARDOUR::handle_old_configuration_files (boost::function<bool (std::string const&, std::string const&, int)> ui_handler)
381 if (have_old_configuration_files) {
382 int current_version = atoi (X_(PROGRAM_VERSION));
383 assert (current_version > 1); // established in check_for_old_configuration_files ()
384 int old_version = current_version - 1;
385 string old_config_dir = user_config_directory (old_version);
386 string current_config_dir = user_config_directory (current_version);
388 if (ui_handler (old_config_dir, current_config_dir, old_version)) {
389 copy_configuration_files (old_config_dir, current_config_dir, old_version);
397 ARDOUR::init (bool use_windows_vst, bool try_optimization, const char* localedir)
399 if (libardour_initialized) {
403 if (!PBD::init()) return false;
406 (void) bindtextdomain(PACKAGE, localedir);
407 (void) bind_textdomain_codeset (PACKAGE, "UTF-8");
410 SessionEvent::init_event_pool ();
412 Operations::make_operations_quarks ();
413 SessionObject::make_property_quarks ();
414 Region::make_property_quarks ();
415 MidiRegion::make_property_quarks ();
416 AudioRegion::make_property_quarks ();
417 RouteGroup::make_property_quarks ();
418 Playlist::make_property_quarks ();
419 AudioPlaylist::make_property_quarks ();
421 /* this is a useful ready to use PropertyChange that many
422 things need to check. This avoids having to compose
423 it every time we want to check for any of the relevant
427 bounds_change.add (ARDOUR::Properties::start);
428 bounds_change.add (ARDOUR::Properties::position);
429 bounds_change.add (ARDOUR::Properties::length);
431 /* provide a state version for the few cases that need it and are not
432 driven by reading state from disk (e.g. undo/redo)
435 Stateful::current_state_version = CURRENT_SESSION_FILE_VERSION;
437 ARDOUR::setup_enum_writer ();
439 // allow ardour the absolute maximum number of open files
440 lotsa_files_please ();
445 Library = new AudioLibrary;
447 BootMessage (_("Loading configuration"));
449 Config = new RCConfiguration;
451 if (Config->load_state ()) {
455 Config->set_use_windows_vst (use_windows_vst);
457 Config->set_use_lxvst(true);
460 Profile = new RuntimeProfile;
463 #ifdef WINDOWS_VST_SUPPORT
464 if (Config->get_use_windows_vst() && fst_init (0)) {
470 if (Config->get_use_lxvst() && vstfx_init (0)) {
475 #ifdef AUDIOUNIT_SUPPORT
476 AUPluginInfo::load_cached_info ();
479 setup_hardware_optimization (try_optimization);
481 SourceFactory::init ();
484 /* singletons - first object is "it" */
485 (void) PluginManager::instance();
487 (void) URIMap::instance();
489 (void) EventTypeMap::instance();
491 ProcessThread::init ();
492 /* the + 4 is a bit of a handwave. i don't actually know
493 how many more per-thread buffer sets we need above
494 the h/w concurrency, but its definitely > 1 more.
496 BufferManager::init (hardware_concurrency() + 4);
498 PannerManager::instance().discover_panners();
500 ARDOUR::AudioEngine::create ();
502 libardour_initialized = true;
508 ARDOUR::init_post_engine ()
510 ControlProtocolManager::instance().discover_control_protocols ();
513 if ((node = Config->control_protocol_state()) != 0) {
514 ControlProtocolManager::instance().set_state (*node, Stateful::loading_state_version);
519 ARDOUR::PluginManager::instance().refresh (!Config->get_discover_vst_on_start());
525 if (!libardour_initialized) {
529 ARDOUR::AudioEngine::destroy ();
535 delete &ControlProtocolManager::instance();
536 #ifdef WINDOWS_VST_SUPPORT
543 delete &PluginManager::instance();
551 ARDOUR::find_bindings_files (map<string,string>& files)
553 vector<std::string> found;
554 Searchpath spath = ardour_config_search_path();
556 if (getenv ("ARDOUR_SAE")) {
557 find_files_matching_pattern (found, spath, "*SAE-*.bindings");
559 find_files_matching_pattern (found, spath, "*.bindings");
566 for (vector<std::string>::iterator x = found.begin(); x != found.end(); ++x) {
567 std::string path(*x);
568 pair<string,string> namepath;
569 namepath.second = path;
570 namepath.first = PBD::basename_nosuffix (path);
571 files.insert (namepath);
576 ARDOUR::no_auto_connect()
578 return getenv ("ARDOUR_NO_AUTOCONNECT") != 0;
585 if (getenv ("ARDOUR_RUNNING_UNDER_VALGRIND")) {
586 // valgrind doesn't understand this assembler stuff
587 // September 10th, 2007
591 #if defined(ARCH_X86) && defined(USE_XMMINTRIN)
596 /* XXX use real code to determine if the processor supports
597 DenormalsAreZero and FlushToZero
600 if (!fpu.has_flush_to_zero() && !fpu.has_denormals_are_zero()) {
604 MXCSR = _mm_getcsr();
606 #ifdef DEBUG_DENORMAL_EXCEPTION
607 /* This will raise a FP exception if a denormal is detected */
608 MXCSR &= ~_MM_MASK_DENORM;
611 switch (Config->get_denormal_model()) {
613 MXCSR &= ~(_MM_FLUSH_ZERO_ON | 0x40);
617 if (fpu.has_flush_to_zero()) {
618 MXCSR |= _MM_FLUSH_ZERO_ON;
623 MXCSR &= ~_MM_FLUSH_ZERO_ON;
624 if (fpu.has_denormals_are_zero()) {
630 if (fpu.has_flush_to_zero()) {
631 if (fpu.has_denormals_are_zero()) {
632 MXCSR |= _MM_FLUSH_ZERO_ON | 0x40;
634 MXCSR |= _MM_FLUSH_ZERO_ON;
645 /* this can be changed to modify the translation behaviour for
646 cases where the user has never expressed a preference.
648 static const bool translate_by_default = true;
651 ARDOUR::translation_enable_path ()
653 return Glib::build_filename (user_config_directory(), ".translate");
657 ARDOUR::translations_are_enabled ()
659 int fd = g_open (ARDOUR::translation_enable_path().c_str(), O_RDONLY, 0444);
662 return translate_by_default;
668 if (::read (fd, &c, 1) == 1 && c == '1') {
678 ARDOUR::set_translations_enabled (bool yn)
680 string i18n_enabler = ARDOUR::translation_enable_path();
681 int fd = g_open (i18n_enabler.c_str(), O_WRONLY|O_CREAT|O_TRUNC, 0644);
695 (void) ::write (fd, &c, 1);
703 ARDOUR::get_available_sync_options ()
705 vector<SyncSource> ret;
707 boost::shared_ptr<AudioBackend> backend = AudioEngine::instance()->current_backend();
708 if (backend && backend->name() == "JACK") {
709 ret.push_back (Engine);
713 ret.push_back (MIDIClock);
719 /** Return a monotonic value for the number of microseconds that have elapsed
720 * since an arbitrary zero origin.
724 /* Thanks Apple for not implementing this basic SUSv2, POSIX.1-2001 function
726 #include <mach/mach_time.h>
727 #define CLOCK_REALTIME 0
728 #define CLOCK_MONOTONIC 0
730 clock_gettime (int /*clk_id*/, struct timespec *t)
732 static bool initialized = false;
733 static mach_timebase_info_data_t timebase;
735 mach_timebase_info(&timebase);
739 time = mach_absolute_time();
740 double nseconds = ((double)time * (double)timebase.numer)/((double)timebase.denom);
741 double seconds = ((double)time * (double)timebase.numer)/((double)timebase.denom * 1e9);
743 t->tv_nsec = nseconds;
749 ARDOUR::get_microseconds ()
751 #ifdef PLATFORM_WINDOWS
752 microseconds_t ret = 0;
753 LARGE_INTEGER freq, time;
755 if (QueryPerformanceFrequency(&freq))
756 if (QueryPerformanceCounter(&time))
757 ret = (microseconds_t)((time.QuadPart * 1000000) / freq.QuadPart);
762 if (clock_gettime (CLOCK_MONOTONIC, &ts) != 0) {
766 return (microseconds_t) ts.tv_sec * 1000000 + (ts.tv_nsec/1000);
770 /** Return the number of bits per sample for a given sample format.
772 * This is closely related to sndfile_data_width() but does NOT
773 * return a "magic" value to differentiate between 32 bit integer
774 * and 32 bit floating point values.
778 ARDOUR::format_data_width (ARDOUR::SampleFormat format)
784 case ARDOUR::FormatInt16:
786 case ARDOUR::FormatInt24: