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