finish (?) infrastructure for copying configuration files from a3 to a4
[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<bool,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_recurse (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_recurse (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_recurse (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                 boost::optional<bool> r = CopyConfigurationFiles (old_config_dir, current_config_dir, version); /* EMIT SIGNAL */
323                 if (r) {
324                         if (r.get()) {
325                                 copy_configuration_files (old_config_dir, current_config_dir, version);
326                         }
327                 }
328         }
329 }
330
331 bool
332 ARDOUR::init (bool use_windows_vst, bool try_optimization, const char* localedir)
333 {
334         if (libardour_initialized) {
335                 return true;
336         }
337
338         if (!PBD::init()) return false;
339
340 #ifdef ENABLE_NLS
341         (void) bindtextdomain(PACKAGE, localedir);
342         (void) bind_textdomain_codeset (PACKAGE, "UTF-8");
343 #endif
344
345         SessionEvent::init_event_pool ();
346
347         Operations::make_operations_quarks ();
348         SessionObject::make_property_quarks ();
349         Region::make_property_quarks ();
350         MidiRegion::make_property_quarks ();
351         AudioRegion::make_property_quarks ();
352         RouteGroup::make_property_quarks ();
353         Playlist::make_property_quarks ();
354         AudioPlaylist::make_property_quarks ();
355
356         /* this is a useful ready to use PropertyChange that many
357            things need to check. This avoids having to compose
358            it every time we want to check for any of the relevant
359            property changes.
360         */
361
362         bounds_change.add (ARDOUR::Properties::start);
363         bounds_change.add (ARDOUR::Properties::position);
364         bounds_change.add (ARDOUR::Properties::length);
365
366         /* provide a state version for the few cases that need it and are not
367            driven by reading state from disk (e.g. undo/redo)
368         */
369
370         Stateful::current_state_version = CURRENT_SESSION_FILE_VERSION;
371
372         ARDOUR::setup_enum_writer ();
373
374         // allow ardour the absolute maximum number of open files
375         lotsa_files_please ();
376
377         maybe_copy_old_configuration_files ();
378         
379 #ifdef HAVE_LRDF
380         lrdf_init();
381 #endif
382         Library = new AudioLibrary;
383
384         BootMessage (_("Loading configuration"));
385
386         Config = new RCConfiguration;
387
388         if (Config->load_state ()) {
389                 return false;
390         }
391
392         Config->set_use_windows_vst (use_windows_vst);
393 #ifdef LXVST_SUPPORT
394         Config->set_use_lxvst(true);
395 #endif
396
397         Profile = new RuntimeProfile;
398
399
400 #ifdef WINDOWS_VST_SUPPORT
401         if (Config->get_use_windows_vst() && fst_init (0)) {
402                 return false;
403         }
404 #endif
405
406 #ifdef LXVST_SUPPORT
407         if (Config->get_use_lxvst() && vstfx_init (0)) {
408                 return false;
409         }
410 #endif
411
412 #ifdef AUDIOUNIT_SUPPORT
413         AUPluginInfo::load_cached_info ();
414 #endif
415
416         setup_hardware_optimization (try_optimization);
417
418         SourceFactory::init ();
419         Analyser::init ();
420
421         /* singletons - first object is "it" */
422         (void) PluginManager::instance();
423 #ifdef LV2_SUPPORT
424         (void) URIMap::instance();
425 #endif
426         (void) EventTypeMap::instance();
427
428         ProcessThread::init ();
429         /* the + 4 is a bit of a handwave. i don't actually know
430            how many more per-thread buffer sets we need above
431            the h/w concurrency, but its definitely > 1 more.
432         */
433         BufferManager::init (hardware_concurrency() + 4); 
434
435         PannerManager::instance().discover_panners();
436
437         ARDOUR::AudioEngine::create ();
438
439         libardour_initialized = true;
440
441         return true;
442 }
443
444 void
445 ARDOUR::init_post_engine ()
446 {
447         ControlProtocolManager::instance().discover_control_protocols ();
448
449         XMLNode* node;
450         if ((node = Config->control_protocol_state()) != 0) {
451                 ControlProtocolManager::instance().set_state (*node, Stateful::loading_state_version);
452         }
453
454         /* find plugins */
455
456         ARDOUR::PluginManager::instance().refresh (!Config->get_discover_vst_on_start());
457 }
458
459 void
460 ARDOUR::cleanup () 
461 {
462         if (!libardour_initialized) {
463                 return;
464         }
465
466         ARDOUR::AudioEngine::destroy ();
467
468         delete Library;
469 #ifdef HAVE_LRDF
470         lrdf_cleanup ();
471 #endif
472         delete &ControlProtocolManager::instance();
473 #ifdef WINDOWS_VST_SUPPORT
474         fst_exit ();
475 #endif
476
477 #ifdef LXVST_SUPPORT
478         vstfx_exit();
479 #endif
480         delete &PluginManager::instance();
481         delete Config;
482         PBD::cleanup ();
483
484         return;
485 }
486
487 void
488 ARDOUR::find_bindings_files (map<string,string>& files)
489 {
490         vector<std::string> found;
491         Searchpath spath = ardour_config_search_path();
492
493         if (getenv ("ARDOUR_SAE")) {
494                 find_files_matching_pattern (found, spath, "*SAE-*.bindings");
495         } else {
496                 find_files_matching_pattern (found, spath, "*.bindings");
497         }
498
499         if (found.empty()) {
500                 return;
501         }
502
503         for (vector<std::string>::iterator x = found.begin(); x != found.end(); ++x) {
504                 std::string path(*x);
505                 pair<string,string> namepath;
506                 namepath.second = path;
507                 namepath.first = PBD::basename_nosuffix (path);
508                 files.insert (namepath);
509         }
510 }
511
512 bool
513 ARDOUR::no_auto_connect()
514 {
515         return getenv ("ARDOUR_NO_AUTOCONNECT") != 0;
516 }
517
518 void
519 ARDOUR::setup_fpu ()
520 {
521
522         if (getenv ("ARDOUR_RUNNING_UNDER_VALGRIND")) {
523                 // valgrind doesn't understand this assembler stuff
524                 // September 10th, 2007
525                 return;
526         }
527
528 #if defined(ARCH_X86) && defined(USE_XMMINTRIN)
529
530         int MXCSR;
531         FPU fpu;
532
533         /* XXX use real code to determine if the processor supports
534            DenormalsAreZero and FlushToZero
535         */
536
537         if (!fpu.has_flush_to_zero() && !fpu.has_denormals_are_zero()) {
538                 return;
539         }
540
541         MXCSR  = _mm_getcsr();
542
543 #ifdef DEBUG_DENORMAL_EXCEPTION
544         /* This will raise a FP exception if a denormal is detected */
545         MXCSR &= ~_MM_MASK_DENORM;
546 #endif  
547
548         switch (Config->get_denormal_model()) {
549         case DenormalNone:
550                 MXCSR &= ~(_MM_FLUSH_ZERO_ON | 0x40);
551                 break;
552
553         case DenormalFTZ:
554                 if (fpu.has_flush_to_zero()) {
555                         MXCSR |= _MM_FLUSH_ZERO_ON;
556                 }
557                 break;
558
559         case DenormalDAZ:
560                 MXCSR &= ~_MM_FLUSH_ZERO_ON;
561                 if (fpu.has_denormals_are_zero()) {
562                         MXCSR |= 0x40;
563                 }
564                 break;
565
566         case DenormalFTZDAZ:
567                 if (fpu.has_flush_to_zero()) {
568                         if (fpu.has_denormals_are_zero()) {
569                                 MXCSR |= _MM_FLUSH_ZERO_ON | 0x40;
570                         } else {
571                                 MXCSR |= _MM_FLUSH_ZERO_ON;
572                         }
573                 }
574                 break;
575         }
576
577         _mm_setcsr (MXCSR);
578
579 #endif
580 }
581
582 /* this can be changed to modify the translation behaviour for
583    cases where the user has never expressed a preference.
584 */
585 static const bool translate_by_default = true;
586
587 string
588 ARDOUR::translation_enable_path ()
589 {
590         return Glib::build_filename (user_config_directory(), ".translate");
591 }
592
593 bool
594 ARDOUR::translations_are_enabled ()
595 {
596         int fd = ::open (ARDOUR::translation_enable_path().c_str(), O_RDONLY);
597
598         if (fd < 0) {
599                 return translate_by_default;
600         }
601
602         char c;
603         bool ret = false;
604
605         if (::read (fd, &c, 1) == 1 && c == '1') {
606                 ret = true;
607         }
608
609         ::close (fd);
610
611         return ret;
612 }
613
614 bool
615 ARDOUR::set_translations_enabled (bool yn)
616 {
617         string i18n_enabler = ARDOUR::translation_enable_path();
618         int fd = ::open (i18n_enabler.c_str(), O_WRONLY|O_CREAT|O_TRUNC, 0644);
619
620         if (fd < 0) {
621                 return false;
622         }
623         
624         char c;
625         
626         if (yn) {
627                 c = '1';
628         } else {
629                 c = '0';
630         }
631         
632         (void) ::write (fd, &c, 1);
633         (void) ::close (fd);
634
635         return true;
636 }
637
638
639 vector<SyncSource>
640 ARDOUR::get_available_sync_options ()
641 {
642         vector<SyncSource> ret;
643
644         boost::shared_ptr<AudioBackend> backend = AudioEngine::instance()->current_backend();
645         if (backend && backend->name() == "JACK") {
646                 ret.push_back (Engine);
647         }
648
649         ret.push_back (MTC);
650         ret.push_back (MIDIClock);
651         ret.push_back (LTC);
652
653         return ret;
654 }
655
656 /** Return a monotonic value for the number of microseconds that have elapsed
657  * since an arbitrary zero origin.
658  */
659
660 #ifdef __MACH__
661 /* Thanks Apple for not implementing this basic SUSv2, POSIX.1-2001 function
662  */
663 #include <mach/mach_time.h>
664 #define CLOCK_REALTIME 0
665 #define CLOCK_MONOTONIC 0
666 int 
667 clock_gettime (int /*clk_id*/, struct timespec *t)
668 {
669         static bool initialized = false;
670         static mach_timebase_info_data_t timebase;
671         if (!initialized) {
672                 mach_timebase_info(&timebase);
673                 initialized = true;
674         }
675         uint64_t time;
676         time = mach_absolute_time();
677         double nseconds = ((double)time * (double)timebase.numer)/((double)timebase.denom);
678         double seconds = ((double)time * (double)timebase.numer)/((double)timebase.denom * 1e9);
679         t->tv_sec = seconds;
680         t->tv_nsec = nseconds;
681         return 0;
682 }
683 #endif
684  
685 microseconds_t
686 ARDOUR::get_microseconds ()
687 {
688 #ifdef PLATFORM_WINDOWS
689         microseconds_t ret = 0;
690         LARGE_INTEGER freq, time;
691
692         if (QueryPerformanceFrequency(&freq))
693                 if (QueryPerformanceCounter(&time))
694                         ret = (microseconds_t)((time.QuadPart * 1000000) / freq.QuadPart);
695
696         return ret;
697 #else
698         struct timespec ts;
699         if (clock_gettime (CLOCK_MONOTONIC, &ts) != 0) {
700                 /* EEEK! */
701                 return 0;
702         }
703         return (microseconds_t) ts.tv_sec * 1000000 + (ts.tv_nsec/1000);
704 #endif
705 }
706
707 /** Return the number of bits per sample for a given sample format.
708  *
709  * This is closely related to sndfile_data_width() but does NOT
710  * return a "magic" value to differentiate between 32 bit integer
711  * and 32 bit floating point values.
712  */
713
714 int
715 ARDOUR::format_data_width (ARDOUR::SampleFormat format)
716 {
717
718
719
720         switch (format) {
721         case ARDOUR::FormatInt16:
722                 return 16;
723         case ARDOUR::FormatInt24:
724                 return 24;
725         default:
726                 return 32;
727         }
728 }