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 <pbd/gstdio_compat.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) {
163 FPU* fpu = FPU::instance();
165 #if defined (ARCH_X86) && defined (BUILD_SSE_OPTIMIZATIONS)
167 #ifdef PLATFORM_WINDOWS
168 /* We have AVX-optimized code for Windows */
170 if (fpu->has_avx()) {
172 /* AVX code doesn't compile on Linux yet */
176 info << "Using AVX optimized routines" << endmsg;
179 compute_peak = x86_sse_avx_compute_peak;
180 find_peaks = x86_sse_avx_find_peaks;
181 apply_gain_to_buffer = x86_sse_avx_apply_gain_to_buffer;
182 mix_buffers_with_gain = x86_sse_avx_mix_buffers_with_gain;
183 mix_buffers_no_gain = x86_sse_avx_mix_buffers_no_gain;
184 copy_vector = x86_sse_avx_copy_vector;
186 generic_mix_functions = false;
188 } else if (fpu->has_sse()) {
190 info << "Using SSE optimized routines" << endmsg;
193 compute_peak = x86_sse_compute_peak;
194 find_peaks = x86_sse_find_peaks;
195 apply_gain_to_buffer = x86_sse_apply_gain_to_buffer;
196 mix_buffers_with_gain = x86_sse_mix_buffers_with_gain;
197 mix_buffers_no_gain = x86_sse_mix_buffers_no_gain;
198 copy_vector = default_copy_vector;
200 generic_mix_functions = false;
204 #elif defined (__APPLE__) && defined (BUILD_VECLIB_OPTIMIZATIONS)
205 SInt32 sysVersion = 0;
207 if (noErr != Gestalt(gestaltSystemVersion, &sysVersion))
210 if (sysVersion >= 0x00001040) { // Tiger at least
211 compute_peak = veclib_compute_peak;
212 find_peaks = veclib_find_peaks;
213 apply_gain_to_buffer = veclib_apply_gain_to_buffer;
214 mix_buffers_with_gain = veclib_mix_buffers_with_gain;
215 mix_buffers_no_gain = veclib_mix_buffers_no_gain;
216 copy_vector = default_copy_vector;
218 generic_mix_functions = false;
220 info << "Apple VecLib H/W specific optimizations in use" << endmsg;
224 /* consider FPU denormal handling to be "h/w optimization" */
229 if (generic_mix_functions) {
231 compute_peak = default_compute_peak;
232 find_peaks = default_find_peaks;
233 apply_gain_to_buffer = default_apply_gain_to_buffer;
234 mix_buffers_with_gain = default_mix_buffers_with_gain;
235 mix_buffers_no_gain = default_mix_buffers_no_gain;
236 copy_vector = default_copy_vector;
238 info << "No H/W specific optimizations in use" << endmsg;
241 AudioGrapher::Routines::override_compute_peak (compute_peak);
242 AudioGrapher::Routines::override_apply_gain_to_buffer (apply_gain_to_buffer);
246 lotsa_files_please ()
248 #ifndef PLATFORM_WINDOWS
251 if (getrlimit (RLIMIT_NOFILE, &rl) == 0) {
254 /* See the COMPATIBILITY note on the Apple setrlimit() man page */
255 rl.rlim_cur = min ((rlim_t) OPEN_MAX, rl.rlim_max);
257 rl.rlim_cur = rl.rlim_max;
260 if (setrlimit (RLIMIT_NOFILE, &rl) != 0) {
261 if (rl.rlim_cur == RLIM_INFINITY) {
262 error << _("Could not set system open files limit to \"unlimited\"") << endmsg;
264 error << string_compose (_("Could not set system open files limit to %1"), rl.rlim_cur) << endmsg;
267 if (rl.rlim_cur != RLIM_INFINITY) {
268 info << string_compose (_("Your system is configured to limit %1 to only %2 open files"), PROGRAM_NAME, rl.rlim_cur) << endmsg;
272 error << string_compose (_("Could not get system open files limit (%1)"), strerror (errno)) << endmsg;
278 copy_configuration_files (string const & old_dir, string const & new_dir, int old_version)
283 /* ensure target directory exists */
285 if (g_mkdir_with_parents (new_dir.c_str(), 0755)) {
289 if (old_version == 3) {
291 old_name = Glib::build_filename (old_dir, X_("recent"));
292 new_name = Glib::build_filename (new_dir, X_("recent"));
294 copy_file (old_name, new_name);
296 old_name = Glib::build_filename (old_dir, X_("sfdb"));
297 new_name = Glib::build_filename (new_dir, X_("sfdb"));
299 copy_file (old_name, new_name);
301 /* can only copy ardour.rc/config - UI config is not compatible */
303 /* users who have been using git/nightlies since the last
304 * release of 3.5 will have $CONFIG/config rather than
305 * $CONFIG/ardour.rc. Pick up the newer "old" config file,
306 * to avoid confusion.
309 string old_name = Glib::build_filename (old_dir, X_("config"));
311 if (!Glib::file_test (old_name, Glib::FILE_TEST_EXISTS)) {
312 old_name = Glib::build_filename (old_dir, X_("ardour.rc"));
315 new_name = Glib::build_filename (new_dir, X_("config"));
317 copy_file (old_name, new_name);
319 /* copy templates and route templates */
321 old_name = Glib::build_filename (old_dir, X_("templates"));
322 new_name = Glib::build_filename (new_dir, X_("templates"));
324 copy_recurse (old_name, new_name);
326 old_name = Glib::build_filename (old_dir, X_("route_templates"));
327 new_name = Glib::build_filename (new_dir, X_("route_templates"));
329 copy_recurse (old_name, new_name);
333 old_name = Glib::build_filename (old_dir, X_("presets"));
334 new_name = Glib::build_filename (new_dir, X_("presets"));
336 copy_recurse (old_name, new_name);
340 old_name = Glib::build_filename (old_dir, X_("plugin_statuses"));
341 new_name = Glib::build_filename (new_dir, X_("plugin_statuses"));
343 copy_file (old_name, new_name);
347 old_name = Glib::build_filename (old_dir, export_formats_dir_name);
348 new_name = Glib::build_filename (new_dir, export_formats_dir_name);
350 vector<string> export_formats;
351 g_mkdir_with_parents (Glib::build_filename (new_dir, export_formats_dir_name).c_str(), 0755);
352 find_files_matching_pattern (export_formats, old_name, X_("*.format"));
353 for (vector<string>::iterator i = export_formats.begin(); i != export_formats.end(); ++i) {
354 std::string from = *i;
355 std::string to = Glib::build_filename (new_name, Glib::path_get_basename (*i));
356 copy_file (from, to);
364 ARDOUR::check_for_old_configuration_files ()
366 int current_version = atoi (X_(PROGRAM_VERSION));
368 if (current_version <= 1) {
372 int old_version = current_version - 1;
374 string old_config_dir = user_config_directory (old_version);
375 /* pass in the current version explicitly to avoid creation */
376 string current_config_dir = user_config_directory (current_version);
378 if (!Glib::file_test (current_config_dir, Glib::FILE_TEST_IS_DIR)) {
379 if (Glib::file_test (old_config_dir, Glib::FILE_TEST_IS_DIR)) {
380 have_old_configuration_files = true;
386 ARDOUR::handle_old_configuration_files (boost::function<bool (std::string const&, std::string const&, int)> ui_handler)
388 if (have_old_configuration_files) {
389 int current_version = atoi (X_(PROGRAM_VERSION));
390 assert (current_version > 1); // established in check_for_old_configuration_files ()
391 int old_version = current_version - 1;
392 string old_config_dir = user_config_directory (old_version);
393 string current_config_dir = user_config_directory (current_version);
395 if (ui_handler (old_config_dir, current_config_dir, old_version)) {
396 copy_configuration_files (old_config_dir, current_config_dir, old_version);
404 ARDOUR::init (bool use_windows_vst, bool try_optimization, const char* localedir)
406 if (libardour_initialized) {
410 if (!PBD::init()) return false;
413 (void) bindtextdomain(PACKAGE, localedir);
414 (void) bind_textdomain_codeset (PACKAGE, "UTF-8");
417 SessionEvent::init_event_pool ();
419 Operations::make_operations_quarks ();
420 SessionObject::make_property_quarks ();
421 Region::make_property_quarks ();
422 MidiRegion::make_property_quarks ();
423 AudioRegion::make_property_quarks ();
424 RouteGroup::make_property_quarks ();
425 Playlist::make_property_quarks ();
426 AudioPlaylist::make_property_quarks ();
428 /* this is a useful ready to use PropertyChange that many
429 things need to check. This avoids having to compose
430 it every time we want to check for any of the relevant
434 bounds_change.add (ARDOUR::Properties::start);
435 bounds_change.add (ARDOUR::Properties::position);
436 bounds_change.add (ARDOUR::Properties::length);
438 /* provide a state version for the few cases that need it and are not
439 driven by reading state from disk (e.g. undo/redo)
442 Stateful::current_state_version = CURRENT_SESSION_FILE_VERSION;
444 ARDOUR::setup_enum_writer ();
446 // allow ardour the absolute maximum number of open files
447 lotsa_files_please ();
452 Library = new AudioLibrary;
454 BootMessage (_("Loading configuration"));
456 Config = new RCConfiguration;
458 if (Config->load_state ()) {
462 Config->set_use_windows_vst (use_windows_vst);
464 Config->set_use_lxvst(true);
467 Profile = new RuntimeProfile;
470 #ifdef WINDOWS_VST_SUPPORT
471 if (Config->get_use_windows_vst() && fst_init (0)) {
477 if (Config->get_use_lxvst() && vstfx_init (0)) {
482 #ifdef AUDIOUNIT_SUPPORT
483 AUPluginInfo::load_cached_info ();
486 setup_hardware_optimization (try_optimization);
488 SourceFactory::init ();
491 /* singletons - first object is "it" */
492 (void) PluginManager::instance();
494 (void) URIMap::instance();
496 (void) EventTypeMap::instance();
498 ProcessThread::init ();
499 /* the + 4 is a bit of a handwave. i don't actually know
500 how many more per-thread buffer sets we need above
501 the h/w concurrency, but its definitely > 1 more.
503 BufferManager::init (hardware_concurrency() + 4);
505 PannerManager::instance().discover_panners();
507 ARDOUR::AudioEngine::create ();
509 libardour_initialized = true;
515 ARDOUR::init_post_engine ()
517 ControlProtocolManager::instance().discover_control_protocols ();
520 if ((node = Config->control_protocol_state()) != 0) {
521 ControlProtocolManager::instance().set_state (*node, Stateful::loading_state_version);
526 ARDOUR::PluginManager::instance().refresh (!Config->get_discover_vst_on_start());
532 if (!libardour_initialized) {
536 ARDOUR::AudioEngine::destroy ();
542 delete &ControlProtocolManager::instance();
543 #ifdef WINDOWS_VST_SUPPORT
550 delete &PluginManager::instance();
558 ARDOUR::find_bindings_files (map<string,string>& files)
560 vector<std::string> found;
561 Searchpath spath = ardour_config_search_path();
563 if (getenv ("ARDOUR_SAE")) {
564 find_files_matching_pattern (found, spath, "*SAE-*.bindings");
566 find_files_matching_pattern (found, spath, "*.bindings");
573 for (vector<std::string>::iterator x = found.begin(); x != found.end(); ++x) {
574 std::string path(*x);
575 pair<string,string> namepath;
576 namepath.second = path;
577 namepath.first = PBD::basename_nosuffix (path);
578 files.insert (namepath);
583 ARDOUR::no_auto_connect()
585 return getenv ("ARDOUR_NO_AUTOCONNECT") != 0;
591 FPU* fpu = FPU::instance ();
593 if (getenv ("ARDOUR_RUNNING_UNDER_VALGRIND")) {
594 // valgrind doesn't understand this assembler stuff
595 // September 10th, 2007
599 #if defined(ARCH_X86) && defined(USE_XMMINTRIN)
603 if (!fpu->has_flush_to_zero() && !fpu->has_denormals_are_zero()) {
607 MXCSR = _mm_getcsr();
609 #ifdef DEBUG_DENORMAL_EXCEPTION
610 /* This will raise a FP exception if a denormal is detected */
611 MXCSR &= ~_MM_MASK_DENORM;
614 switch (Config->get_denormal_model()) {
616 MXCSR &= ~(_MM_FLUSH_ZERO_ON | 0x40);
620 if (fpu->has_flush_to_zero()) {
621 MXCSR |= _MM_FLUSH_ZERO_ON;
626 MXCSR &= ~_MM_FLUSH_ZERO_ON;
627 if (fpu->has_denormals_are_zero()) {
633 if (fpu->has_flush_to_zero()) {
634 if (fpu->has_denormals_are_zero()) {
635 MXCSR |= _MM_FLUSH_ZERO_ON | 0x40;
637 MXCSR |= _MM_FLUSH_ZERO_ON;
648 /* this can be changed to modify the translation behaviour for
649 cases where the user has never expressed a preference.
651 static const bool translate_by_default = true;
654 ARDOUR::translation_enable_path ()
656 return Glib::build_filename (user_config_directory(), ".translate");
660 ARDOUR::translations_are_enabled ()
662 int fd = g_open (ARDOUR::translation_enable_path().c_str(), O_RDONLY, 0444);
665 return translate_by_default;
671 if (::read (fd, &c, 1) == 1 && c == '1') {
681 ARDOUR::set_translations_enabled (bool yn)
683 string i18n_enabler = ARDOUR::translation_enable_path();
684 int fd = g_open (i18n_enabler.c_str(), O_WRONLY|O_CREAT|O_TRUNC, 0644);
698 (void) ::write (fd, &c, 1);
706 ARDOUR::get_available_sync_options ()
708 vector<SyncSource> ret;
710 boost::shared_ptr<AudioBackend> backend = AudioEngine::instance()->current_backend();
711 if (backend && backend->name() == "JACK") {
712 ret.push_back (Engine);
716 ret.push_back (MIDIClock);
722 /** Return a monotonic value for the number of microseconds that have elapsed
723 * since an arbitrary zero origin.
727 /* Thanks Apple for not implementing this basic SUSv2, POSIX.1-2001 function
729 #include <mach/mach_time.h>
730 #define CLOCK_REALTIME 0
731 #define CLOCK_MONOTONIC 0
733 clock_gettime (int /*clk_id*/, struct timespec *t)
735 static bool initialized = false;
736 static mach_timebase_info_data_t timebase;
738 mach_timebase_info(&timebase);
742 time = mach_absolute_time();
743 double nseconds = ((double)time * (double)timebase.numer)/((double)timebase.denom);
744 double seconds = ((double)time * (double)timebase.numer)/((double)timebase.denom * 1e9);
746 t->tv_nsec = nseconds;
752 ARDOUR::get_microseconds ()
754 #ifdef PLATFORM_WINDOWS
755 microseconds_t ret = 0;
756 LARGE_INTEGER freq, time;
758 if (QueryPerformanceFrequency(&freq))
759 if (QueryPerformanceCounter(&time))
760 ret = (microseconds_t)((time.QuadPart * 1000000) / freq.QuadPart);
765 if (clock_gettime (CLOCK_MONOTONIC, &ts) != 0) {
769 return (microseconds_t) ts.tv_sec * 1000000 + (ts.tv_nsec/1000);
773 /** Return the number of bits per sample for a given sample format.
775 * This is closely related to sndfile_data_width() but does NOT
776 * return a "magic" value to differentiate between 32 bit integer
777 * and 32 bit floating point values.
781 ARDOUR::format_data_width (ARDOUR::SampleFormat format)
787 case ARDOUR::FormatInt16:
789 case ARDOUR::FormatInt24: