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