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<void,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_files (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_files (old_name, new_name);
277 old_name = Glib::build_filename (old_dir, "presets");
278 new_name = Glib::build_filename (new_dir, "presets");
280 copy_files (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 CopyConfigurationFiles (old_config_dir, current_config_dir, version); /* EMIT SIGNAL */
327 ARDOUR::init (bool use_windows_vst, bool try_optimization, const char* localedir)
329 if (libardour_initialized) {
333 if (!PBD::init()) return false;
336 (void) bindtextdomain(PACKAGE, localedir);
337 (void) bind_textdomain_codeset (PACKAGE, "UTF-8");
340 SessionEvent::init_event_pool ();
342 Operations::make_operations_quarks ();
343 SessionObject::make_property_quarks ();
344 Region::make_property_quarks ();
345 MidiRegion::make_property_quarks ();
346 AudioRegion::make_property_quarks ();
347 RouteGroup::make_property_quarks ();
348 Playlist::make_property_quarks ();
349 AudioPlaylist::make_property_quarks ();
351 /* this is a useful ready to use PropertyChange that many
352 things need to check. This avoids having to compose
353 it every time we want to check for any of the relevant
357 bounds_change.add (ARDOUR::Properties::start);
358 bounds_change.add (ARDOUR::Properties::position);
359 bounds_change.add (ARDOUR::Properties::length);
361 /* provide a state version for the few cases that need it and are not
362 driven by reading state from disk (e.g. undo/redo)
365 Stateful::current_state_version = CURRENT_SESSION_FILE_VERSION;
367 ARDOUR::setup_enum_writer ();
369 // allow ardour the absolute maximum number of open files
370 lotsa_files_please ();
372 maybe_copy_old_configuration_files ();
377 Library = new AudioLibrary;
379 BootMessage (_("Loading configuration"));
381 Config = new RCConfiguration;
383 if (Config->load_state ()) {
387 Config->set_use_windows_vst (use_windows_vst);
389 Config->set_use_lxvst(true);
392 Profile = new RuntimeProfile;
395 #ifdef WINDOWS_VST_SUPPORT
396 if (Config->get_use_windows_vst() && fst_init (0)) {
402 if (Config->get_use_lxvst() && vstfx_init (0)) {
407 #ifdef AUDIOUNIT_SUPPORT
408 AUPluginInfo::load_cached_info ();
411 setup_hardware_optimization (try_optimization);
413 SourceFactory::init ();
416 /* singletons - first object is "it" */
417 (void) PluginManager::instance();
419 (void) URIMap::instance();
421 (void) EventTypeMap::instance();
423 ProcessThread::init ();
424 /* the + 4 is a bit of a handwave. i don't actually know
425 how many more per-thread buffer sets we need above
426 the h/w concurrency, but its definitely > 1 more.
428 BufferManager::init (hardware_concurrency() + 4);
430 PannerManager::instance().discover_panners();
432 ARDOUR::AudioEngine::create ();
434 libardour_initialized = true;
440 ARDOUR::init_post_engine ()
442 ControlProtocolManager::instance().discover_control_protocols ();
445 if ((node = Config->control_protocol_state()) != 0) {
446 ControlProtocolManager::instance().set_state (*node, Stateful::loading_state_version);
451 ARDOUR::PluginManager::instance().refresh (!Config->get_discover_vst_on_start());
457 if (!libardour_initialized) {
461 ARDOUR::AudioEngine::destroy ();
467 delete &ControlProtocolManager::instance();
468 #ifdef WINDOWS_VST_SUPPORT
475 delete &PluginManager::instance();
483 ARDOUR::find_bindings_files (map<string,string>& files)
485 vector<std::string> found;
486 Searchpath spath = ardour_config_search_path();
488 if (getenv ("ARDOUR_SAE")) {
489 find_files_matching_pattern (found, spath, "*SAE-*.bindings");
491 find_files_matching_pattern (found, spath, "*.bindings");
498 for (vector<std::string>::iterator x = found.begin(); x != found.end(); ++x) {
499 std::string path(*x);
500 pair<string,string> namepath;
501 namepath.second = path;
502 namepath.first = PBD::basename_nosuffix (path);
503 files.insert (namepath);
508 ARDOUR::no_auto_connect()
510 return getenv ("ARDOUR_NO_AUTOCONNECT") != 0;
517 if (getenv ("ARDOUR_RUNNING_UNDER_VALGRIND")) {
518 // valgrind doesn't understand this assembler stuff
519 // September 10th, 2007
523 #if defined(ARCH_X86) && defined(USE_XMMINTRIN)
528 /* XXX use real code to determine if the processor supports
529 DenormalsAreZero and FlushToZero
532 if (!fpu.has_flush_to_zero() && !fpu.has_denormals_are_zero()) {
536 MXCSR = _mm_getcsr();
538 #ifdef DEBUG_DENORMAL_EXCEPTION
539 /* This will raise a FP exception if a denormal is detected */
540 MXCSR &= ~_MM_MASK_DENORM;
543 switch (Config->get_denormal_model()) {
545 MXCSR &= ~(_MM_FLUSH_ZERO_ON | 0x40);
549 if (fpu.has_flush_to_zero()) {
550 MXCSR |= _MM_FLUSH_ZERO_ON;
555 MXCSR &= ~_MM_FLUSH_ZERO_ON;
556 if (fpu.has_denormals_are_zero()) {
562 if (fpu.has_flush_to_zero()) {
563 if (fpu.has_denormals_are_zero()) {
564 MXCSR |= _MM_FLUSH_ZERO_ON | 0x40;
566 MXCSR |= _MM_FLUSH_ZERO_ON;
577 /* this can be changed to modify the translation behaviour for
578 cases where the user has never expressed a preference.
580 static const bool translate_by_default = true;
583 ARDOUR::translation_enable_path ()
585 return Glib::build_filename (user_config_directory(), ".translate");
589 ARDOUR::translations_are_enabled ()
591 int fd = ::open (ARDOUR::translation_enable_path().c_str(), O_RDONLY);
594 return translate_by_default;
600 if (::read (fd, &c, 1) == 1 && c == '1') {
610 ARDOUR::set_translations_enabled (bool yn)
612 string i18n_enabler = ARDOUR::translation_enable_path();
613 int fd = ::open (i18n_enabler.c_str(), O_WRONLY|O_CREAT|O_TRUNC, 0644);
627 (void) ::write (fd, &c, 1);
635 ARDOUR::get_available_sync_options ()
637 vector<SyncSource> ret;
639 boost::shared_ptr<AudioBackend> backend = AudioEngine::instance()->current_backend();
640 if (backend && backend->name() == "JACK") {
641 ret.push_back (Engine);
645 ret.push_back (MIDIClock);
651 /** Return a monotonic value for the number of microseconds that have elapsed
652 * since an arbitrary zero origin.
656 /* Thanks Apple for not implementing this basic SUSv2, POSIX.1-2001 function
658 #include <mach/mach_time.h>
659 #define CLOCK_REALTIME 0
660 #define CLOCK_MONOTONIC 0
662 clock_gettime (int /*clk_id*/, struct timespec *t)
664 static bool initialized = false;
665 static mach_timebase_info_data_t timebase;
667 mach_timebase_info(&timebase);
671 time = mach_absolute_time();
672 double nseconds = ((double)time * (double)timebase.numer)/((double)timebase.denom);
673 double seconds = ((double)time * (double)timebase.numer)/((double)timebase.denom * 1e9);
675 t->tv_nsec = nseconds;
681 ARDOUR::get_microseconds ()
683 #ifdef PLATFORM_WINDOWS
684 microseconds_t ret = 0;
685 LARGE_INTEGER freq, time;
687 if (QueryPerformanceFrequency(&freq))
688 if (QueryPerformanceCounter(&time))
689 ret = (microseconds_t)((time.QuadPart * 1000000) / freq.QuadPart);
694 if (clock_gettime (CLOCK_MONOTONIC, &ts) != 0) {
698 return (microseconds_t) ts.tv_sec * 1000000 + (ts.tv_nsec/1000);
702 /** Return the number of bits per sample for a given sample format.
704 * This is closely related to sndfile_data_width() but does NOT
705 * return a "magic" value to differentiate between 32 bit integer
706 * and 32 bit floating point values.
710 ARDOUR::format_data_width (ARDOUR::SampleFormat format)
716 case ARDOUR::FormatInt16:
718 case ARDOUR::FormatInt24: