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 WINDOWS_VST_SUPPORT
45 #include "ardour/linux_vst_support.h"
48 #ifdef AUDIOUNIT_SUPPORT
49 #include "ardour/audio_unit.h"
52 #if defined(__SSE__) || defined(USE_XMMINTRIN)
53 #include <xmmintrin.h>
57 #undef check /* stupid Apple and their un-namespaced, generic Carbon macros */
60 #include <glibmm/fileutils.h>
61 #include <glibmm/miscutils.h>
68 #include "pbd/error.h"
71 #include "pbd/strsplit.h"
73 #include "pbd/file_utils.h"
74 #include "pbd/enumwriter.h"
75 #include "pbd/basename.h"
77 #include "midi++/port.h"
78 #include "midi++/mmc.h"
80 #include "ardour/analyser.h"
81 #include "ardour/audio_library.h"
82 #include "ardour/audio_backend.h"
83 #include "ardour/audioengine.h"
84 #include "ardour/audioplaylist.h"
85 #include "ardour/audioregion.h"
86 #include "ardour/buffer_manager.h"
87 #include "ardour/control_protocol_manager.h"
88 #include "ardour/directory_names.h"
89 #include "ardour/event_type_map.h"
90 #include "ardour/filesystem_paths.h"
91 #include "ardour/midi_region.h"
92 #include "ardour/midiport_manager.h"
93 #include "ardour/mix.h"
94 #include "ardour/operations.h"
95 #include "ardour/panner_manager.h"
96 #include "ardour/plugin_manager.h"
97 #include "ardour/process_thread.h"
98 #include "ardour/profile.h"
99 #include "ardour/rc_configuration.h"
100 #include "ardour/region.h"
101 #include "ardour/route_group.h"
102 #include "ardour/runtime_functions.h"
103 #include "ardour/session_event.h"
104 #include "ardour/source_factory.h"
105 #include "ardour/uri_map.h"
107 #include "audiographer/routines.h"
109 #if defined (__APPLE__)
110 #include <Carbon/Carbon.h> // For Gestalt
115 ARDOUR::RCConfiguration* ARDOUR::Config = 0;
116 ARDOUR::RuntimeProfile* ARDOUR::Profile = 0;
117 ARDOUR::AudioLibrary* ARDOUR::Library = 0;
119 using namespace ARDOUR;
123 bool libardour_initialized = false;
125 compute_peak_t ARDOUR::compute_peak = 0;
126 find_peaks_t ARDOUR::find_peaks = 0;
127 apply_gain_to_buffer_t ARDOUR::apply_gain_to_buffer = 0;
128 mix_buffers_with_gain_t ARDOUR::mix_buffers_with_gain = 0;
129 mix_buffers_no_gain_t ARDOUR::mix_buffers_no_gain = 0;
131 PBD::Signal1<void,std::string> ARDOUR::BootMessage;
132 PBD::Signal3<void,std::string,std::string,bool> ARDOUR::PluginScanMessage;
133 PBD::Signal1<void,int> ARDOUR::PluginScanTimeout;
134 PBD::Signal0<void> ARDOUR::GUIIdle;
135 PBD::Signal3<bool,std::string,std::string,int> ARDOUR::CopyConfigurationFiles;
138 extern void setup_enum_writer ();
141 /* this is useful for quite a few things that want to check
142 if any bounds-related property has changed
144 PBD::PropertyChange ARDOUR::bounds_change;
147 setup_hardware_optimization (bool try_optimization)
149 bool generic_mix_functions = true;
151 if (try_optimization) {
155 #if defined (ARCH_X86) && defined (BUILD_SSE_OPTIMIZATIONS)
159 info << "Using SSE optimized routines" << endmsg;
162 compute_peak = x86_sse_compute_peak;
163 find_peaks = x86_sse_find_peaks;
164 apply_gain_to_buffer = x86_sse_apply_gain_to_buffer;
165 mix_buffers_with_gain = x86_sse_mix_buffers_with_gain;
166 mix_buffers_no_gain = x86_sse_mix_buffers_no_gain;
168 generic_mix_functions = false;
172 #elif defined (__APPLE__) && defined (BUILD_VECLIB_OPTIMIZATIONS)
173 SInt32 sysVersion = 0;
175 if (noErr != Gestalt(gestaltSystemVersion, &sysVersion))
178 if (sysVersion >= 0x00001040) { // Tiger at least
179 compute_peak = veclib_compute_peak;
180 find_peaks = veclib_find_peaks;
181 apply_gain_to_buffer = veclib_apply_gain_to_buffer;
182 mix_buffers_with_gain = veclib_mix_buffers_with_gain;
183 mix_buffers_no_gain = veclib_mix_buffers_no_gain;
185 generic_mix_functions = false;
187 info << "Apple VecLib H/W specific optimizations in use" << endmsg;
191 /* consider FPU denormal handling to be "h/w optimization" */
196 if (generic_mix_functions) {
198 compute_peak = default_compute_peak;
199 find_peaks = default_find_peaks;
200 apply_gain_to_buffer = default_apply_gain_to_buffer;
201 mix_buffers_with_gain = default_mix_buffers_with_gain;
202 mix_buffers_no_gain = default_mix_buffers_no_gain;
204 info << "No H/W specific optimizations in use" << endmsg;
207 AudioGrapher::Routines::override_compute_peak (compute_peak);
208 AudioGrapher::Routines::override_apply_gain_to_buffer (apply_gain_to_buffer);
212 lotsa_files_please ()
214 #ifndef PLATFORM_WINDOWS
217 if (getrlimit (RLIMIT_NOFILE, &rl) == 0) {
220 /* See the COMPATIBILITY note on the Apple setrlimit() man page */
221 rl.rlim_cur = min ((rlim_t) OPEN_MAX, rl.rlim_max);
223 rl.rlim_cur = rl.rlim_max;
226 if (setrlimit (RLIMIT_NOFILE, &rl) != 0) {
227 if (rl.rlim_cur == RLIM_INFINITY) {
228 error << _("Could not set system open files limit to \"unlimited\"") << endmsg;
230 error << string_compose (_("Could not set system open files limit to %1"), rl.rlim_cur) << endmsg;
233 if (rl.rlim_cur != RLIM_INFINITY) {
234 info << string_compose (_("Your system is configured to limit %1 to only %2 open files"), PROGRAM_NAME, rl.rlim_cur) << endmsg;
238 error << string_compose (_("Could not get system open files limit (%1)"), strerror (errno)) << endmsg;
244 ARDOUR::copy_configuration_files (string const & old_dir, string const & new_dir, int old_version)
249 if (old_version == 3) {
251 old_name = Glib::build_filename (old_dir, "recent");
252 new_name = Glib::build_filename (new_dir, "recent");
254 copy_file (old_name, new_name);
256 /* can only copy ardour.rc - UI config is not compatible */
258 old_name = Glib::build_filename (old_dir, "ardour.rc");
259 new_name = Glib::build_filename (new_dir, "config");
261 copy_file (old_name, new_name);
263 /* copy templates and route templates */
265 old_name = Glib::build_filename (old_dir, "templates");
266 new_name = Glib::build_filename (new_dir, "templates");
268 copy_recurse (old_name, new_name);
270 old_name = Glib::build_filename (old_dir, "route_templates");
271 new_name = Glib::build_filename (new_dir, "route_templates");
273 copy_recurse (old_name, new_name);
277 old_name = Glib::build_filename (old_dir, "presets");
278 new_name = Glib::build_filename (new_dir, "presets");
280 copy_recurse (old_name, new_name);
284 old_name = Glib::build_filename (old_dir, "plugin_statuses");
285 new_name = Glib::build_filename (new_dir, "plugin_statuses");
287 copy_file (old_name, new_name);
291 old_name = Glib::build_filename (old_dir, export_formats_dir_name);
292 new_name = Glib::build_filename (new_dir, export_formats_dir_name);
294 vector<string> export_formats;
295 g_mkdir_with_parents (Glib::build_filename (new_dir, export_formats_dir_name).c_str(), 0755);
296 find_files_matching_pattern (export_formats, old_name, "*.format");
297 for (vector<string>::iterator i = export_formats.begin(); i != export_formats.end(); ++i) {
298 std::string from = *i;
299 std::string to = Glib::build_filename (new_name, Glib::path_get_basename (*i));
300 copy_file (from, to);
308 maybe_copy_old_configuration_files ()
310 int version = atoi (X_(PROGRAM_VERSION));
318 string old_config_dir = user_config_directory (version);
320 if (Glib::file_test (old_config_dir, Glib::FILE_TEST_IS_DIR)) {
321 string current_config_dir = user_config_directory ();
322 boost::optional<bool> r = CopyConfigurationFiles (old_config_dir, current_config_dir, version); /* EMIT SIGNAL */
325 copy_configuration_files (old_config_dir, current_config_dir, version);
332 ARDOUR::init (bool use_windows_vst, bool try_optimization, const char* localedir)
334 if (libardour_initialized) {
338 if (!PBD::init()) return false;
341 (void) bindtextdomain(PACKAGE, localedir);
342 (void) bind_textdomain_codeset (PACKAGE, "UTF-8");
345 SessionEvent::init_event_pool ();
347 Operations::make_operations_quarks ();
348 SessionObject::make_property_quarks ();
349 Region::make_property_quarks ();
350 MidiRegion::make_property_quarks ();
351 AudioRegion::make_property_quarks ();
352 RouteGroup::make_property_quarks ();
353 Playlist::make_property_quarks ();
354 AudioPlaylist::make_property_quarks ();
356 /* this is a useful ready to use PropertyChange that many
357 things need to check. This avoids having to compose
358 it every time we want to check for any of the relevant
362 bounds_change.add (ARDOUR::Properties::start);
363 bounds_change.add (ARDOUR::Properties::position);
364 bounds_change.add (ARDOUR::Properties::length);
366 /* provide a state version for the few cases that need it and are not
367 driven by reading state from disk (e.g. undo/redo)
370 Stateful::current_state_version = CURRENT_SESSION_FILE_VERSION;
372 ARDOUR::setup_enum_writer ();
374 // allow ardour the absolute maximum number of open files
375 lotsa_files_please ();
377 maybe_copy_old_configuration_files ();
382 Library = new AudioLibrary;
384 BootMessage (_("Loading configuration"));
386 Config = new RCConfiguration;
388 if (Config->load_state ()) {
392 Config->set_use_windows_vst (use_windows_vst);
394 Config->set_use_lxvst(true);
397 Profile = new RuntimeProfile;
400 #ifdef WINDOWS_VST_SUPPORT
401 if (Config->get_use_windows_vst() && fst_init (0)) {
407 if (Config->get_use_lxvst() && vstfx_init (0)) {
412 #ifdef AUDIOUNIT_SUPPORT
413 AUPluginInfo::load_cached_info ();
416 setup_hardware_optimization (try_optimization);
418 SourceFactory::init ();
421 /* singletons - first object is "it" */
422 (void) PluginManager::instance();
424 (void) URIMap::instance();
426 (void) EventTypeMap::instance();
428 ProcessThread::init ();
429 /* the + 4 is a bit of a handwave. i don't actually know
430 how many more per-thread buffer sets we need above
431 the h/w concurrency, but its definitely > 1 more.
433 BufferManager::init (hardware_concurrency() + 4);
435 PannerManager::instance().discover_panners();
437 ARDOUR::AudioEngine::create ();
439 libardour_initialized = true;
445 ARDOUR::init_post_engine ()
447 ControlProtocolManager::instance().discover_control_protocols ();
450 if ((node = Config->control_protocol_state()) != 0) {
451 ControlProtocolManager::instance().set_state (*node, Stateful::loading_state_version);
456 ARDOUR::PluginManager::instance().refresh (!Config->get_discover_vst_on_start());
462 if (!libardour_initialized) {
466 ARDOUR::AudioEngine::destroy ();
472 delete &ControlProtocolManager::instance();
473 #ifdef WINDOWS_VST_SUPPORT
480 delete &PluginManager::instance();
488 ARDOUR::find_bindings_files (map<string,string>& files)
490 vector<std::string> found;
491 Searchpath spath = ardour_config_search_path();
493 if (getenv ("ARDOUR_SAE")) {
494 find_files_matching_pattern (found, spath, "*SAE-*.bindings");
496 find_files_matching_pattern (found, spath, "*.bindings");
503 for (vector<std::string>::iterator x = found.begin(); x != found.end(); ++x) {
504 std::string path(*x);
505 pair<string,string> namepath;
506 namepath.second = path;
507 namepath.first = PBD::basename_nosuffix (path);
508 files.insert (namepath);
513 ARDOUR::no_auto_connect()
515 return getenv ("ARDOUR_NO_AUTOCONNECT") != 0;
522 if (getenv ("ARDOUR_RUNNING_UNDER_VALGRIND")) {
523 // valgrind doesn't understand this assembler stuff
524 // September 10th, 2007
528 #if defined(ARCH_X86) && defined(USE_XMMINTRIN)
533 /* XXX use real code to determine if the processor supports
534 DenormalsAreZero and FlushToZero
537 if (!fpu.has_flush_to_zero() && !fpu.has_denormals_are_zero()) {
541 MXCSR = _mm_getcsr();
543 #ifdef DEBUG_DENORMAL_EXCEPTION
544 /* This will raise a FP exception if a denormal is detected */
545 MXCSR &= ~_MM_MASK_DENORM;
548 switch (Config->get_denormal_model()) {
550 MXCSR &= ~(_MM_FLUSH_ZERO_ON | 0x40);
554 if (fpu.has_flush_to_zero()) {
555 MXCSR |= _MM_FLUSH_ZERO_ON;
560 MXCSR &= ~_MM_FLUSH_ZERO_ON;
561 if (fpu.has_denormals_are_zero()) {
567 if (fpu.has_flush_to_zero()) {
568 if (fpu.has_denormals_are_zero()) {
569 MXCSR |= _MM_FLUSH_ZERO_ON | 0x40;
571 MXCSR |= _MM_FLUSH_ZERO_ON;
582 /* this can be changed to modify the translation behaviour for
583 cases where the user has never expressed a preference.
585 static const bool translate_by_default = true;
588 ARDOUR::translation_enable_path ()
590 return Glib::build_filename (user_config_directory(), ".translate");
594 ARDOUR::translations_are_enabled ()
596 int fd = ::open (ARDOUR::translation_enable_path().c_str(), O_RDONLY);
599 return translate_by_default;
605 if (::read (fd, &c, 1) == 1 && c == '1') {
615 ARDOUR::set_translations_enabled (bool yn)
617 string i18n_enabler = ARDOUR::translation_enable_path();
618 int fd = ::open (i18n_enabler.c_str(), O_WRONLY|O_CREAT|O_TRUNC, 0644);
632 (void) ::write (fd, &c, 1);
640 ARDOUR::get_available_sync_options ()
642 vector<SyncSource> ret;
644 boost::shared_ptr<AudioBackend> backend = AudioEngine::instance()->current_backend();
645 if (backend && backend->name() == "JACK") {
646 ret.push_back (Engine);
650 ret.push_back (MIDIClock);
656 /** Return a monotonic value for the number of microseconds that have elapsed
657 * since an arbitrary zero origin.
661 /* Thanks Apple for not implementing this basic SUSv2, POSIX.1-2001 function
663 #include <mach/mach_time.h>
664 #define CLOCK_REALTIME 0
665 #define CLOCK_MONOTONIC 0
667 clock_gettime (int /*clk_id*/, struct timespec *t)
669 static bool initialized = false;
670 static mach_timebase_info_data_t timebase;
672 mach_timebase_info(&timebase);
676 time = mach_absolute_time();
677 double nseconds = ((double)time * (double)timebase.numer)/((double)timebase.denom);
678 double seconds = ((double)time * (double)timebase.numer)/((double)timebase.denom * 1e9);
680 t->tv_nsec = nseconds;
686 ARDOUR::get_microseconds ()
688 #ifdef PLATFORM_WINDOWS
689 microseconds_t ret = 0;
690 LARGE_INTEGER freq, time;
692 if (QueryPerformanceFrequency(&freq))
693 if (QueryPerformanceCounter(&time))
694 ret = (microseconds_t)((time.QuadPart * 1000000) / freq.QuadPart);
699 if (clock_gettime (CLOCK_MONOTONIC, &ts) != 0) {
703 return (microseconds_t) ts.tv_sec * 1000000 + (ts.tv_nsec/1000);
707 /** Return the number of bits per sample for a given sample format.
709 * This is closely related to sndfile_data_width() but does NOT
710 * return a "magic" value to differentiate between 32 bit integer
711 * and 32 bit floating point values.
715 ARDOUR::format_data_width (ARDOUR::SampleFormat format)
721 case ARDOUR::FormatInt16:
723 case ARDOUR::FormatInt24: