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