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