"only" 1048576 -- sounds like it's not sufficient
[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 #include <glib.h>
41 #include "pbd/gstdio_compat.h"
42
43 #ifdef PLATFORM_WINDOWS
44 #include <stdio.h> // for _setmaxstdio
45 #include <windows.h> // for LARGE_INTEGER
46 #endif
47
48 #ifdef WINDOWS_VST_SUPPORT
49 #include <fst.h>
50 #endif
51
52 #ifdef LXVST_SUPPORT
53 #include "ardour/linux_vst_support.h"
54 #endif
55
56 #ifdef AUDIOUNIT_SUPPORT
57 #include "ardour/audio_unit.h"
58 #endif
59
60 #if defined(__SSE__) || defined(USE_XMMINTRIN)
61 #include <xmmintrin.h>
62 #endif
63
64 #ifdef check
65 #undef check /* stupid Apple and their un-namespaced, generic Carbon macros */
66 #endif
67
68 #include <glibmm/fileutils.h>
69 #include <glibmm/miscutils.h>
70
71 #ifdef HAVE_LRDF
72 #include <lrdf.h>
73 #endif
74
75 #include "pbd/cpus.h"
76 #include "pbd/error.h"
77 #include "pbd/id.h"
78 #include "pbd/pbd.h"
79 #include "pbd/strsplit.h"
80 #include "pbd/fpu.h"
81 #include "pbd/file_utils.h"
82 #include "pbd/enumwriter.h"
83
84 #include "midi++/port.h"
85 #include "midi++/mmc.h"
86
87 #include "LuaBridge/LuaBridge.h"
88
89 #include "ardour/analyser.h"
90 #include "ardour/audio_library.h"
91 #include "ardour/audio_backend.h"
92 #include "ardour/audioengine.h"
93 #include "ardour/audioplaylist.h"
94 #include "ardour/audioregion.h"
95 #include "ardour/buffer_manager.h"
96 #include "ardour/control_protocol_manager.h"
97 #include "ardour/directory_names.h"
98 #include "ardour/event_type_map.h"
99 #include "ardour/filesystem_paths.h"
100 #include "ardour/midi_region.h"
101 #include "ardour/midi_ui.h"
102 #include "ardour/midiport_manager.h"
103 #include "ardour/mix.h"
104 #include "ardour/operations.h"
105 #include "ardour/panner_manager.h"
106 #include "ardour/plugin_manager.h"
107 #include "ardour/presentation_info.h"
108 #include "ardour/process_thread.h"
109 #include "ardour/profile.h"
110 #include "ardour/rc_configuration.h"
111 #include "ardour/region.h"
112 #include "ardour/route_group.h"
113 #include "ardour/runtime_functions.h"
114 #include "ardour/session_event.h"
115 #include "ardour/source_factory.h"
116 #include "ardour/transport_master_manager.h"
117 #ifdef LV2_SUPPORT
118 #include "ardour/uri_map.h"
119 #endif
120 #include "audiographer/routines.h"
121
122 #if defined (__APPLE__)
123 #include <CoreFoundation/CoreFoundation.h>
124 #endif
125
126 #include "pbd/i18n.h"
127
128 ARDOUR::RCConfiguration* ARDOUR::Config = 0;
129 ARDOUR::RuntimeProfile* ARDOUR::Profile = 0;
130 ARDOUR::AudioLibrary* ARDOUR::Library = 0;
131
132 using namespace ARDOUR;
133 using namespace std;
134 using namespace PBD;
135
136 bool libardour_initialized = false;
137
138 compute_peak_t          ARDOUR::compute_peak = 0;
139 find_peaks_t            ARDOUR::find_peaks = 0;
140 apply_gain_to_buffer_t  ARDOUR::apply_gain_to_buffer = 0;
141 mix_buffers_with_gain_t ARDOUR::mix_buffers_with_gain = 0;
142 mix_buffers_no_gain_t   ARDOUR::mix_buffers_no_gain = 0;
143 copy_vector_t                   ARDOUR::copy_vector = 0;
144
145 PBD::Signal1<void,std::string> ARDOUR::BootMessage;
146 PBD::Signal3<void,std::string,std::string,bool> ARDOUR::PluginScanMessage;
147 PBD::Signal1<void,int> ARDOUR::PluginScanTimeout;
148 PBD::Signal0<void> ARDOUR::GUIIdle;
149 PBD::Signal3<bool,std::string,std::string,int> ARDOUR::CopyConfigurationFiles;
150
151 std::map<std::string, bool> ARDOUR::reserved_io_names;
152
153 static bool have_old_configuration_files = false;
154
155 namespace ARDOUR {
156 extern void setup_enum_writer ();
157 }
158
159 /* this is useful for quite a few things that want to check
160    if any bounds-related property has changed
161 */
162 PBD::PropertyChange ARDOUR::bounds_change;
163
164 void
165 setup_hardware_optimization (bool try_optimization)
166 {
167         bool generic_mix_functions = true;
168
169         if (try_optimization) {
170
171                 FPU* fpu = FPU::instance();
172
173 #if defined (ARCH_X86) && defined (BUILD_SSE_OPTIMIZATIONS)
174
175 #ifdef PLATFORM_WINDOWS
176                 /* We have AVX-optimized code for Windows */
177
178                 if (fpu->has_avx()) {
179 #else
180                 /* AVX code doesn't compile on Linux yet */
181
182                 if (false) {
183 #endif
184                         info << "Using AVX optimized routines" << endmsg;
185
186                         // AVX SET
187                         compute_peak          = x86_sse_avx_compute_peak;
188                         find_peaks            = x86_sse_avx_find_peaks;
189                         apply_gain_to_buffer  = x86_sse_avx_apply_gain_to_buffer;
190                         mix_buffers_with_gain = x86_sse_avx_mix_buffers_with_gain;
191                         mix_buffers_no_gain   = x86_sse_avx_mix_buffers_no_gain;
192                         copy_vector           = x86_sse_avx_copy_vector;
193
194                         generic_mix_functions = false;
195
196                 } else if (fpu->has_sse()) {
197
198                         info << "Using SSE optimized routines" << endmsg;
199
200                         // SSE SET
201                         compute_peak          = x86_sse_compute_peak;
202                         find_peaks            = x86_sse_find_peaks;
203                         apply_gain_to_buffer  = x86_sse_apply_gain_to_buffer;
204                         mix_buffers_with_gain = x86_sse_mix_buffers_with_gain;
205                         mix_buffers_no_gain   = x86_sse_mix_buffers_no_gain;
206                         copy_vector           = default_copy_vector;
207
208                         generic_mix_functions = false;
209
210                 }
211
212 #elif defined (__APPLE__) && defined (BUILD_VECLIB_OPTIMIZATIONS)
213
214                 if (floor (kCFCoreFoundationVersionNumber) > kCFCoreFoundationVersionNumber10_4) { /* at least Tiger */
215                         compute_peak           = veclib_compute_peak;
216                         find_peaks             = veclib_find_peaks;
217                         apply_gain_to_buffer   = veclib_apply_gain_to_buffer;
218                         mix_buffers_with_gain  = veclib_mix_buffers_with_gain;
219                         mix_buffers_no_gain    = veclib_mix_buffers_no_gain;
220                         copy_vector            = default_copy_vector;
221
222                         generic_mix_functions = false;
223
224                         info << "Apple VecLib H/W specific optimizations in use" << endmsg;
225                 }
226 #endif
227
228                 /* consider FPU denormal handling to be "h/w optimization" */
229
230                 setup_fpu ();
231         }
232
233         if (generic_mix_functions) {
234
235                 compute_peak          = default_compute_peak;
236                 find_peaks            = default_find_peaks;
237                 apply_gain_to_buffer  = default_apply_gain_to_buffer;
238                 mix_buffers_with_gain = default_mix_buffers_with_gain;
239                 mix_buffers_no_gain   = default_mix_buffers_no_gain;
240                 copy_vector           = default_copy_vector;
241
242                 info << "No H/W specific optimizations in use" << endmsg;
243         }
244
245         AudioGrapher::Routines::override_compute_peak (compute_peak);
246         AudioGrapher::Routines::override_apply_gain_to_buffer (apply_gain_to_buffer);
247 }
248
249 static void
250 lotsa_files_please ()
251 {
252 #ifndef PLATFORM_WINDOWS
253         struct rlimit rl;
254
255         if (getrlimit (RLIMIT_NOFILE, &rl) == 0) {
256
257 #ifdef __APPLE__
258                 /* See the COMPATIBILITY note on the Apple setrlimit() man page */
259                 rl.rlim_cur = min ((rlim_t) OPEN_MAX, rl.rlim_max);
260 #else
261                 rl.rlim_cur = rl.rlim_max;
262 #endif
263
264                 if (setrlimit (RLIMIT_NOFILE, &rl) != 0) {
265                         if (rl.rlim_cur == RLIM_INFINITY) {
266                                 error << _("Could not set system open files limit to \"unlimited\"") << endmsg;
267                         } else {
268                                 error << string_compose (_("Could not set system open files limit to %1"), rl.rlim_cur) << endmsg;
269                         }
270                 } else {
271                         if (rl.rlim_cur != RLIM_INFINITY) {
272                                 info << string_compose (_("Your system is configured to limit %1 to %2 open files"), PROGRAM_NAME, rl.rlim_cur) << endmsg;
273                         }
274                 }
275         } else {
276                 error << string_compose (_("Could not get system open files limit (%1)"), strerror (errno)) << endmsg;
277         }
278 #else
279         /* this only affects stdio. 2048 is the maxium possible (512 the default).
280          *
281          * If we want more, we'll have to replaces the POSIX I/O interfaces with
282          * Win32 API calls (CreateFile, WriteFile, etc) which allows for 16K.
283          *
284          * see http://stackoverflow.com/questions/870173/is-there-a-limit-on-number-of-open-files-in-windows
285          * and http://bugs.mysql.com/bug.php?id=24509
286          */
287         int newmax = _setmaxstdio (2048);
288         if (newmax > 0) {
289                 info << string_compose (_("Your system is configured to limit %1 to %2 open files"), PROGRAM_NAME, newmax) << endmsg;
290         } else {
291                 error << string_compose (_("Could not set system open files limit. Current limit is %1 open files"), _getmaxstdio())  << endmsg;
292         }
293 #endif
294 }
295
296 static int
297 copy_configuration_files (string const & old_dir, string const & new_dir, int old_version)
298 {
299         string old_name;
300         string new_name;
301
302         /* ensure target directory exists */
303
304         if (g_mkdir_with_parents (new_dir.c_str(), 0755)) {
305                 return -1;
306         }
307
308         if (old_version >= 3) {
309
310                 old_name = Glib::build_filename (old_dir, X_("recent"));
311                 new_name = Glib::build_filename (new_dir, X_("recent"));
312
313                 copy_file (old_name, new_name);
314
315                 old_name = Glib::build_filename (old_dir, X_("sfdb"));
316                 new_name = Glib::build_filename (new_dir, X_("sfdb"));
317
318                 copy_file (old_name, new_name);
319
320                 /* can only copy ardour.rc/config - UI config is not compatible */
321
322                 /* users who have been using git/nightlies since the last
323                  * release of 3.5 will have $CONFIG/config rather than
324                  * $CONFIG/ardour.rc. Pick up the newer "old" config file,
325                  * to avoid confusion.
326                  */
327
328                 string old_name = Glib::build_filename (old_dir, X_("config"));
329
330                 if (!Glib::file_test (old_name, Glib::FILE_TEST_EXISTS)) {
331                         old_name = Glib::build_filename (old_dir, X_("ardour.rc"));
332                 }
333
334                 new_name = Glib::build_filename (new_dir, X_("config"));
335
336                 copy_file (old_name, new_name);
337
338                 /* copy templates and route templates */
339
340                 old_name = Glib::build_filename (old_dir, X_("templates"));
341                 new_name = Glib::build_filename (new_dir, X_("templates"));
342
343                 copy_recurse (old_name, new_name);
344
345                 old_name = Glib::build_filename (old_dir, X_("route_templates"));
346                 new_name = Glib::build_filename (new_dir, X_("route_templates"));
347
348                 copy_recurse (old_name, new_name);
349
350                 /* presets */
351
352                 old_name = Glib::build_filename (old_dir, X_("presets"));
353                 new_name = Glib::build_filename (new_dir, X_("presets"));
354
355                 copy_recurse (old_name, new_name);
356
357                 /* plugin status */
358                 g_mkdir_with_parents (Glib::build_filename (new_dir, plugin_metadata_dir_name).c_str(), 0755);
359
360                 old_name = Glib::build_filename (old_dir, X_("plugin_statuses")); /* until 6.0 */
361                 new_name = Glib::build_filename (new_dir, plugin_metadata_dir_name, X_("plugin_statuses"));
362                 copy_file (old_name, new_name); /* can fail silently */
363
364                 old_name = Glib::build_filename (old_dir, plugin_metadata_dir_name, X_("plugin_statuses"));
365                 copy_file (old_name, new_name);
366
367                 /* plugin tags */
368
369                 old_name = Glib::build_filename (old_dir, plugin_metadata_dir_name, X_("plugin_tags"));
370                 new_name = Glib::build_filename (new_dir, plugin_metadata_dir_name, X_("plugin_tags"));
371
372                 copy_file (old_name, new_name);
373
374                 /* export formats */
375
376                 old_name = Glib::build_filename (old_dir, export_formats_dir_name);
377                 new_name = Glib::build_filename (new_dir, export_formats_dir_name);
378
379                 vector<string> export_formats;
380                 g_mkdir_with_parents (Glib::build_filename (new_dir, export_formats_dir_name).c_str(), 0755);
381                 find_files_matching_pattern (export_formats, old_name, X_("*.format"));
382                 for (vector<string>::iterator i = export_formats.begin(); i != export_formats.end(); ++i) {
383                         std::string from = *i;
384                         std::string to = Glib::build_filename (new_name, Glib::path_get_basename (*i));
385                         copy_file (from, to);
386                 }
387         }
388
389         return 0;
390 }
391
392 void
393 ARDOUR::check_for_old_configuration_files ()
394 {
395         int current_version = atoi (X_(PROGRAM_VERSION));
396
397         if (current_version <= 1) {
398                 return;
399         }
400
401         int old_version = current_version - 1;
402
403         string old_config_dir = user_config_directory (old_version);
404         /* pass in the current version explicitly to avoid creation */
405         string current_config_dir = user_config_directory (current_version);
406
407         if (!Glib::file_test (current_config_dir, Glib::FILE_TEST_IS_DIR)) {
408                 if (Glib::file_test (old_config_dir, Glib::FILE_TEST_IS_DIR)) {
409                         have_old_configuration_files = true;
410                 }
411         }
412 }
413
414 int
415 ARDOUR::handle_old_configuration_files (boost::function<bool (std::string const&, std::string const&, int)> ui_handler)
416 {
417         if (have_old_configuration_files) {
418                 int current_version = atoi (X_(PROGRAM_VERSION));
419                 assert (current_version > 1); // established in check_for_old_configuration_files ()
420                 int old_version = current_version - 1;
421                 string old_config_dir = user_config_directory (old_version);
422                 string current_config_dir = user_config_directory (current_version);
423
424                 if (ui_handler (old_config_dir, current_config_dir, old_version)) {
425                         copy_configuration_files (old_config_dir, current_config_dir, old_version);
426                         return 1;
427                 }
428         }
429         return 0;
430 }
431
432 bool
433 ARDOUR::init (bool use_windows_vst, bool try_optimization, const char* localedir)
434 {
435         if (libardour_initialized) {
436                 return true;
437         }
438
439 #ifndef NDEBUG
440         if (getenv("LUA_METATABLES")) {
441                 luabridge::Security::setHideMetatables (false);
442         }
443 #endif
444
445         if (!PBD::init()) return false;
446
447 #if ENABLE_NLS
448         (void) bindtextdomain(PACKAGE, localedir);
449         (void) bind_textdomain_codeset (PACKAGE, "UTF-8");
450 #endif
451
452         SessionEvent::init_event_pool ();
453
454         Operations::make_operations_quarks ();
455         SessionObject::make_property_quarks ();
456         Region::make_property_quarks ();
457         MidiRegion::make_property_quarks ();
458         AudioRegion::make_property_quarks ();
459         RouteGroup::make_property_quarks ();
460         Playlist::make_property_quarks ();
461         AudioPlaylist::make_property_quarks ();
462         PresentationInfo::make_property_quarks ();
463         TransportMaster::make_property_quarks ();
464
465         /* this is a useful ready to use PropertyChange that many
466            things need to check. This avoids having to compose
467            it every time we want to check for any of the relevant
468            property changes.
469         */
470
471         bounds_change.add (ARDOUR::Properties::start);
472         bounds_change.add (ARDOUR::Properties::position);
473         bounds_change.add (ARDOUR::Properties::length);
474
475         /* provide a state version for the few cases that need it and are not
476            driven by reading state from disk (e.g. undo/redo)
477         */
478
479         Stateful::current_state_version = CURRENT_SESSION_FILE_VERSION;
480
481         ARDOUR::setup_enum_writer ();
482
483         // allow ardour the absolute maximum number of open files
484         lotsa_files_please ();
485
486 #ifdef HAVE_LRDF
487         lrdf_init();
488 #endif
489         Library = new AudioLibrary;
490
491         BootMessage (_("Loading configuration"));
492
493         Config = new RCConfiguration;
494
495         if (Config->load_state ()) {
496                 return false;
497         }
498
499         Config->set_use_windows_vst (use_windows_vst);
500 #ifdef LXVST_SUPPORT
501         Config->set_use_lxvst(true);
502 #endif
503
504         Profile = new RuntimeProfile;
505
506
507 #ifdef WINDOWS_VST_SUPPORT
508         if (Config->get_use_windows_vst() && fst_init (0)) {
509                 return false;
510         }
511 #endif
512
513 #ifdef LXVST_SUPPORT
514         if (Config->get_use_lxvst() && vstfx_init (0)) {
515                 return false;
516         }
517 #endif
518
519 #ifdef AUDIOUNIT_SUPPORT
520         AUPluginInfo::load_cached_info ();
521 #endif
522
523         setup_hardware_optimization (try_optimization);
524
525         SourceFactory::init ();
526         Analyser::init ();
527
528         /* singletons - first object is "it" */
529         (void) PluginManager::instance();
530 #ifdef LV2_SUPPORT
531         (void) URIMap::instance();
532 #endif
533         (void) EventTypeMap::instance();
534
535         ControlProtocolManager::instance().discover_control_protocols ();
536
537         /* for each control protocol, check for a request buffer factory method
538            and if it exists, store it in the EventLoop list of such
539            methods. This allows the relevant threads to register themselves
540            with EventLoops so that signal emission can be RT-safe.
541         */
542
543         ControlProtocolManager::instance().register_request_buffer_factories ();
544         /* it would be nice if this could auto-register itself in the
545            constructor, since MidiControlUI is a singleton, but it can't be
546            created until after the engine is running. Therefore we have to
547            explicitly register it here.
548         */
549         EventLoop::register_request_buffer_factory (X_("midiUI"), MidiControlUI::request_factory);
550
551         ProcessThread::init ();
552         /* the + 4 is a bit of a handwave. i don't actually know
553            how many more per-thread buffer sets we need above
554            the h/w concurrency, but its definitely > 1 more.
555         */
556         BufferManager::init (hardware_concurrency() + 4);
557
558         PannerManager::instance().discover_panners();
559
560         ARDOUR::AudioEngine::create ();
561
562         /* it is unfortunate that we need to include reserved names here that
563            refer to control surfaces. But there's no way to ensure a complete
564            lack of collisions without doing this, since the control surface
565            support may not even be active. Without adding an API to control
566            surface support that would list their port names, we do have to
567            list them here.
568
569            We also need to know if the given I/O is an actual route.
570            For routes (e.g. "master"), bus creation needs to be allowed the first time,
571            while for pure I/O (e.g. "Click") track/bus creation must always fail.
572         */
573
574         reserved_io_names[_("Monitor")] = true;
575         reserved_io_names[_("Master")] = true;
576         reserved_io_names["auditioner"] = true; // auditioner.cc  Track (s, "auditioner",...)
577
578         /* pure I/O */
579         reserved_io_names[X_("Click")] = false; // session.cc ClickIO (*this, X_("Click")
580         reserved_io_names[_("Control")] = false;
581         reserved_io_names[_("Mackie")] = false;
582         reserved_io_names[_("FaderPort Recv")] = false;
583         reserved_io_names[_("FaderPort Send")] = false;
584         reserved_io_names[_("FaderPort2 Recv")] = false;
585         reserved_io_names[_("FaderPort2 Send")] = false;
586         reserved_io_names[_("FaderPort8 Recv")] = false;
587         reserved_io_names[_("FaderPort8 Send")] = false;
588         reserved_io_names[_("FaderPort16 Recv")] = false;
589         reserved_io_names[_("FaderPort16 Send")] = false;
590
591         libardour_initialized = true;
592
593         return true;
594 }
595
596 void
597 ARDOUR::init_post_engine ()
598 {
599         XMLNode* node;
600
601         if ((node = Config->control_protocol_state()) != 0) {
602                 ControlProtocolManager::instance().set_state (*node, 0 /* here: global-config state */);
603         }
604
605         if ((node = Config->transport_master_state()) != 0) {
606                 if (TransportMasterManager::instance().set_state (*node, Stateful::loading_state_version)) {
607                         error << _("Cannot restore transport master manager") << endmsg;
608                         /* XXX now what? */
609                 }
610         } else {
611                 if (TransportMasterManager::instance().set_default_configuration ()) {
612                         error << _("Cannot initialize transport master manager") << endmsg;
613                         /* XXX now what? */
614                 }
615         }
616
617         /* find plugins */
618
619         ARDOUR::PluginManager::instance().refresh (!Config->get_discover_vst_on_start());
620 }
621
622 void
623         ARDOUR::cleanup ()
624 {
625         if (!libardour_initialized) {
626                 return;
627         }
628
629         delete &ControlProtocolManager::instance();
630         ARDOUR::AudioEngine::destroy ();
631
632         delete Library;
633 #ifdef HAVE_LRDF
634         lrdf_cleanup ();
635 #endif
636 #ifdef WINDOWS_VST_SUPPORT
637         fst_exit ();
638 #endif
639
640 #ifdef LXVST_SUPPORT
641         vstfx_exit();
642 #endif
643         delete &PluginManager::instance();
644         delete Config;
645         PBD::cleanup ();
646
647         return;
648 }
649
650 bool
651 ARDOUR::no_auto_connect()
652 {
653         return getenv ("ARDOUR_NO_AUTOCONNECT") != 0;
654 }
655
656 void
657 ARDOUR::setup_fpu ()
658 {
659         FPU* fpu = FPU::instance ();
660
661         if (getenv ("ARDOUR_RUNNING_UNDER_VALGRIND")) {
662                 // valgrind doesn't understand this assembler stuff
663                 // September 10th, 2007
664                 return;
665         }
666
667 #if defined(ARCH_X86) && defined(USE_XMMINTRIN)
668
669         int MXCSR;
670
671         if (!fpu->has_flush_to_zero() && !fpu->has_denormals_are_zero()) {
672                 return;
673         }
674
675         MXCSR  = _mm_getcsr();
676
677 #ifdef DEBUG_DENORMAL_EXCEPTION
678         /* This will raise a FP exception if a denormal is detected */
679         MXCSR &= ~_MM_MASK_DENORM;
680 #endif
681
682         switch (Config->get_denormal_model()) {
683         case DenormalNone:
684                 MXCSR &= ~(_MM_FLUSH_ZERO_ON | 0x40);
685                 break;
686
687         case DenormalFTZ:
688                 if (fpu->has_flush_to_zero()) {
689                         MXCSR |= _MM_FLUSH_ZERO_ON;
690                 }
691                 break;
692
693         case DenormalDAZ:
694                 MXCSR &= ~_MM_FLUSH_ZERO_ON;
695                 if (fpu->has_denormals_are_zero()) {
696                         MXCSR |= 0x40;
697                 }
698                 break;
699
700         case DenormalFTZDAZ:
701                 if (fpu->has_flush_to_zero()) {
702                         if (fpu->has_denormals_are_zero()) {
703                                 MXCSR |= _MM_FLUSH_ZERO_ON | 0x40;
704                         } else {
705                                 MXCSR |= _MM_FLUSH_ZERO_ON;
706                         }
707                 }
708                 break;
709         }
710
711         _mm_setcsr (MXCSR);
712
713 #endif
714 }
715
716 /* this can be changed to modify the translation behaviour for
717    cases where the user has never expressed a preference.
718 */
719 static const bool translate_by_default = true;
720
721 string
722 ARDOUR::translation_enable_path ()
723 {
724         return Glib::build_filename (user_config_directory(), ".translate");
725 }
726
727 bool
728 ARDOUR::translations_are_enabled ()
729 {
730         int fd = g_open (ARDOUR::translation_enable_path().c_str(), O_RDONLY, 0444);
731
732         if (fd < 0) {
733                 return translate_by_default;
734         }
735
736         char c;
737         bool ret = false;
738
739         if (::read (fd, &c, 1) == 1 && c == '1') {
740                 ret = true;
741         }
742
743         ::close (fd);
744
745         return ret;
746 }
747
748 bool
749 ARDOUR::set_translations_enabled (bool yn)
750 {
751         string i18n_enabler = ARDOUR::translation_enable_path();
752         int fd = g_open (i18n_enabler.c_str(), O_WRONLY|O_CREAT|O_TRUNC, 0644);
753
754         if (fd < 0) {
755                 return false;
756         }
757
758         char c;
759
760         if (yn) {
761                 c = '1';
762         } else {
763                 c = '0';
764         }
765
766         (void) ::write (fd, &c, 1);
767         (void) ::close (fd);
768
769         Config->ParameterChanged ("enable-translation");
770         return true;
771 }
772
773
774 vector<SyncSource>
775 ARDOUR::get_available_sync_options ()
776 {
777         vector<SyncSource> ret;
778
779         boost::shared_ptr<AudioBackend> backend = AudioEngine::instance()->current_backend();
780         if (backend && backend->name() == "JACK") {
781                 ret.push_back (Engine);
782         }
783
784         ret.push_back (MTC);
785         ret.push_back (MIDIClock);
786         ret.push_back (LTC);
787
788         return ret;
789 }
790
791 /** Return a monotonic value for the number of microseconds that have elapsed
792  * since an arbitrary zero origin.
793  */
794
795 #ifdef __MACH__
796 /* Thanks Apple for not implementing this basic SUSv2, POSIX.1-2001 function
797  */
798 #include <mach/mach_time.h>
799 #define CLOCK_REALTIME 0
800 #define CLOCK_MONOTONIC 0
801 int
802 clock_gettime (int /*clk_id*/, struct timespec *t)
803 {
804         static bool initialized = false;
805         static mach_timebase_info_data_t timebase;
806         if (!initialized) {
807                 mach_timebase_info(&timebase);
808                 initialized = true;
809         }
810         uint64_t time;
811         time = mach_absolute_time();
812         double nseconds = ((double)time * (double)timebase.numer)/((double)timebase.denom);
813         double seconds = ((double)time * (double)timebase.numer)/((double)timebase.denom * 1e9);
814         t->tv_sec = seconds;
815         t->tv_nsec = nseconds;
816         return 0;
817 }
818 #endif
819
820 microseconds_t
821 ARDOUR::get_microseconds ()
822 {
823 #ifdef PLATFORM_WINDOWS
824         microseconds_t ret = 0;
825         LARGE_INTEGER freq, time;
826
827         if (QueryPerformanceFrequency(&freq))
828                 if (QueryPerformanceCounter(&time))
829                         ret = (microseconds_t)((time.QuadPart * 1000000) / freq.QuadPart);
830
831         return ret;
832 #else
833         struct timespec ts;
834         if (clock_gettime (CLOCK_MONOTONIC, &ts) != 0) {
835                 /* EEEK! */
836                 return 0;
837         }
838         return (microseconds_t) ts.tv_sec * 1000000 + (ts.tv_nsec/1000);
839 #endif
840 }
841
842 /** Return the number of bits per sample for a given sample format.
843  *
844  * This is closely related to sndfile_data_width() but does NOT
845  * return a "magic" value to differentiate between 32 bit integer
846  * and 32 bit floating point values.
847  */
848
849 int
850 ARDOUR::format_data_width (ARDOUR::SampleFormat format)
851 {
852
853
854
855         switch (format) {
856         case ARDOUR::FormatInt16:
857                 return 16;
858         case ARDOUR::FormatInt24:
859                 return 24;
860         default:
861                 return 32;
862         }
863 }