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 copy_configuration_files (string const & old_dir, string const & new_dir, int old_version)
253 /* ensure target directory exists */
255 if (g_mkdir_with_parents (new_dir.c_str(), 0755)) {
259 if (old_version == 3) {
261 old_name = Glib::build_filename (old_dir, X_("recent"));
262 new_name = Glib::build_filename (new_dir, X_("recent"));
264 copy_file (old_name, new_name);
266 /* can only copy ardour.rc - UI config is not compatible */
268 old_name = Glib::build_filename (old_dir, X_("ardour.rc"));
269 new_name = Glib::build_filename (new_dir, X_("config"));
271 copy_file (old_name, new_name);
273 /* copy templates and route templates */
275 old_name = Glib::build_filename (old_dir, X_("templates"));
276 new_name = Glib::build_filename (new_dir, X_("templates"));
278 copy_recurse (old_name, new_name);
280 old_name = Glib::build_filename (old_dir, X_("route_templates"));
281 new_name = Glib::build_filename (new_dir, X_("route_templates"));
283 copy_recurse (old_name, new_name);
287 old_name = Glib::build_filename (old_dir, X_("presets"));
288 new_name = Glib::build_filename (new_dir, X_("presets"));
290 copy_recurse (old_name, new_name);
294 old_name = Glib::build_filename (old_dir, X_("plugin_statuses"));
295 new_name = Glib::build_filename (new_dir, X_("plugin_statuses"));
297 copy_file (old_name, new_name);
301 old_name = Glib::build_filename (old_dir, export_formats_dir_name);
302 new_name = Glib::build_filename (new_dir, export_formats_dir_name);
304 vector<string> export_formats;
305 g_mkdir_with_parents (Glib::build_filename (new_dir, export_formats_dir_name).c_str(), 0755);
306 find_files_matching_pattern (export_formats, old_name, X_("*.format"));
307 for (vector<string>::iterator i = export_formats.begin(); i != export_formats.end(); ++i) {
308 std::string from = *i;
309 std::string to = Glib::build_filename (new_name, Glib::path_get_basename (*i));
310 copy_file (from, to);
318 ARDOUR::check_for_old_configuration_files (boost::function<bool (std::string const&, std::string const&, int)> ui_handler)
320 int current_version = atoi (X_(PROGRAM_VERSION));
322 if (current_version <= 1) {
326 int old_version = current_version - 1;
328 string old_config_dir = user_config_directory (old_version);
329 /* pass in the current version explicitly to avoid creation */
330 string current_config_dir = user_config_directory (current_version);
332 if (!Glib::file_test (current_config_dir, Glib::FILE_TEST_IS_DIR)) {
333 if (Glib::file_test (old_config_dir, Glib::FILE_TEST_IS_DIR)) {
335 if (ui_handler (old_config_dir, current_config_dir, old_version)) {
336 copy_configuration_files (old_config_dir, current_config_dir, old_version);
346 ARDOUR::init (bool use_windows_vst, bool try_optimization, const char* localedir)
348 if (libardour_initialized) {
352 if (!PBD::init()) return false;
355 (void) bindtextdomain(PACKAGE, localedir);
356 (void) bind_textdomain_codeset (PACKAGE, "UTF-8");
359 SessionEvent::init_event_pool ();
361 Operations::make_operations_quarks ();
362 SessionObject::make_property_quarks ();
363 Region::make_property_quarks ();
364 MidiRegion::make_property_quarks ();
365 AudioRegion::make_property_quarks ();
366 RouteGroup::make_property_quarks ();
367 Playlist::make_property_quarks ();
368 AudioPlaylist::make_property_quarks ();
370 /* this is a useful ready to use PropertyChange that many
371 things need to check. This avoids having to compose
372 it every time we want to check for any of the relevant
376 bounds_change.add (ARDOUR::Properties::start);
377 bounds_change.add (ARDOUR::Properties::position);
378 bounds_change.add (ARDOUR::Properties::length);
380 /* provide a state version for the few cases that need it and are not
381 driven by reading state from disk (e.g. undo/redo)
384 Stateful::current_state_version = CURRENT_SESSION_FILE_VERSION;
386 ARDOUR::setup_enum_writer ();
388 // allow ardour the absolute maximum number of open files
389 lotsa_files_please ();
394 Library = new AudioLibrary;
396 BootMessage (_("Loading configuration"));
398 Config = new RCConfiguration;
400 if (Config->load_state ()) {
404 Config->set_use_windows_vst (use_windows_vst);
406 Config->set_use_lxvst(true);
409 Profile = new RuntimeProfile;
412 #ifdef WINDOWS_VST_SUPPORT
413 if (Config->get_use_windows_vst() && fst_init (0)) {
419 if (Config->get_use_lxvst() && vstfx_init (0)) {
424 #ifdef AUDIOUNIT_SUPPORT
425 AUPluginInfo::load_cached_info ();
428 setup_hardware_optimization (try_optimization);
430 SourceFactory::init ();
433 /* singletons - first object is "it" */
434 (void) PluginManager::instance();
436 (void) URIMap::instance();
438 (void) EventTypeMap::instance();
440 ProcessThread::init ();
441 /* the + 4 is a bit of a handwave. i don't actually know
442 how many more per-thread buffer sets we need above
443 the h/w concurrency, but its definitely > 1 more.
445 BufferManager::init (hardware_concurrency() + 4);
447 PannerManager::instance().discover_panners();
449 ARDOUR::AudioEngine::create ();
451 libardour_initialized = true;
457 ARDOUR::init_post_engine ()
459 ControlProtocolManager::instance().discover_control_protocols ();
462 if ((node = Config->control_protocol_state()) != 0) {
463 ControlProtocolManager::instance().set_state (*node, Stateful::loading_state_version);
468 ARDOUR::PluginManager::instance().refresh (!Config->get_discover_vst_on_start());
474 if (!libardour_initialized) {
478 ARDOUR::AudioEngine::destroy ();
484 delete &ControlProtocolManager::instance();
485 #ifdef WINDOWS_VST_SUPPORT
492 delete &PluginManager::instance();
500 ARDOUR::find_bindings_files (map<string,string>& files)
502 vector<std::string> found;
503 Searchpath spath = ardour_config_search_path();
505 if (getenv ("ARDOUR_SAE")) {
506 find_files_matching_pattern (found, spath, "*SAE-*.bindings");
508 find_files_matching_pattern (found, spath, "*.bindings");
515 for (vector<std::string>::iterator x = found.begin(); x != found.end(); ++x) {
516 std::string path(*x);
517 pair<string,string> namepath;
518 namepath.second = path;
519 namepath.first = PBD::basename_nosuffix (path);
520 files.insert (namepath);
525 ARDOUR::no_auto_connect()
527 return getenv ("ARDOUR_NO_AUTOCONNECT") != 0;
534 if (getenv ("ARDOUR_RUNNING_UNDER_VALGRIND")) {
535 // valgrind doesn't understand this assembler stuff
536 // September 10th, 2007
540 #if defined(ARCH_X86) && defined(USE_XMMINTRIN)
545 /* XXX use real code to determine if the processor supports
546 DenormalsAreZero and FlushToZero
549 if (!fpu.has_flush_to_zero() && !fpu.has_denormals_are_zero()) {
553 MXCSR = _mm_getcsr();
555 #ifdef DEBUG_DENORMAL_EXCEPTION
556 /* This will raise a FP exception if a denormal is detected */
557 MXCSR &= ~_MM_MASK_DENORM;
560 switch (Config->get_denormal_model()) {
562 MXCSR &= ~(_MM_FLUSH_ZERO_ON | 0x40);
566 if (fpu.has_flush_to_zero()) {
567 MXCSR |= _MM_FLUSH_ZERO_ON;
572 MXCSR &= ~_MM_FLUSH_ZERO_ON;
573 if (fpu.has_denormals_are_zero()) {
579 if (fpu.has_flush_to_zero()) {
580 if (fpu.has_denormals_are_zero()) {
581 MXCSR |= _MM_FLUSH_ZERO_ON | 0x40;
583 MXCSR |= _MM_FLUSH_ZERO_ON;
594 /* this can be changed to modify the translation behaviour for
595 cases where the user has never expressed a preference.
597 static const bool translate_by_default = true;
600 ARDOUR::translation_enable_path ()
602 return Glib::build_filename (user_config_directory(), ".translate");
606 ARDOUR::translations_are_enabled ()
608 int fd = ::open (ARDOUR::translation_enable_path().c_str(), O_RDONLY);
611 return translate_by_default;
617 if (::read (fd, &c, 1) == 1 && c == '1') {
627 ARDOUR::set_translations_enabled (bool yn)
629 string i18n_enabler = ARDOUR::translation_enable_path();
630 int fd = ::open (i18n_enabler.c_str(), O_WRONLY|O_CREAT|O_TRUNC, 0644);
644 (void) ::write (fd, &c, 1);
652 ARDOUR::get_available_sync_options ()
654 vector<SyncSource> ret;
656 boost::shared_ptr<AudioBackend> backend = AudioEngine::instance()->current_backend();
657 if (backend && backend->name() == "JACK") {
658 ret.push_back (Engine);
662 ret.push_back (MIDIClock);
668 /** Return a monotonic value for the number of microseconds that have elapsed
669 * since an arbitrary zero origin.
673 /* Thanks Apple for not implementing this basic SUSv2, POSIX.1-2001 function
675 #include <mach/mach_time.h>
676 #define CLOCK_REALTIME 0
677 #define CLOCK_MONOTONIC 0
679 clock_gettime (int /*clk_id*/, struct timespec *t)
681 static bool initialized = false;
682 static mach_timebase_info_data_t timebase;
684 mach_timebase_info(&timebase);
688 time = mach_absolute_time();
689 double nseconds = ((double)time * (double)timebase.numer)/((double)timebase.denom);
690 double seconds = ((double)time * (double)timebase.numer)/((double)timebase.denom * 1e9);
692 t->tv_nsec = nseconds;
698 ARDOUR::get_microseconds ()
700 #ifdef PLATFORM_WINDOWS
701 microseconds_t ret = 0;
702 LARGE_INTEGER freq, time;
704 if (QueryPerformanceFrequency(&freq))
705 if (QueryPerformanceCounter(&time))
706 ret = (microseconds_t)((time.QuadPart * 1000000) / freq.QuadPart);
711 if (clock_gettime (CLOCK_MONOTONIC, &ts) != 0) {
715 return (microseconds_t) ts.tv_sec * 1000000 + (ts.tv_nsec/1000);
719 /** Return the number of bits per sample for a given sample format.
721 * This is closely related to sndfile_data_width() but does NOT
722 * return a "magic" value to differentiate between 32 bit integer
723 * and 32 bit floating point values.
727 ARDOUR::format_data_width (ARDOUR::SampleFormat format)
733 case ARDOUR::FormatInt16:
735 case ARDOUR::FormatInt24: