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;
135 PBD::Signal1<void,std::string> ARDOUR::BootMessage;
136 PBD::Signal3<void,std::string,std::string,bool> ARDOUR::PluginScanMessage;
137 PBD::Signal1<void,int> ARDOUR::PluginScanTimeout;
138 PBD::Signal0<void> ARDOUR::GUIIdle;
139 PBD::Signal3<bool,std::string,std::string,int> ARDOUR::CopyConfigurationFiles;
141 static bool have_old_configuration_files = false;
144 extern void setup_enum_writer ();
147 /* this is useful for quite a few things that want to check
148 if any bounds-related property has changed
150 PBD::PropertyChange ARDOUR::bounds_change;
153 setup_hardware_optimization (bool try_optimization)
155 bool generic_mix_functions = true;
157 if (try_optimization) {
161 #if defined (ARCH_X86) && defined (BUILD_SSE_OPTIMIZATIONS)
165 info << "Using SSE optimized routines" << endmsg;
168 compute_peak = x86_sse_compute_peak;
169 find_peaks = x86_sse_find_peaks;
170 apply_gain_to_buffer = x86_sse_apply_gain_to_buffer;
171 mix_buffers_with_gain = x86_sse_mix_buffers_with_gain;
172 mix_buffers_no_gain = x86_sse_mix_buffers_no_gain;
174 generic_mix_functions = false;
178 #elif defined (__APPLE__) && defined (BUILD_VECLIB_OPTIMIZATIONS)
179 SInt32 sysVersion = 0;
181 if (noErr != Gestalt(gestaltSystemVersion, &sysVersion))
184 if (sysVersion >= 0x00001040) { // Tiger at least
185 compute_peak = veclib_compute_peak;
186 find_peaks = veclib_find_peaks;
187 apply_gain_to_buffer = veclib_apply_gain_to_buffer;
188 mix_buffers_with_gain = veclib_mix_buffers_with_gain;
189 mix_buffers_no_gain = veclib_mix_buffers_no_gain;
191 generic_mix_functions = false;
193 info << "Apple VecLib H/W specific optimizations in use" << endmsg;
197 /* consider FPU denormal handling to be "h/w optimization" */
202 if (generic_mix_functions) {
204 compute_peak = default_compute_peak;
205 find_peaks = default_find_peaks;
206 apply_gain_to_buffer = default_apply_gain_to_buffer;
207 mix_buffers_with_gain = default_mix_buffers_with_gain;
208 mix_buffers_no_gain = default_mix_buffers_no_gain;
210 info << "No H/W specific optimizations in use" << endmsg;
213 AudioGrapher::Routines::override_compute_peak (compute_peak);
214 AudioGrapher::Routines::override_apply_gain_to_buffer (apply_gain_to_buffer);
218 lotsa_files_please ()
220 #ifndef PLATFORM_WINDOWS
223 if (getrlimit (RLIMIT_NOFILE, &rl) == 0) {
226 /* See the COMPATIBILITY note on the Apple setrlimit() man page */
227 rl.rlim_cur = min ((rlim_t) OPEN_MAX, rl.rlim_max);
229 rl.rlim_cur = rl.rlim_max;
232 if (setrlimit (RLIMIT_NOFILE, &rl) != 0) {
233 if (rl.rlim_cur == RLIM_INFINITY) {
234 error << _("Could not set system open files limit to \"unlimited\"") << endmsg;
236 error << string_compose (_("Could not set system open files limit to %1"), rl.rlim_cur) << endmsg;
239 if (rl.rlim_cur != RLIM_INFINITY) {
240 info << string_compose (_("Your system is configured to limit %1 to only %2 open files"), PROGRAM_NAME, rl.rlim_cur) << endmsg;
244 error << string_compose (_("Could not get system open files limit (%1)"), strerror (errno)) << endmsg;
250 copy_configuration_files (string const & old_dir, string const & new_dir, int old_version)
255 /* ensure target directory exists */
257 if (g_mkdir_with_parents (new_dir.c_str(), 0755)) {
261 if (old_version == 3) {
263 old_name = Glib::build_filename (old_dir, X_("recent"));
264 new_name = Glib::build_filename (new_dir, X_("recent"));
266 copy_file (old_name, new_name);
268 old_name = Glib::build_filename (old_dir, X_("sfdb"));
269 new_name = Glib::build_filename (new_dir, X_("sfdb"));
271 copy_file (old_name, new_name);
273 /* can only copy ardour.rc/config - UI config is not compatible */
275 /* users who have been using git/nightlies since the last
276 * release of 3.5 will have $CONFIG/config rather than
277 * $CONFIG/ardour.rc. Pick up the newer "old" config file,
278 * to avoid confusion.
281 string old_name = Glib::build_filename (old_dir, X_("config"));
283 if (!Glib::file_test (old_name, Glib::FILE_TEST_EXISTS)) {
284 old_name = Glib::build_filename (old_dir, X_("ardour.rc"));
287 new_name = Glib::build_filename (new_dir, X_("config"));
289 copy_file (old_name, new_name);
291 /* copy templates and route templates */
293 old_name = Glib::build_filename (old_dir, X_("templates"));
294 new_name = Glib::build_filename (new_dir, X_("templates"));
296 copy_recurse (old_name, new_name);
298 old_name = Glib::build_filename (old_dir, X_("route_templates"));
299 new_name = Glib::build_filename (new_dir, X_("route_templates"));
301 copy_recurse (old_name, new_name);
305 old_name = Glib::build_filename (old_dir, X_("presets"));
306 new_name = Glib::build_filename (new_dir, X_("presets"));
308 copy_recurse (old_name, new_name);
312 old_name = Glib::build_filename (old_dir, X_("plugin_statuses"));
313 new_name = Glib::build_filename (new_dir, X_("plugin_statuses"));
315 copy_file (old_name, new_name);
319 old_name = Glib::build_filename (old_dir, export_formats_dir_name);
320 new_name = Glib::build_filename (new_dir, export_formats_dir_name);
322 vector<string> export_formats;
323 g_mkdir_with_parents (Glib::build_filename (new_dir, export_formats_dir_name).c_str(), 0755);
324 find_files_matching_pattern (export_formats, old_name, X_("*.format"));
325 for (vector<string>::iterator i = export_formats.begin(); i != export_formats.end(); ++i) {
326 std::string from = *i;
327 std::string to = Glib::build_filename (new_name, Glib::path_get_basename (*i));
328 copy_file (from, to);
336 ARDOUR::check_for_old_configuration_files ()
338 int current_version = atoi (X_(PROGRAM_VERSION));
340 if (current_version <= 1) {
344 int old_version = current_version - 1;
346 string old_config_dir = user_config_directory (old_version);
347 /* pass in the current version explicitly to avoid creation */
348 string current_config_dir = user_config_directory (current_version);
350 if (!Glib::file_test (current_config_dir, Glib::FILE_TEST_IS_DIR)) {
351 if (Glib::file_test (old_config_dir, Glib::FILE_TEST_IS_DIR)) {
352 have_old_configuration_files = true;
358 ARDOUR::handle_old_configuration_files (boost::function<bool (std::string const&, std::string const&, int)> ui_handler)
360 if (have_old_configuration_files) {
361 int current_version = atoi (X_(PROGRAM_VERSION));
362 assert (current_version > 1); // established in check_for_old_configuration_files ()
363 int old_version = current_version - 1;
364 string old_config_dir = user_config_directory (old_version);
365 string current_config_dir = user_config_directory (current_version);
367 if (ui_handler (old_config_dir, current_config_dir, old_version)) {
368 copy_configuration_files (old_config_dir, current_config_dir, old_version);
376 ARDOUR::init (bool use_windows_vst, bool try_optimization, const char* localedir)
378 if (libardour_initialized) {
382 if (!PBD::init()) return false;
385 (void) bindtextdomain(PACKAGE, localedir);
386 (void) bind_textdomain_codeset (PACKAGE, "UTF-8");
389 SessionEvent::init_event_pool ();
391 Operations::make_operations_quarks ();
392 SessionObject::make_property_quarks ();
393 Region::make_property_quarks ();
394 MidiRegion::make_property_quarks ();
395 AudioRegion::make_property_quarks ();
396 RouteGroup::make_property_quarks ();
397 Playlist::make_property_quarks ();
398 AudioPlaylist::make_property_quarks ();
400 /* this is a useful ready to use PropertyChange that many
401 things need to check. This avoids having to compose
402 it every time we want to check for any of the relevant
406 bounds_change.add (ARDOUR::Properties::start);
407 bounds_change.add (ARDOUR::Properties::position);
408 bounds_change.add (ARDOUR::Properties::length);
410 /* provide a state version for the few cases that need it and are not
411 driven by reading state from disk (e.g. undo/redo)
414 Stateful::current_state_version = CURRENT_SESSION_FILE_VERSION;
416 ARDOUR::setup_enum_writer ();
418 // allow ardour the absolute maximum number of open files
419 lotsa_files_please ();
424 Library = new AudioLibrary;
426 BootMessage (_("Loading configuration"));
428 Config = new RCConfiguration;
430 if (Config->load_state ()) {
434 Config->set_use_windows_vst (use_windows_vst);
436 Config->set_use_lxvst(true);
439 Profile = new RuntimeProfile;
442 #ifdef WINDOWS_VST_SUPPORT
443 if (Config->get_use_windows_vst() && fst_init (0)) {
449 if (Config->get_use_lxvst() && vstfx_init (0)) {
454 #ifdef AUDIOUNIT_SUPPORT
455 AUPluginInfo::load_cached_info ();
458 setup_hardware_optimization (try_optimization);
460 SourceFactory::init ();
463 /* singletons - first object is "it" */
464 (void) PluginManager::instance();
466 (void) URIMap::instance();
468 (void) EventTypeMap::instance();
470 ProcessThread::init ();
471 /* the + 4 is a bit of a handwave. i don't actually know
472 how many more per-thread buffer sets we need above
473 the h/w concurrency, but its definitely > 1 more.
475 BufferManager::init (hardware_concurrency() + 4);
477 PannerManager::instance().discover_panners();
479 ARDOUR::AudioEngine::create ();
481 libardour_initialized = true;
487 ARDOUR::init_post_engine ()
489 ControlProtocolManager::instance().discover_control_protocols ();
492 if ((node = Config->control_protocol_state()) != 0) {
493 ControlProtocolManager::instance().set_state (*node, Stateful::loading_state_version);
498 ARDOUR::PluginManager::instance().refresh (!Config->get_discover_vst_on_start());
504 if (!libardour_initialized) {
508 ARDOUR::AudioEngine::destroy ();
514 delete &ControlProtocolManager::instance();
515 #ifdef WINDOWS_VST_SUPPORT
522 delete &PluginManager::instance();
530 ARDOUR::find_bindings_files (map<string,string>& files)
532 vector<std::string> found;
533 Searchpath spath = ardour_config_search_path();
535 if (getenv ("ARDOUR_SAE")) {
536 find_files_matching_pattern (found, spath, "*SAE-*.bindings");
538 find_files_matching_pattern (found, spath, "*.bindings");
545 for (vector<std::string>::iterator x = found.begin(); x != found.end(); ++x) {
546 std::string path(*x);
547 pair<string,string> namepath;
548 namepath.second = path;
549 namepath.first = PBD::basename_nosuffix (path);
550 files.insert (namepath);
555 ARDOUR::no_auto_connect()
557 return getenv ("ARDOUR_NO_AUTOCONNECT") != 0;
564 if (getenv ("ARDOUR_RUNNING_UNDER_VALGRIND")) {
565 // valgrind doesn't understand this assembler stuff
566 // September 10th, 2007
570 #if defined(ARCH_X86) && defined(USE_XMMINTRIN)
575 /* XXX use real code to determine if the processor supports
576 DenormalsAreZero and FlushToZero
579 if (!fpu.has_flush_to_zero() && !fpu.has_denormals_are_zero()) {
583 MXCSR = _mm_getcsr();
585 #ifdef DEBUG_DENORMAL_EXCEPTION
586 /* This will raise a FP exception if a denormal is detected */
587 MXCSR &= ~_MM_MASK_DENORM;
590 switch (Config->get_denormal_model()) {
592 MXCSR &= ~(_MM_FLUSH_ZERO_ON | 0x40);
596 if (fpu.has_flush_to_zero()) {
597 MXCSR |= _MM_FLUSH_ZERO_ON;
602 MXCSR &= ~_MM_FLUSH_ZERO_ON;
603 if (fpu.has_denormals_are_zero()) {
609 if (fpu.has_flush_to_zero()) {
610 if (fpu.has_denormals_are_zero()) {
611 MXCSR |= _MM_FLUSH_ZERO_ON | 0x40;
613 MXCSR |= _MM_FLUSH_ZERO_ON;
624 /* this can be changed to modify the translation behaviour for
625 cases where the user has never expressed a preference.
627 static const bool translate_by_default = true;
630 ARDOUR::translation_enable_path ()
632 return Glib::build_filename (user_config_directory(), ".translate");
636 ARDOUR::translations_are_enabled ()
638 int fd = ::open (ARDOUR::translation_enable_path().c_str(), O_RDONLY);
641 return translate_by_default;
647 if (::read (fd, &c, 1) == 1 && c == '1') {
657 ARDOUR::set_translations_enabled (bool yn)
659 string i18n_enabler = ARDOUR::translation_enable_path();
660 int fd = ::open (i18n_enabler.c_str(), O_WRONLY|O_CREAT|O_TRUNC, 0644);
674 (void) ::write (fd, &c, 1);
682 ARDOUR::get_available_sync_options ()
684 vector<SyncSource> ret;
686 boost::shared_ptr<AudioBackend> backend = AudioEngine::instance()->current_backend();
687 if (backend && backend->name() == "JACK") {
688 ret.push_back (Engine);
692 ret.push_back (MIDIClock);
698 /** Return a monotonic value for the number of microseconds that have elapsed
699 * since an arbitrary zero origin.
703 /* Thanks Apple for not implementing this basic SUSv2, POSIX.1-2001 function
705 #include <mach/mach_time.h>
706 #define CLOCK_REALTIME 0
707 #define CLOCK_MONOTONIC 0
709 clock_gettime (int /*clk_id*/, struct timespec *t)
711 static bool initialized = false;
712 static mach_timebase_info_data_t timebase;
714 mach_timebase_info(&timebase);
718 time = mach_absolute_time();
719 double nseconds = ((double)time * (double)timebase.numer)/((double)timebase.denom);
720 double seconds = ((double)time * (double)timebase.numer)/((double)timebase.denom * 1e9);
722 t->tv_nsec = nseconds;
728 ARDOUR::get_microseconds ()
730 #ifdef PLATFORM_WINDOWS
731 microseconds_t ret = 0;
732 LARGE_INTEGER freq, time;
734 if (QueryPerformanceFrequency(&freq))
735 if (QueryPerformanceCounter(&time))
736 ret = (microseconds_t)((time.QuadPart * 1000000) / freq.QuadPart);
741 if (clock_gettime (CLOCK_MONOTONIC, &ts) != 0) {
745 return (microseconds_t) ts.tv_sec * 1000000 + (ts.tv_nsec/1000);
749 /** Return the number of bits per sample for a given sample format.
751 * This is closely related to sndfile_data_width() but does NOT
752 * return a "magic" value to differentiate between 32 bit integer
753 * and 32 bit floating point values.
757 ARDOUR::format_data_width (ARDOUR::SampleFormat format)
763 case ARDOUR::FormatInt16:
765 case ARDOUR::FormatInt24: