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"
23 #include <cstdio> // Needed so that libraptor (included in lrdf) won't complain
25 #include <sys/types.h>
27 #include <sys/resource.h>
32 #ifdef WINDOWS_VST_SUPPORT
37 #include "ardour/linux_vst_support.h"
40 #ifdef AUDIOUNIT_SUPPORT
41 #include "ardour/audio_unit.h"
45 #include <xmmintrin.h>
50 #include <glibmm/fileutils.h>
51 #include <glibmm/miscutils.h>
55 #include "pbd/error.h"
57 #include "pbd/strsplit.h"
59 #include "pbd/file_utils.h"
60 #include "pbd/enumwriter.h"
61 #include "pbd/basename.h"
63 #include "midi++/port.h"
64 #include "midi++/manager.h"
65 #include "midi++/mmc.h"
67 #include "ardour/analyser.h"
68 #include "ardour/audio_library.h"
69 #include "ardour/audioengine.h"
70 #include "ardour/audioplaylist.h"
71 #include "ardour/audioregion.h"
72 #include "ardour/buffer_manager.h"
73 #include "ardour/control_protocol_manager.h"
74 #include "ardour/filesystem_paths.h"
75 #include "ardour/midi_region.h"
76 #include "ardour/mix.h"
77 #include "ardour/panner_manager.h"
78 #include "ardour/plugin_manager.h"
79 #include "ardour/process_thread.h"
80 #include "ardour/profile.h"
81 #include "ardour/rc_configuration.h"
82 #include "ardour/region.h"
83 #include "ardour/route_group.h"
84 #include "ardour/runtime_functions.h"
85 #include "ardour/session_event.h"
86 #include "ardour/source_factory.h"
88 #include "audiographer/routines.h"
90 #if defined (__APPLE__)
91 #include <Carbon/Carbon.h> // For Gestalt
96 ARDOUR::RCConfiguration* ARDOUR::Config = 0;
97 ARDOUR::RuntimeProfile* ARDOUR::Profile = 0;
98 ARDOUR::AudioLibrary* ARDOUR::Library = 0;
100 using namespace ARDOUR;
104 compute_peak_t ARDOUR::compute_peak = 0;
105 find_peaks_t ARDOUR::find_peaks = 0;
106 apply_gain_to_buffer_t ARDOUR::apply_gain_to_buffer = 0;
107 mix_buffers_with_gain_t ARDOUR::mix_buffers_with_gain = 0;
108 mix_buffers_no_gain_t ARDOUR::mix_buffers_no_gain = 0;
110 PBD::Signal1<void,std::string> ARDOUR::BootMessage;
113 extern void setup_enum_writer ();
116 /* this is useful for quite a few things that want to check
117 if any bounds-related property has changed
119 PBD::PropertyChange ARDOUR::bounds_change;
122 setup_hardware_optimization (bool try_optimization)
124 bool generic_mix_functions = true;
126 if (try_optimization) {
130 #if defined (ARCH_X86) && defined (BUILD_SSE_OPTIMIZATIONS)
134 info << "Using SSE optimized routines" << endmsg;
137 compute_peak = x86_sse_compute_peak;
138 find_peaks = x86_sse_find_peaks;
139 apply_gain_to_buffer = x86_sse_apply_gain_to_buffer;
140 // mix_buffers_with_gain = x86_sse_mix_buffers_with_gain;
141 mix_buffers_with_gain = default_mix_buffers_with_gain;
142 mix_buffers_no_gain = x86_sse_mix_buffers_no_gain;
144 generic_mix_functions = false;
148 #elif defined (__APPLE__) && defined (BUILD_VECLIB_OPTIMIZATIONS)
149 SInt32 sysVersion = 0;
151 if (noErr != Gestalt(gestaltSystemVersion, &sysVersion))
154 if (sysVersion >= 0x00001040) { // Tiger at least
155 compute_peak = veclib_compute_peak;
156 find_peaks = veclib_find_peaks;
157 apply_gain_to_buffer = veclib_apply_gain_to_buffer;
158 mix_buffers_with_gain = veclib_mix_buffers_with_gain;
159 mix_buffers_no_gain = veclib_mix_buffers_no_gain;
161 generic_mix_functions = false;
163 info << "Apple VecLib H/W specific optimizations in use" << endmsg;
167 /* consider FPU denormal handling to be "h/w optimization" */
172 if (generic_mix_functions) {
174 compute_peak = default_compute_peak;
175 find_peaks = default_find_peaks;
176 apply_gain_to_buffer = default_apply_gain_to_buffer;
177 mix_buffers_with_gain = default_mix_buffers_with_gain;
178 mix_buffers_no_gain = default_mix_buffers_no_gain;
180 info << "No H/W specific optimizations in use" << endmsg;
183 AudioGrapher::Routines::override_compute_peak (compute_peak);
184 AudioGrapher::Routines::override_apply_gain_to_buffer (apply_gain_to_buffer);
188 lotsa_files_please ()
192 if (getrlimit (RLIMIT_NOFILE, &rl) == 0) {
194 rl.rlim_cur = rl.rlim_max;
196 if (setrlimit (RLIMIT_NOFILE, &rl) != 0) {
197 if (rl.rlim_cur == RLIM_INFINITY) {
198 error << _("Could not set system open files limit to \"unlimited\"") << endmsg;
200 error << string_compose (_("Could not set system open files limit to %1"), rl.rlim_cur) << endmsg;
203 if (rl.rlim_cur == RLIM_INFINITY) {
204 info << _("Removed open file count limit. Excellent!") << endmsg;
206 info << string_compose (_("%1 will be limited to %2 open files"), PROGRAM_NAME, rl.rlim_cur) << endmsg;
210 error << string_compose (_("Could not get system open files limit (%1)"), strerror (errno)) << endmsg;
215 ARDOUR::init (bool use_windows_vst, bool try_optimization)
217 if (!Glib::thread_supported()) {
221 // this really should be in PBD::init..if there was one
224 (void) bindtextdomain(PACKAGE, LOCALEDIR);
227 SessionEvent::init_event_pool ();
229 SessionObject::make_property_quarks ();
230 Region::make_property_quarks ();
231 MidiRegion::make_property_quarks ();
232 AudioRegion::make_property_quarks ();
233 RouteGroup::make_property_quarks ();
234 Playlist::make_property_quarks ();
235 AudioPlaylist::make_property_quarks ();
237 /* this is a useful ready to use PropertyChange that many
238 things need to check. This avoids having to compose
239 it every time we want to check for any of the relevant
243 bounds_change.add (ARDOUR::Properties::start);
244 bounds_change.add (ARDOUR::Properties::position);
245 bounds_change.add (ARDOUR::Properties::length);
247 /* provide a state version for the few cases that need it and are not
248 driven by reading state from disk (e.g. undo/redo)
251 Stateful::current_state_version = CURRENT_SESSION_FILE_VERSION;
253 ARDOUR::setup_enum_writer ();
255 // allow ardour the absolute maximum number of open files
256 lotsa_files_please ();
259 Library = new AudioLibrary;
261 BootMessage (_("Loading configuration"));
263 Config = new RCConfiguration;
265 if (Config->load_state ()) {
269 Config->set_use_windows_vst (use_windows_vst);
271 Config->set_use_lxvst(true);
274 Profile = new RuntimeProfile;
277 #ifdef WINDOWS_VST_SUPPORT
278 if (Config->get_use_windows_vst() && fst_init (0)) {
284 if (Config->get_use_lxvst() && vstfx_init (0)) {
289 #ifdef AUDIOUNIT_SUPPORT
290 AUPluginInfo::load_cached_info ();
293 setup_hardware_optimization (try_optimization);
295 SourceFactory::init ();
298 /* singleton - first object is "it" */
299 (void) PluginManager::instance();
301 ProcessThread::init ();
302 BufferManager::init (10); // XX should be num_processors_for_dsp + 1 for the GUI thread
304 PannerManager::instance().discover_panners();
306 // Initialize parameter metadata
307 EventTypeMap::instance().new_parameter(NullAutomation);
308 EventTypeMap::instance().new_parameter(GainAutomation);
309 EventTypeMap::instance().new_parameter(PanAzimuthAutomation);
310 EventTypeMap::instance().new_parameter(PanElevationAutomation);
311 EventTypeMap::instance().new_parameter(PanWidthAutomation);
312 EventTypeMap::instance().new_parameter(PluginAutomation);
313 EventTypeMap::instance().new_parameter(SoloAutomation);
314 EventTypeMap::instance().new_parameter(MuteAutomation);
315 EventTypeMap::instance().new_parameter(MidiCCAutomation);
316 EventTypeMap::instance().new_parameter(MidiPgmChangeAutomation);
317 EventTypeMap::instance().new_parameter(MidiPitchBenderAutomation);
318 EventTypeMap::instance().new_parameter(MidiChannelPressureAutomation);
319 EventTypeMap::instance().new_parameter(FadeInAutomation);
320 EventTypeMap::instance().new_parameter(FadeOutAutomation);
321 EventTypeMap::instance().new_parameter(EnvelopeAutomation);
322 EventTypeMap::instance().new_parameter(MidiCCAutomation);
328 ARDOUR::init_post_engine ()
330 /* the MIDI Manager is needed by the ControlProtocolManager */
331 MIDI::Manager::create (AudioEngine::instance()->jack());
333 ControlProtocolManager::instance().discover_control_protocols ();
336 if ((node = Config->control_protocol_state()) != 0) {
337 ControlProtocolManager::instance().set_state (*node, Stateful::loading_state_version);
342 ARDOUR::PluginManager::instance().refresh ();
350 delete &ControlProtocolManager::instance();
351 #ifdef WINDOWS_VST_SUPPORT
358 EnumWriter::destroy ();
363 ARDOUR::find_bindings_files (map<string,string>& files)
365 vector<std::string> found;
366 SearchPath spath = ardour_config_search_path();
368 if (getenv ("ARDOUR_SAE")) {
369 Glib::PatternSpec pattern("*SAE-*.bindings");
370 find_matching_files_in_search_path (spath, pattern, found);
372 Glib::PatternSpec pattern("*.bindings");
373 find_matching_files_in_search_path (spath, pattern, found);
380 for (vector<std::string>::iterator x = found.begin(); x != found.end(); ++x) {
381 std::string path(*x);
382 pair<string,string> namepath;
383 namepath.second = path;
384 namepath.first = PBD::basename_nosuffix (path);
385 files.insert (namepath);
390 ARDOUR::no_auto_connect()
392 return getenv ("ARDOUR_NO_AUTOCONNECT") != 0;
399 if (getenv ("ARDOUR_RUNNING_UNDER_VALGRIND")) {
400 // valgrind doesn't understand this assembler stuff
401 // September 10th, 2007
405 #if defined(ARCH_X86) && defined(USE_XMMINTRIN)
410 /* XXX use real code to determine if the processor supports
411 DenormalsAreZero and FlushToZero
414 if (!fpu.has_flush_to_zero() && !fpu.has_denormals_are_zero()) {
418 MXCSR = _mm_getcsr();
420 #ifdef DEBUG_DENORMAL_EXCEPTION
421 /* This will raise a FP exception if a denormal is detected */
422 MXCSR &= ~_MM_MASK_DENORM;
425 switch (Config->get_denormal_model()) {
427 MXCSR &= ~(_MM_FLUSH_ZERO_ON | 0x40);
431 if (fpu.has_flush_to_zero()) {
432 MXCSR |= _MM_FLUSH_ZERO_ON;
437 MXCSR &= ~_MM_FLUSH_ZERO_ON;
438 if (fpu.has_denormals_are_zero()) {
444 if (fpu.has_flush_to_zero()) {
445 if (fpu.has_denormals_are_zero()) {
446 MXCSR |= _MM_FLUSH_ZERO_ON | 0x40;
448 MXCSR |= _MM_FLUSH_ZERO_ON;
460 ARDOUR::translation_kill_path ()
462 return Glib::build_filename (user_config_directory(), ".love_is_the_language_of_audio");
466 ARDOUR::translations_are_disabled ()
468 /* if file does not exist, we don't translate (bundled ardour only) */
469 return Glib::file_test (translation_kill_path(), Glib::FILE_TEST_EXISTS) == false;