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/fileutils.h>
65 #include <glibmm/miscutils.h>
72 #include "pbd/error.h"
75 #include "pbd/strsplit.h"
77 #include "pbd/file_utils.h"
78 #include "pbd/enumwriter.h"
79 #include "pbd/basename.h"
81 #include "midi++/port.h"
82 #include "midi++/mmc.h"
84 #include "ardour/analyser.h"
85 #include "ardour/audio_library.h"
86 #include "ardour/audio_backend.h"
87 #include "ardour/audioengine.h"
88 #include "ardour/audioplaylist.h"
89 #include "ardour/audioregion.h"
90 #include "ardour/buffer_manager.h"
91 #include "ardour/control_protocol_manager.h"
92 #include "ardour/directory_names.h"
93 #include "ardour/event_type_map.h"
94 #include "ardour/filesystem_paths.h"
95 #include "ardour/midi_region.h"
96 #include "ardour/midiport_manager.h"
97 #include "ardour/mix.h"
98 #include "ardour/operations.h"
99 #include "ardour/panner_manager.h"
100 #include "ardour/plugin_manager.h"
101 #include "ardour/process_thread.h"
102 #include "ardour/profile.h"
103 #include "ardour/rc_configuration.h"
104 #include "ardour/region.h"
105 #include "ardour/route_group.h"
106 #include "ardour/runtime_functions.h"
107 #include "ardour/session_event.h"
108 #include "ardour/source_factory.h"
109 #include "ardour/uri_map.h"
111 #include "audiographer/routines.h"
113 #if defined (__APPLE__)
114 #include <Carbon/Carbon.h> // For Gestalt
119 ARDOUR::RCConfiguration* ARDOUR::Config = 0;
120 ARDOUR::RuntimeProfile* ARDOUR::Profile = 0;
121 ARDOUR::AudioLibrary* ARDOUR::Library = 0;
123 using namespace ARDOUR;
127 bool libardour_initialized = false;
129 compute_peak_t ARDOUR::compute_peak = 0;
130 find_peaks_t ARDOUR::find_peaks = 0;
131 apply_gain_to_buffer_t ARDOUR::apply_gain_to_buffer = 0;
132 mix_buffers_with_gain_t ARDOUR::mix_buffers_with_gain = 0;
133 mix_buffers_no_gain_t ARDOUR::mix_buffers_no_gain = 0;
134 copy_vector_t ARDOUR::copy_vector = 0;
136 PBD::Signal1<void,std::string> ARDOUR::BootMessage;
137 PBD::Signal3<void,std::string,std::string,bool> ARDOUR::PluginScanMessage;
138 PBD::Signal1<void,int> ARDOUR::PluginScanTimeout;
139 PBD::Signal0<void> ARDOUR::GUIIdle;
140 PBD::Signal3<bool,std::string,std::string,int> ARDOUR::CopyConfigurationFiles;
142 static bool have_old_configuration_files = false;
145 extern void setup_enum_writer ();
148 /* this is useful for quite a few things that want to check
149 if any bounds-related property has changed
151 PBD::PropertyChange ARDOUR::bounds_change;
154 setup_hardware_optimization (bool try_optimization)
156 bool generic_mix_functions = true;
158 if (try_optimization) {
162 #if defined (ARCH_X86) && defined (BUILD_SSE_OPTIMIZATIONS)
166 info << "Using AVX optimized routines" << endmsg;
169 compute_peak = x86_sse_avx_compute_peak;
170 find_peaks = x86_sse_avx_find_peaks;
171 apply_gain_to_buffer = x86_sse_avx_apply_gain_to_buffer;
172 mix_buffers_with_gain = x86_sse_avx_mix_buffers_with_gain;
173 mix_buffers_no_gain = x86_sse_avx_mix_buffers_no_gain;
174 copy_vector = x86_sse_avx_copy_vector;
176 generic_mix_functions = false;
178 } else if (fpu.has_sse()) {
180 info << "Using SSE optimized routines" << endmsg;
183 compute_peak = x86_sse_compute_peak;
184 find_peaks = x86_sse_find_peaks;
185 apply_gain_to_buffer = x86_sse_apply_gain_to_buffer;
186 mix_buffers_with_gain = x86_sse_mix_buffers_with_gain;
187 mix_buffers_no_gain = x86_sse_mix_buffers_no_gain;
188 copy_vector = default_copy_vector;
190 generic_mix_functions = false;
194 #elif defined (__APPLE__) && defined (BUILD_VECLIB_OPTIMIZATIONS)
195 SInt32 sysVersion = 0;
197 if (noErr != Gestalt(gestaltSystemVersion, &sysVersion))
200 if (sysVersion >= 0x00001040) { // Tiger at least
201 compute_peak = veclib_compute_peak;
202 find_peaks = veclib_find_peaks;
203 apply_gain_to_buffer = veclib_apply_gain_to_buffer;
204 mix_buffers_with_gain = veclib_mix_buffers_with_gain;
205 mix_buffers_no_gain = veclib_mix_buffers_no_gain;
206 copy_vector = default_copy_vector;
208 generic_mix_functions = false;
210 info << "Apple VecLib H/W specific optimizations in use" << endmsg;
214 /* consider FPU denormal handling to be "h/w optimization" */
219 if (generic_mix_functions) {
221 compute_peak = default_compute_peak;
222 find_peaks = default_find_peaks;
223 apply_gain_to_buffer = default_apply_gain_to_buffer;
224 mix_buffers_with_gain = default_mix_buffers_with_gain;
225 mix_buffers_no_gain = default_mix_buffers_no_gain;
226 copy_vector = default_copy_vector;
228 info << "No H/W specific optimizations in use" << endmsg;
231 AudioGrapher::Routines::override_compute_peak (compute_peak);
232 AudioGrapher::Routines::override_apply_gain_to_buffer (apply_gain_to_buffer);
236 lotsa_files_please ()
238 #ifndef PLATFORM_WINDOWS
241 if (getrlimit (RLIMIT_NOFILE, &rl) == 0) {
244 /* See the COMPATIBILITY note on the Apple setrlimit() man page */
245 rl.rlim_cur = min ((rlim_t) OPEN_MAX, rl.rlim_max);
247 rl.rlim_cur = rl.rlim_max;
250 if (setrlimit (RLIMIT_NOFILE, &rl) != 0) {
251 if (rl.rlim_cur == RLIM_INFINITY) {
252 error << _("Could not set system open files limit to \"unlimited\"") << endmsg;
254 error << string_compose (_("Could not set system open files limit to %1"), rl.rlim_cur) << endmsg;
257 if (rl.rlim_cur != RLIM_INFINITY) {
258 info << string_compose (_("Your system is configured to limit %1 to only %2 open files"), PROGRAM_NAME, rl.rlim_cur) << endmsg;
262 error << string_compose (_("Could not get system open files limit (%1)"), strerror (errno)) << endmsg;
268 copy_configuration_files (string const & old_dir, string const & new_dir, int old_version)
273 /* ensure target directory exists */
275 if (g_mkdir_with_parents (new_dir.c_str(), 0755)) {
279 if (old_version == 3) {
281 old_name = Glib::build_filename (old_dir, X_("recent"));
282 new_name = Glib::build_filename (new_dir, X_("recent"));
284 copy_file (old_name, new_name);
286 old_name = Glib::build_filename (old_dir, X_("sfdb"));
287 new_name = Glib::build_filename (new_dir, X_("sfdb"));
289 copy_file (old_name, new_name);
291 /* can only copy ardour.rc/config - UI config is not compatible */
293 /* users who have been using git/nightlies since the last
294 * release of 3.5 will have $CONFIG/config rather than
295 * $CONFIG/ardour.rc. Pick up the newer "old" config file,
296 * to avoid confusion.
299 string old_name = Glib::build_filename (old_dir, X_("config"));
301 if (!Glib::file_test (old_name, Glib::FILE_TEST_EXISTS)) {
302 old_name = Glib::build_filename (old_dir, X_("ardour.rc"));
305 new_name = Glib::build_filename (new_dir, X_("config"));
307 copy_file (old_name, new_name);
309 /* copy templates and route templates */
311 old_name = Glib::build_filename (old_dir, X_("templates"));
312 new_name = Glib::build_filename (new_dir, X_("templates"));
314 copy_recurse (old_name, new_name);
316 old_name = Glib::build_filename (old_dir, X_("route_templates"));
317 new_name = Glib::build_filename (new_dir, X_("route_templates"));
319 copy_recurse (old_name, new_name);
323 old_name = Glib::build_filename (old_dir, X_("presets"));
324 new_name = Glib::build_filename (new_dir, X_("presets"));
326 copy_recurse (old_name, new_name);
330 old_name = Glib::build_filename (old_dir, X_("plugin_statuses"));
331 new_name = Glib::build_filename (new_dir, X_("plugin_statuses"));
333 copy_file (old_name, new_name);
337 old_name = Glib::build_filename (old_dir, export_formats_dir_name);
338 new_name = Glib::build_filename (new_dir, export_formats_dir_name);
340 vector<string> export_formats;
341 g_mkdir_with_parents (Glib::build_filename (new_dir, export_formats_dir_name).c_str(), 0755);
342 find_files_matching_pattern (export_formats, old_name, X_("*.format"));
343 for (vector<string>::iterator i = export_formats.begin(); i != export_formats.end(); ++i) {
344 std::string from = *i;
345 std::string to = Glib::build_filename (new_name, Glib::path_get_basename (*i));
346 copy_file (from, to);
354 ARDOUR::check_for_old_configuration_files ()
356 int current_version = atoi (X_(PROGRAM_VERSION));
358 if (current_version <= 1) {
362 int old_version = current_version - 1;
364 string old_config_dir = user_config_directory (old_version);
365 /* pass in the current version explicitly to avoid creation */
366 string current_config_dir = user_config_directory (current_version);
368 if (!Glib::file_test (current_config_dir, Glib::FILE_TEST_IS_DIR)) {
369 if (Glib::file_test (old_config_dir, Glib::FILE_TEST_IS_DIR)) {
370 have_old_configuration_files = true;
376 ARDOUR::handle_old_configuration_files (boost::function<bool (std::string const&, std::string const&, int)> ui_handler)
378 if (have_old_configuration_files) {
379 int current_version = atoi (X_(PROGRAM_VERSION));
380 assert (current_version > 1); // established in check_for_old_configuration_files ()
381 int old_version = current_version - 1;
382 string old_config_dir = user_config_directory (old_version);
383 string current_config_dir = user_config_directory (current_version);
385 if (ui_handler (old_config_dir, current_config_dir, old_version)) {
386 copy_configuration_files (old_config_dir, current_config_dir, old_version);
394 ARDOUR::init (bool use_windows_vst, bool try_optimization, const char* localedir)
396 if (libardour_initialized) {
400 if (!PBD::init()) return false;
403 (void) bindtextdomain(PACKAGE, localedir);
404 (void) bind_textdomain_codeset (PACKAGE, "UTF-8");
407 SessionEvent::init_event_pool ();
409 Operations::make_operations_quarks ();
410 SessionObject::make_property_quarks ();
411 Region::make_property_quarks ();
412 MidiRegion::make_property_quarks ();
413 AudioRegion::make_property_quarks ();
414 RouteGroup::make_property_quarks ();
415 Playlist::make_property_quarks ();
416 AudioPlaylist::make_property_quarks ();
418 /* this is a useful ready to use PropertyChange that many
419 things need to check. This avoids having to compose
420 it every time we want to check for any of the relevant
424 bounds_change.add (ARDOUR::Properties::start);
425 bounds_change.add (ARDOUR::Properties::position);
426 bounds_change.add (ARDOUR::Properties::length);
428 /* provide a state version for the few cases that need it and are not
429 driven by reading state from disk (e.g. undo/redo)
432 Stateful::current_state_version = CURRENT_SESSION_FILE_VERSION;
434 ARDOUR::setup_enum_writer ();
436 // allow ardour the absolute maximum number of open files
437 lotsa_files_please ();
442 Library = new AudioLibrary;
444 BootMessage (_("Loading configuration"));
446 Config = new RCConfiguration;
448 if (Config->load_state ()) {
452 Config->set_use_windows_vst (use_windows_vst);
454 Config->set_use_lxvst(true);
457 Profile = new RuntimeProfile;
460 #ifdef WINDOWS_VST_SUPPORT
461 if (Config->get_use_windows_vst() && fst_init (0)) {
467 if (Config->get_use_lxvst() && vstfx_init (0)) {
472 #ifdef AUDIOUNIT_SUPPORT
473 AUPluginInfo::load_cached_info ();
476 setup_hardware_optimization (try_optimization);
478 SourceFactory::init ();
481 /* singletons - first object is "it" */
482 (void) PluginManager::instance();
484 (void) URIMap::instance();
486 (void) EventTypeMap::instance();
488 ProcessThread::init ();
489 /* the + 4 is a bit of a handwave. i don't actually know
490 how many more per-thread buffer sets we need above
491 the h/w concurrency, but its definitely > 1 more.
493 BufferManager::init (hardware_concurrency() + 4);
495 PannerManager::instance().discover_panners();
497 ARDOUR::AudioEngine::create ();
499 libardour_initialized = true;
505 ARDOUR::init_post_engine ()
507 ControlProtocolManager::instance().discover_control_protocols ();
510 if ((node = Config->control_protocol_state()) != 0) {
511 ControlProtocolManager::instance().set_state (*node, Stateful::loading_state_version);
516 ARDOUR::PluginManager::instance().refresh (!Config->get_discover_vst_on_start());
522 if (!libardour_initialized) {
526 ARDOUR::AudioEngine::destroy ();
532 delete &ControlProtocolManager::instance();
533 #ifdef WINDOWS_VST_SUPPORT
540 delete &PluginManager::instance();
548 ARDOUR::find_bindings_files (map<string,string>& files)
550 vector<std::string> found;
551 Searchpath spath = ardour_config_search_path();
553 if (getenv ("ARDOUR_SAE")) {
554 find_files_matching_pattern (found, spath, "*SAE-*.bindings");
556 find_files_matching_pattern (found, spath, "*.bindings");
563 for (vector<std::string>::iterator x = found.begin(); x != found.end(); ++x) {
564 std::string path(*x);
565 pair<string,string> namepath;
566 namepath.second = path;
567 namepath.first = PBD::basename_nosuffix (path);
568 files.insert (namepath);
573 ARDOUR::no_auto_connect()
575 return getenv ("ARDOUR_NO_AUTOCONNECT") != 0;
582 if (getenv ("ARDOUR_RUNNING_UNDER_VALGRIND")) {
583 // valgrind doesn't understand this assembler stuff
584 // September 10th, 2007
588 #if defined(ARCH_X86) && defined(USE_XMMINTRIN)
593 /* XXX use real code to determine if the processor supports
594 DenormalsAreZero and FlushToZero
597 if (!fpu.has_flush_to_zero() && !fpu.has_denormals_are_zero()) {
601 MXCSR = _mm_getcsr();
603 #ifdef DEBUG_DENORMAL_EXCEPTION
604 /* This will raise a FP exception if a denormal is detected */
605 MXCSR &= ~_MM_MASK_DENORM;
608 switch (Config->get_denormal_model()) {
610 MXCSR &= ~(_MM_FLUSH_ZERO_ON | 0x40);
614 if (fpu.has_flush_to_zero()) {
615 MXCSR |= _MM_FLUSH_ZERO_ON;
620 MXCSR &= ~_MM_FLUSH_ZERO_ON;
621 if (fpu.has_denormals_are_zero()) {
627 if (fpu.has_flush_to_zero()) {
628 if (fpu.has_denormals_are_zero()) {
629 MXCSR |= _MM_FLUSH_ZERO_ON | 0x40;
631 MXCSR |= _MM_FLUSH_ZERO_ON;
642 /* this can be changed to modify the translation behaviour for
643 cases where the user has never expressed a preference.
645 static const bool translate_by_default = true;
648 ARDOUR::translation_enable_path ()
650 return Glib::build_filename (user_config_directory(), ".translate");
654 ARDOUR::translations_are_enabled ()
656 int fd = ::open (ARDOUR::translation_enable_path().c_str(), O_RDONLY);
659 return translate_by_default;
665 if (::read (fd, &c, 1) == 1 && c == '1') {
675 ARDOUR::set_translations_enabled (bool yn)
677 string i18n_enabler = ARDOUR::translation_enable_path();
678 int fd = ::open (i18n_enabler.c_str(), O_WRONLY|O_CREAT|O_TRUNC, 0644);
692 (void) ::write (fd, &c, 1);
700 ARDOUR::get_available_sync_options ()
702 vector<SyncSource> ret;
704 boost::shared_ptr<AudioBackend> backend = AudioEngine::instance()->current_backend();
705 if (backend && backend->name() == "JACK") {
706 ret.push_back (Engine);
710 ret.push_back (MIDIClock);
716 /** Return a monotonic value for the number of microseconds that have elapsed
717 * since an arbitrary zero origin.
721 /* Thanks Apple for not implementing this basic SUSv2, POSIX.1-2001 function
723 #include <mach/mach_time.h>
724 #define CLOCK_REALTIME 0
725 #define CLOCK_MONOTONIC 0
727 clock_gettime (int /*clk_id*/, struct timespec *t)
729 static bool initialized = false;
730 static mach_timebase_info_data_t timebase;
732 mach_timebase_info(&timebase);
736 time = mach_absolute_time();
737 double nseconds = ((double)time * (double)timebase.numer)/((double)timebase.denom);
738 double seconds = ((double)time * (double)timebase.numer)/((double)timebase.denom * 1e9);
740 t->tv_nsec = nseconds;
746 ARDOUR::get_microseconds ()
748 #ifdef PLATFORM_WINDOWS
749 microseconds_t ret = 0;
750 LARGE_INTEGER freq, time;
752 if (QueryPerformanceFrequency(&freq))
753 if (QueryPerformanceCounter(&time))
754 ret = (microseconds_t)((time.QuadPart * 1000000) / freq.QuadPart);
759 if (clock_gettime (CLOCK_MONOTONIC, &ts) != 0) {
763 return (microseconds_t) ts.tv_sec * 1000000 + (ts.tv_nsec/1000);
767 /** Return the number of bits per sample for a given sample format.
769 * This is closely related to sndfile_data_width() but does NOT
770 * return a "magic" value to differentiate between 32 bit integer
771 * and 32 bit floating point values.
775 ARDOUR::format_data_width (ARDOUR::SampleFormat format)
781 case ARDOUR::FormatInt16:
783 case ARDOUR::FormatInt24: