visibility macros and flush() added to SrcFileSource; merge with master
[ardour.git] / libs / ardour / globals.cc
1 /*
2     Copyright (C) 2000 Paul Davis
3
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.
8
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.
13
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.
17 */
18
19 #ifdef WAF_BUILD
20 #include "libardour-config.h"
21 #endif
22
23 #ifdef interface
24 #undef interface
25 #endif
26
27 #include <cstdio> // Needed so that libraptor (included in lrdf) won't complain
28 #include <cstdlib>
29 #include <sys/stat.h>
30 #include <sys/types.h>
31 #include <sys/time.h>
32 #ifndef PLATFORM_WINDOWS
33 #include <sys/resource.h>
34 #endif
35 #include <unistd.h>
36 #include <fcntl.h>
37 #include <errno.h>
38 #include <time.h>
39
40 #ifdef WINDOWS_VST_SUPPORT
41 #include <fst.h>
42 #endif
43
44 #ifdef LXVST_SUPPORT
45 #include "ardour/linux_vst_support.h"
46 #endif
47
48 #ifdef AUDIOUNIT_SUPPORT
49 #include "ardour/audio_unit.h"
50 #endif
51
52 #if defined(__SSE__) || defined(USE_XMMINTRIN)
53 #include <xmmintrin.h>
54 #endif
55
56 #ifdef check
57 #undef check /* stupid Apple and their un-namespaced, generic Carbon macros */
58 #endif 
59
60 #include <glibmm/fileutils.h>
61 #include <glibmm/miscutils.h>
62
63 #ifdef HAVE_LRDF
64 #include <lrdf.h>
65 #endif
66
67 #include "pbd/cpus.h"
68 #include "pbd/error.h"
69 #include "pbd/id.h"
70 #include "pbd/pbd.h"
71 #include "pbd/strsplit.h"
72 #include "pbd/fpu.h"
73 #include "pbd/file_utils.h"
74 #include "pbd/enumwriter.h"
75 #include "pbd/basename.h"
76
77 #include "midi++/port.h"
78 #include "midi++/mmc.h"
79
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/filesystem_paths.h"
89 #include "ardour/midi_region.h"
90 #include "ardour/midiport_manager.h"
91 #include "ardour/mix.h"
92 #include "ardour/panner_manager.h"
93 #include "ardour/plugin_manager.h"
94 #include "ardour/process_thread.h"
95 #include "ardour/profile.h"
96 #include "ardour/rc_configuration.h"
97 #include "ardour/region.h"
98 #include "ardour/route_group.h"
99 #include "ardour/runtime_functions.h"
100 #include "ardour/session_event.h"
101 #include "ardour/source_factory.h"
102
103 #include "audiographer/routines.h"
104
105 #if defined (__APPLE__)
106        #include <Carbon/Carbon.h> // For Gestalt
107 #endif
108
109 #include "i18n.h"
110
111 ARDOUR::RCConfiguration* ARDOUR::Config = 0;
112 ARDOUR::RuntimeProfile* ARDOUR::Profile = 0;
113 ARDOUR::AudioLibrary* ARDOUR::Library = 0;
114
115 using namespace ARDOUR;
116 using namespace std;
117 using namespace PBD;
118
119 bool libardour_initialized = false;
120
121 compute_peak_t          ARDOUR::compute_peak = 0;
122 find_peaks_t            ARDOUR::find_peaks = 0;
123 apply_gain_to_buffer_t  ARDOUR::apply_gain_to_buffer = 0;
124 mix_buffers_with_gain_t ARDOUR::mix_buffers_with_gain = 0;
125 mix_buffers_no_gain_t   ARDOUR::mix_buffers_no_gain = 0;
126
127 PBD::Signal1<void,std::string> ARDOUR::BootMessage;
128 PBD::Signal0<void> ARDOUR::GUIIdle;
129
130 namespace ARDOUR {
131 extern void setup_enum_writer ();
132 }
133
134 /* this is useful for quite a few things that want to check
135    if any bounds-related property has changed
136 */
137 PBD::PropertyChange ARDOUR::bounds_change;
138
139 void
140 setup_hardware_optimization (bool try_optimization)
141 {
142         bool generic_mix_functions = true;
143
144         if (try_optimization) {
145
146                 FPU fpu;
147
148 #if defined (ARCH_X86) && defined (BUILD_SSE_OPTIMIZATIONS)
149
150                 if (fpu.has_sse()) {
151
152                         info << "Using SSE optimized routines" << endmsg;
153
154                         // SSE SET
155                         compute_peak          = x86_sse_compute_peak;
156                         find_peaks            = x86_sse_find_peaks;
157                         apply_gain_to_buffer  = x86_sse_apply_gain_to_buffer;
158                         mix_buffers_with_gain = x86_sse_mix_buffers_with_gain;
159                         mix_buffers_no_gain   = x86_sse_mix_buffers_no_gain;
160
161                         generic_mix_functions = false;
162
163                 }
164
165 #elif defined (__APPLE__) && defined (BUILD_VECLIB_OPTIMIZATIONS)
166                 SInt32 sysVersion = 0;
167
168                 if (noErr != Gestalt(gestaltSystemVersion, &sysVersion))
169                         sysVersion = 0;
170
171                 if (sysVersion >= 0x00001040) { // Tiger at least
172                         compute_peak           = veclib_compute_peak;
173                         find_peaks             = veclib_find_peaks;
174                         apply_gain_to_buffer   = veclib_apply_gain_to_buffer;
175                         mix_buffers_with_gain  = veclib_mix_buffers_with_gain;
176                         mix_buffers_no_gain    = veclib_mix_buffers_no_gain;
177
178                         generic_mix_functions = false;
179
180                         info << "Apple VecLib H/W specific optimizations in use" << endmsg;
181                 }
182 #endif
183
184                 /* consider FPU denormal handling to be "h/w optimization" */
185
186                 setup_fpu ();
187         }
188
189         if (generic_mix_functions) {
190
191                 compute_peak          = default_compute_peak;
192                 find_peaks            = default_find_peaks;
193                 apply_gain_to_buffer  = default_apply_gain_to_buffer;
194                 mix_buffers_with_gain = default_mix_buffers_with_gain;
195                 mix_buffers_no_gain   = default_mix_buffers_no_gain;
196
197                 info << "No H/W specific optimizations in use" << endmsg;
198         }
199
200         AudioGrapher::Routines::override_compute_peak (compute_peak);
201         AudioGrapher::Routines::override_apply_gain_to_buffer (apply_gain_to_buffer);
202 }
203
204 static void
205 lotsa_files_please ()
206 {
207 #ifndef PLATFORM_WINDOWS
208         struct rlimit rl;
209
210         if (getrlimit (RLIMIT_NOFILE, &rl) == 0) {
211
212                 rl.rlim_cur = rl.rlim_max;
213
214                 if (setrlimit (RLIMIT_NOFILE, &rl) != 0) {
215                         if (rl.rlim_cur == RLIM_INFINITY) {
216                                 error << _("Could not set system open files limit to \"unlimited\"") << endmsg;
217                         } else {
218                                 error << string_compose (_("Could not set system open files limit to %1"), rl.rlim_cur) << endmsg;
219                         }
220                 } else {
221                         if (rl.rlim_cur != RLIM_INFINITY) {
222                                 info << string_compose (_("Your system is configured to limit %1 to only %2 open files"), PROGRAM_NAME, rl.rlim_cur) << endmsg;
223                         }
224                 }
225         } else {
226                 error << string_compose (_("Could not get system open files limit (%1)"), strerror (errno)) << endmsg;
227         }
228 #endif
229 }
230
231 bool
232 ARDOUR::init (bool use_windows_vst, bool try_optimization, const char* localedir)
233 {
234         if (libardour_initialized) {
235                 return true;
236         }
237
238         if (!PBD::init()) return false;
239
240 #ifdef ENABLE_NLS
241         (void) bindtextdomain(PACKAGE, localedir);
242 #endif
243
244         SessionEvent::init_event_pool ();
245
246         SessionObject::make_property_quarks ();
247         Region::make_property_quarks ();
248         MidiRegion::make_property_quarks ();
249         AudioRegion::make_property_quarks ();
250         RouteGroup::make_property_quarks ();
251         Playlist::make_property_quarks ();
252         AudioPlaylist::make_property_quarks ();
253
254         /* this is a useful ready to use PropertyChange that many
255            things need to check. This avoids having to compose
256            it every time we want to check for any of the relevant
257            property changes.
258         */
259
260         bounds_change.add (ARDOUR::Properties::start);
261         bounds_change.add (ARDOUR::Properties::position);
262         bounds_change.add (ARDOUR::Properties::length);
263
264         /* provide a state version for the few cases that need it and are not
265            driven by reading state from disk (e.g. undo/redo)
266         */
267
268         Stateful::current_state_version = CURRENT_SESSION_FILE_VERSION;
269
270         ARDOUR::setup_enum_writer ();
271
272         // allow ardour the absolute maximum number of open files
273         lotsa_files_please ();
274
275 #ifdef HAVE_LRDF
276         lrdf_init();
277 #endif
278         Library = new AudioLibrary;
279
280         BootMessage (_("Loading configuration"));
281
282         Config = new RCConfiguration;
283
284         if (Config->load_state ()) {
285                 return false;
286         }
287
288         Config->set_use_windows_vst (use_windows_vst);
289 #ifdef LXVST_SUPPORT
290         Config->set_use_lxvst(true);
291 #endif
292
293         Profile = new RuntimeProfile;
294
295
296 #ifdef WINDOWS_VST_SUPPORT
297         if (Config->get_use_windows_vst() && fst_init (0)) {
298                 return false;
299         }
300 #endif
301
302 #ifdef LXVST_SUPPORT
303         if (Config->get_use_lxvst() && vstfx_init (0)) {
304                 return false;
305         }
306 #endif
307
308 #ifdef AUDIOUNIT_SUPPORT
309         AUPluginInfo::load_cached_info ();
310 #endif
311
312         setup_hardware_optimization (try_optimization);
313
314         SourceFactory::init ();
315         Analyser::init ();
316
317         /* singleton - first object is "it" */
318         (void) PluginManager::instance();
319
320         ProcessThread::init ();
321         /* the + 4 is a bit of a handwave. i don't actually know
322            how many more per-thread buffer sets we need above
323            the h/w concurrency, but its definitely > 1 more.
324         */
325         BufferManager::init (hardware_concurrency() + 4); 
326
327         PannerManager::instance().discover_panners();
328
329         // Initialize parameter metadata
330         EventTypeMap::instance().new_parameter(NullAutomation);
331         EventTypeMap::instance().new_parameter(GainAutomation);
332         EventTypeMap::instance().new_parameter(PanAzimuthAutomation);
333         EventTypeMap::instance().new_parameter(PanElevationAutomation);
334         EventTypeMap::instance().new_parameter(PanWidthAutomation);
335         EventTypeMap::instance().new_parameter(PluginAutomation);
336         EventTypeMap::instance().new_parameter(SoloAutomation);
337         EventTypeMap::instance().new_parameter(MuteAutomation);
338         EventTypeMap::instance().new_parameter(MidiCCAutomation);
339         EventTypeMap::instance().new_parameter(MidiPgmChangeAutomation);
340         EventTypeMap::instance().new_parameter(MidiPitchBenderAutomation);
341         EventTypeMap::instance().new_parameter(MidiChannelPressureAutomation);
342         EventTypeMap::instance().new_parameter(FadeInAutomation);
343         EventTypeMap::instance().new_parameter(FadeOutAutomation);
344         EventTypeMap::instance().new_parameter(EnvelopeAutomation);
345         EventTypeMap::instance().new_parameter(MidiCCAutomation);
346
347         ARDOUR::AudioEngine::create ();
348
349         libardour_initialized = true;
350
351         return true;
352 }
353
354 void
355 ARDOUR::init_post_engine ()
356 {
357         ControlProtocolManager::instance().discover_control_protocols ();
358
359         XMLNode* node;
360         if ((node = Config->control_protocol_state()) != 0) {
361                 ControlProtocolManager::instance().set_state (*node, Stateful::loading_state_version);
362         }
363
364         /* find plugins */
365
366         ARDOUR::PluginManager::instance().refresh ();
367 }
368
369 void
370 ARDOUR::cleanup () 
371 {
372         if (!libardour_initialized) {
373                 return;
374         }
375
376         ARDOUR::AudioEngine::destroy ();
377
378         delete Library;
379 #ifdef HAVE_LRDF
380         lrdf_cleanup ();
381 #endif
382         delete &ControlProtocolManager::instance();
383 #ifdef WINDOWS_VST_SUPPORT
384         fst_exit ();
385 #endif
386
387 #ifdef LXVST_SUPPORT
388         vstfx_exit();
389 #endif
390         PBD::cleanup ();
391
392         return;
393 }
394
395 void
396 ARDOUR::find_bindings_files (map<string,string>& files)
397 {
398         vector<std::string> found;
399         Searchpath spath = ardour_config_search_path();
400
401         if (getenv ("ARDOUR_SAE")) {
402                 Glib::PatternSpec pattern("*SAE-*.bindings");
403                 find_matching_files_in_search_path (spath, pattern, found);
404         } else {
405                 Glib::PatternSpec pattern("*.bindings");
406                 find_matching_files_in_search_path (spath, pattern, found);
407         }
408
409         if (found.empty()) {
410                 return;
411         }
412
413         for (vector<std::string>::iterator x = found.begin(); x != found.end(); ++x) {
414                 std::string path(*x);
415                 pair<string,string> namepath;
416                 namepath.second = path;
417                 namepath.first = PBD::basename_nosuffix (path);
418                 files.insert (namepath);
419         }
420 }
421
422 bool
423 ARDOUR::no_auto_connect()
424 {
425         return getenv ("ARDOUR_NO_AUTOCONNECT") != 0;
426 }
427
428 void
429 ARDOUR::setup_fpu ()
430 {
431
432         if (getenv ("ARDOUR_RUNNING_UNDER_VALGRIND")) {
433                 // valgrind doesn't understand this assembler stuff
434                 // September 10th, 2007
435                 return;
436         }
437
438 #if defined(ARCH_X86) && defined(USE_XMMINTRIN)
439
440         int MXCSR;
441         FPU fpu;
442
443         /* XXX use real code to determine if the processor supports
444            DenormalsAreZero and FlushToZero
445         */
446
447         if (!fpu.has_flush_to_zero() && !fpu.has_denormals_are_zero()) {
448                 return;
449         }
450
451         MXCSR  = _mm_getcsr();
452
453 #ifdef DEBUG_DENORMAL_EXCEPTION
454         /* This will raise a FP exception if a denormal is detected */
455         MXCSR &= ~_MM_MASK_DENORM;
456 #endif  
457
458         switch (Config->get_denormal_model()) {
459         case DenormalNone:
460                 MXCSR &= ~(_MM_FLUSH_ZERO_ON | 0x40);
461                 break;
462
463         case DenormalFTZ:
464                 if (fpu.has_flush_to_zero()) {
465                         MXCSR |= _MM_FLUSH_ZERO_ON;
466                 }
467                 break;
468
469         case DenormalDAZ:
470                 MXCSR &= ~_MM_FLUSH_ZERO_ON;
471                 if (fpu.has_denormals_are_zero()) {
472                         MXCSR |= 0x40;
473                 }
474                 break;
475
476         case DenormalFTZDAZ:
477                 if (fpu.has_flush_to_zero()) {
478                         if (fpu.has_denormals_are_zero()) {
479                                 MXCSR |= _MM_FLUSH_ZERO_ON | 0x40;
480                         } else {
481                                 MXCSR |= _MM_FLUSH_ZERO_ON;
482                         }
483                 }
484                 break;
485         }
486
487         _mm_setcsr (MXCSR);
488
489 #endif
490 }
491
492 /* this can be changed to modify the translation behaviour for
493    cases where the user has never expressed a preference.
494 */
495 static const bool translate_by_default = true;
496
497 string
498 ARDOUR::translation_enable_path ()
499 {
500         return Glib::build_filename (user_config_directory(), ".translate");
501 }
502
503 bool
504 ARDOUR::translations_are_enabled ()
505 {
506         int fd = ::open (ARDOUR::translation_enable_path().c_str(), O_RDONLY);
507
508         if (fd < 0) {
509                 return translate_by_default;
510         }
511
512         char c;
513         bool ret = false;
514
515         if (::read (fd, &c, 1) == 1 && c == '1') {
516                 ret = true;
517         }
518
519         ::close (fd);
520
521         return ret;
522 }
523
524 bool
525 ARDOUR::set_translations_enabled (bool yn)
526 {
527         string i18n_enabler = ARDOUR::translation_enable_path();
528         int fd = ::open (i18n_enabler.c_str(), O_WRONLY|O_CREAT|O_TRUNC, 0644);
529
530         if (fd < 0) {
531                 return false;
532         }
533         
534         char c;
535         
536         if (yn) {
537                 c = '1';
538         } else {
539                 c = '0';
540         }
541         
542         (void) ::write (fd, &c, 1);
543         (void) ::close (fd);
544
545         return true;
546 }
547
548
549 vector<SyncSource>
550 ARDOUR::get_available_sync_options ()
551 {
552         vector<SyncSource> ret;
553
554         boost::shared_ptr<AudioBackend> backend = AudioEngine::instance()->current_backend();
555         if (backend && backend->name() == "JACK") {
556                 ret.push_back (Engine);
557         }
558
559         ret.push_back (MTC);
560         ret.push_back (MIDIClock);
561         ret.push_back (LTC);
562
563         return ret;
564 }
565
566 /** Return a monotonic value for the number of microseconds that have elapsed
567  * since an arbitrary zero origin.
568  */
569
570 #ifdef __MACH__
571 /* Thanks Apple for not implementing this basic SUSv2, POSIX.1-2001 function
572  */
573 #include <mach/mach_time.h>
574 #define CLOCK_REALTIME 0
575 #define CLOCK_MONOTONIC 0
576 int 
577 clock_gettime (int /*clk_id*/, struct timespec *t)
578 {
579         static bool initialized = false;
580         static mach_timebase_info_data_t timebase;
581         if (!initialized) {
582                 mach_timebase_info(&timebase);
583                 initialized = true;
584         }
585         uint64_t time;
586         time = mach_absolute_time();
587         double nseconds = ((double)time * (double)timebase.numer)/((double)timebase.denom);
588         double seconds = ((double)time * (double)timebase.numer)/((double)timebase.denom * 1e9);
589         t->tv_sec = seconds;
590         t->tv_nsec = nseconds;
591         return 0;
592 }
593 #endif
594  
595 microseconds_t
596 ARDOUR::get_microseconds ()
597 {
598 #ifdef PLATFORM_WINDOWS
599         microseconds_t ret = 0;
600         LARGE_INTEGER freq, time;
601
602         if (QueryPerformanceFrequency(&freq))
603                 if (QueryPerformanceCounter(&time))
604                         ret = (microseconds_t)((time.QuadPart * 1000000) / freq.QuadPart);
605
606         return ret;
607 #else
608         struct timespec ts;
609         if (clock_gettime (CLOCK_MONOTONIC, &ts) != 0) {
610                 /* EEEK! */
611                 return 0;
612         }
613         return (microseconds_t) ts.tv_sec * 1000000 + (ts.tv_nsec/1000);
614 #endif
615 }