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;
142 extern void setup_enum_writer ();
145 /* this is useful for quite a few things that want to check
146 if any bounds-related property has changed
148 PBD::PropertyChange ARDOUR::bounds_change;
151 setup_hardware_optimization (bool try_optimization)
153 bool generic_mix_functions = true;
155 if (try_optimization) {
159 #if defined (ARCH_X86) && defined (BUILD_SSE_OPTIMIZATIONS)
163 info << "Using SSE optimized routines" << endmsg;
166 compute_peak = x86_sse_compute_peak;
167 find_peaks = x86_sse_find_peaks;
168 apply_gain_to_buffer = x86_sse_apply_gain_to_buffer;
169 mix_buffers_with_gain = x86_sse_mix_buffers_with_gain;
170 mix_buffers_no_gain = x86_sse_mix_buffers_no_gain;
172 generic_mix_functions = false;
176 #elif defined (__APPLE__) && defined (BUILD_VECLIB_OPTIMIZATIONS)
177 SInt32 sysVersion = 0;
179 if (noErr != Gestalt(gestaltSystemVersion, &sysVersion))
182 if (sysVersion >= 0x00001040) { // Tiger at least
183 compute_peak = veclib_compute_peak;
184 find_peaks = veclib_find_peaks;
185 apply_gain_to_buffer = veclib_apply_gain_to_buffer;
186 mix_buffers_with_gain = veclib_mix_buffers_with_gain;
187 mix_buffers_no_gain = veclib_mix_buffers_no_gain;
189 generic_mix_functions = false;
191 info << "Apple VecLib H/W specific optimizations in use" << endmsg;
195 /* consider FPU denormal handling to be "h/w optimization" */
200 if (generic_mix_functions) {
202 compute_peak = default_compute_peak;
203 find_peaks = default_find_peaks;
204 apply_gain_to_buffer = default_apply_gain_to_buffer;
205 mix_buffers_with_gain = default_mix_buffers_with_gain;
206 mix_buffers_no_gain = default_mix_buffers_no_gain;
208 info << "No H/W specific optimizations in use" << endmsg;
211 AudioGrapher::Routines::override_compute_peak (compute_peak);
212 AudioGrapher::Routines::override_apply_gain_to_buffer (apply_gain_to_buffer);
216 lotsa_files_please ()
218 #ifndef PLATFORM_WINDOWS
221 if (getrlimit (RLIMIT_NOFILE, &rl) == 0) {
224 /* See the COMPATIBILITY note on the Apple setrlimit() man page */
225 rl.rlim_cur = min ((rlim_t) OPEN_MAX, rl.rlim_max);
227 rl.rlim_cur = rl.rlim_max;
230 if (setrlimit (RLIMIT_NOFILE, &rl) != 0) {
231 if (rl.rlim_cur == RLIM_INFINITY) {
232 error << _("Could not set system open files limit to \"unlimited\"") << endmsg;
234 error << string_compose (_("Could not set system open files limit to %1"), rl.rlim_cur) << endmsg;
237 if (rl.rlim_cur != RLIM_INFINITY) {
238 info << string_compose (_("Your system is configured to limit %1 to only %2 open files"), PROGRAM_NAME, rl.rlim_cur) << endmsg;
242 error << string_compose (_("Could not get system open files limit (%1)"), strerror (errno)) << endmsg;
248 ARDOUR::copy_configuration_files (string const & old_dir, string const & new_dir, int old_version)
253 if (old_version == 3) {
255 old_name = Glib::build_filename (old_dir, "recent");
256 new_name = Glib::build_filename (new_dir, "recent");
258 copy_file (old_name, new_name);
260 /* can only copy ardour.rc - UI config is not compatible */
262 old_name = Glib::build_filename (old_dir, "ardour.rc");
263 new_name = Glib::build_filename (new_dir, "config");
265 copy_file (old_name, new_name);
267 /* copy templates and route templates */
269 old_name = Glib::build_filename (old_dir, "templates");
270 new_name = Glib::build_filename (new_dir, "templates");
272 copy_recurse (old_name, new_name);
274 old_name = Glib::build_filename (old_dir, "route_templates");
275 new_name = Glib::build_filename (new_dir, "route_templates");
277 copy_recurse (old_name, new_name);
281 old_name = Glib::build_filename (old_dir, "presets");
282 new_name = Glib::build_filename (new_dir, "presets");
284 copy_recurse (old_name, new_name);
288 old_name = Glib::build_filename (old_dir, "plugin_statuses");
289 new_name = Glib::build_filename (new_dir, "plugin_statuses");
291 copy_file (old_name, new_name);
295 old_name = Glib::build_filename (old_dir, export_formats_dir_name);
296 new_name = Glib::build_filename (new_dir, export_formats_dir_name);
298 vector<string> export_formats;
299 g_mkdir_with_parents (Glib::build_filename (new_dir, export_formats_dir_name).c_str(), 0755);
300 find_files_matching_pattern (export_formats, old_name, "*.format");
301 for (vector<string>::iterator i = export_formats.begin(); i != export_formats.end(); ++i) {
302 std::string from = *i;
303 std::string to = Glib::build_filename (new_name, Glib::path_get_basename (*i));
304 copy_file (from, to);
312 maybe_copy_old_configuration_files ()
314 int version = atoi (X_(PROGRAM_VERSION));
322 string old_config_dir = user_config_directory (version);
324 if (Glib::file_test (old_config_dir, Glib::FILE_TEST_IS_DIR)) {
325 string current_config_dir = user_config_directory ();
326 boost::optional<bool> r = CopyConfigurationFiles (old_config_dir, current_config_dir, version); /* EMIT SIGNAL */
329 copy_configuration_files (old_config_dir, current_config_dir, version);
336 ARDOUR::init (bool use_windows_vst, bool try_optimization, const char* localedir)
338 if (libardour_initialized) {
342 if (!PBD::init()) return false;
345 (void) bindtextdomain(PACKAGE, localedir);
346 (void) bind_textdomain_codeset (PACKAGE, "UTF-8");
349 SessionEvent::init_event_pool ();
351 Operations::make_operations_quarks ();
352 SessionObject::make_property_quarks ();
353 Region::make_property_quarks ();
354 MidiRegion::make_property_quarks ();
355 AudioRegion::make_property_quarks ();
356 RouteGroup::make_property_quarks ();
357 Playlist::make_property_quarks ();
358 AudioPlaylist::make_property_quarks ();
360 /* this is a useful ready to use PropertyChange that many
361 things need to check. This avoids having to compose
362 it every time we want to check for any of the relevant
366 bounds_change.add (ARDOUR::Properties::start);
367 bounds_change.add (ARDOUR::Properties::position);
368 bounds_change.add (ARDOUR::Properties::length);
370 /* provide a state version for the few cases that need it and are not
371 driven by reading state from disk (e.g. undo/redo)
374 Stateful::current_state_version = CURRENT_SESSION_FILE_VERSION;
376 ARDOUR::setup_enum_writer ();
378 // allow ardour the absolute maximum number of open files
379 lotsa_files_please ();
381 maybe_copy_old_configuration_files ();
386 Library = new AudioLibrary;
388 BootMessage (_("Loading configuration"));
390 Config = new RCConfiguration;
392 if (Config->load_state ()) {
396 Config->set_use_windows_vst (use_windows_vst);
398 Config->set_use_lxvst(true);
401 Profile = new RuntimeProfile;
404 #ifdef WINDOWS_VST_SUPPORT
405 if (Config->get_use_windows_vst() && fst_init (0)) {
411 if (Config->get_use_lxvst() && vstfx_init (0)) {
416 #ifdef AUDIOUNIT_SUPPORT
417 AUPluginInfo::load_cached_info ();
420 setup_hardware_optimization (try_optimization);
422 SourceFactory::init ();
425 /* singletons - first object is "it" */
426 (void) PluginManager::instance();
428 (void) URIMap::instance();
430 (void) EventTypeMap::instance();
432 ProcessThread::init ();
433 /* the + 4 is a bit of a handwave. i don't actually know
434 how many more per-thread buffer sets we need above
435 the h/w concurrency, but its definitely > 1 more.
437 BufferManager::init (hardware_concurrency() + 4);
439 PannerManager::instance().discover_panners();
441 ARDOUR::AudioEngine::create ();
443 libardour_initialized = true;
449 ARDOUR::init_post_engine ()
451 ControlProtocolManager::instance().discover_control_protocols ();
454 if ((node = Config->control_protocol_state()) != 0) {
455 ControlProtocolManager::instance().set_state (*node, Stateful::loading_state_version);
460 ARDOUR::PluginManager::instance().refresh (!Config->get_discover_vst_on_start());
466 if (!libardour_initialized) {
470 ARDOUR::AudioEngine::destroy ();
476 delete &ControlProtocolManager::instance();
477 #ifdef WINDOWS_VST_SUPPORT
484 delete &PluginManager::instance();
492 ARDOUR::find_bindings_files (map<string,string>& files)
494 vector<std::string> found;
495 Searchpath spath = ardour_config_search_path();
497 if (getenv ("ARDOUR_SAE")) {
498 find_files_matching_pattern (found, spath, "*SAE-*.bindings");
500 find_files_matching_pattern (found, spath, "*.bindings");
507 for (vector<std::string>::iterator x = found.begin(); x != found.end(); ++x) {
508 std::string path(*x);
509 pair<string,string> namepath;
510 namepath.second = path;
511 namepath.first = PBD::basename_nosuffix (path);
512 files.insert (namepath);
517 ARDOUR::no_auto_connect()
519 return getenv ("ARDOUR_NO_AUTOCONNECT") != 0;
526 if (getenv ("ARDOUR_RUNNING_UNDER_VALGRIND")) {
527 // valgrind doesn't understand this assembler stuff
528 // September 10th, 2007
532 #if defined(ARCH_X86) && defined(USE_XMMINTRIN)
537 /* XXX use real code to determine if the processor supports
538 DenormalsAreZero and FlushToZero
541 if (!fpu.has_flush_to_zero() && !fpu.has_denormals_are_zero()) {
545 MXCSR = _mm_getcsr();
547 #ifdef DEBUG_DENORMAL_EXCEPTION
548 /* This will raise a FP exception if a denormal is detected */
549 MXCSR &= ~_MM_MASK_DENORM;
552 switch (Config->get_denormal_model()) {
554 MXCSR &= ~(_MM_FLUSH_ZERO_ON | 0x40);
558 if (fpu.has_flush_to_zero()) {
559 MXCSR |= _MM_FLUSH_ZERO_ON;
564 MXCSR &= ~_MM_FLUSH_ZERO_ON;
565 if (fpu.has_denormals_are_zero()) {
571 if (fpu.has_flush_to_zero()) {
572 if (fpu.has_denormals_are_zero()) {
573 MXCSR |= _MM_FLUSH_ZERO_ON | 0x40;
575 MXCSR |= _MM_FLUSH_ZERO_ON;
586 /* this can be changed to modify the translation behaviour for
587 cases where the user has never expressed a preference.
589 static const bool translate_by_default = true;
592 ARDOUR::translation_enable_path ()
594 return Glib::build_filename (user_config_directory(), ".translate");
598 ARDOUR::translations_are_enabled ()
600 int fd = ::open (ARDOUR::translation_enable_path().c_str(), O_RDONLY);
603 return translate_by_default;
609 if (::read (fd, &c, 1) == 1 && c == '1') {
619 ARDOUR::set_translations_enabled (bool yn)
621 string i18n_enabler = ARDOUR::translation_enable_path();
622 int fd = ::open (i18n_enabler.c_str(), O_WRONLY|O_CREAT|O_TRUNC, 0644);
636 (void) ::write (fd, &c, 1);
644 ARDOUR::get_available_sync_options ()
646 vector<SyncSource> ret;
648 boost::shared_ptr<AudioBackend> backend = AudioEngine::instance()->current_backend();
649 if (backend && backend->name() == "JACK") {
650 ret.push_back (Engine);
654 ret.push_back (MIDIClock);
660 /** Return a monotonic value for the number of microseconds that have elapsed
661 * since an arbitrary zero origin.
665 /* Thanks Apple for not implementing this basic SUSv2, POSIX.1-2001 function
667 #include <mach/mach_time.h>
668 #define CLOCK_REALTIME 0
669 #define CLOCK_MONOTONIC 0
671 clock_gettime (int /*clk_id*/, struct timespec *t)
673 static bool initialized = false;
674 static mach_timebase_info_data_t timebase;
676 mach_timebase_info(&timebase);
680 time = mach_absolute_time();
681 double nseconds = ((double)time * (double)timebase.numer)/((double)timebase.denom);
682 double seconds = ((double)time * (double)timebase.numer)/((double)timebase.denom * 1e9);
684 t->tv_nsec = nseconds;
690 ARDOUR::get_microseconds ()
692 #ifdef PLATFORM_WINDOWS
693 microseconds_t ret = 0;
694 LARGE_INTEGER freq, time;
696 if (QueryPerformanceFrequency(&freq))
697 if (QueryPerformanceCounter(&time))
698 ret = (microseconds_t)((time.QuadPart * 1000000) / freq.QuadPart);
703 if (clock_gettime (CLOCK_MONOTONIC, &ts) != 0) {
707 return (microseconds_t) ts.tv_sec * 1000000 + (ts.tv_nsec/1000);
711 /** Return the number of bits per sample for a given sample format.
713 * This is closely related to sndfile_data_width() but does NOT
714 * return a "magic" value to differentiate between 32 bit integer
715 * and 32 bit floating point values.
719 ARDOUR::format_data_width (ARDOUR::SampleFormat format)
725 case ARDOUR::FormatInt16:
727 case ARDOUR::FormatInt24: