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