Use XMLNode::get/set_property API in ARDOUR::Diskstream
[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[_("Control")] = false;
565         reserved_io_names[_("Click")] = false;
566         reserved_io_names[_("Mackie")] = false;
567
568         libardour_initialized = true;
569
570         return true;
571 }
572
573 void
574 ARDOUR::init_post_engine ()
575 {
576         XMLNode* node;
577         if ((node = Config->control_protocol_state()) != 0) {
578                 ControlProtocolManager::instance().set_state (*node, Stateful::loading_state_version);
579         }
580
581         /* find plugins */
582
583         ARDOUR::PluginManager::instance().refresh (!Config->get_discover_vst_on_start());
584 }
585
586 void
587 ARDOUR::cleanup ()
588 {
589         if (!libardour_initialized) {
590                 return;
591         }
592
593         ARDOUR::AudioEngine::destroy ();
594
595         delete Library;
596 #ifdef HAVE_LRDF
597         lrdf_cleanup ();
598 #endif
599         delete &ControlProtocolManager::instance();
600 #ifdef WINDOWS_VST_SUPPORT
601         fst_exit ();
602 #endif
603
604 #ifdef LXVST_SUPPORT
605         vstfx_exit();
606 #endif
607         delete &PluginManager::instance();
608         delete Config;
609         PBD::cleanup ();
610
611         return;
612 }
613
614 bool
615 ARDOUR::no_auto_connect()
616 {
617         return getenv ("ARDOUR_NO_AUTOCONNECT") != 0;
618 }
619
620 void
621 ARDOUR::setup_fpu ()
622 {
623         FPU* fpu = FPU::instance ();
624
625         if (getenv ("ARDOUR_RUNNING_UNDER_VALGRIND")) {
626                 // valgrind doesn't understand this assembler stuff
627                 // September 10th, 2007
628                 return;
629         }
630
631 #if defined(ARCH_X86) && defined(USE_XMMINTRIN)
632
633         int MXCSR;
634
635         if (!fpu->has_flush_to_zero() && !fpu->has_denormals_are_zero()) {
636                 return;
637         }
638
639         MXCSR  = _mm_getcsr();
640
641 #ifdef DEBUG_DENORMAL_EXCEPTION
642         /* This will raise a FP exception if a denormal is detected */
643         MXCSR &= ~_MM_MASK_DENORM;
644 #endif
645
646         switch (Config->get_denormal_model()) {
647         case DenormalNone:
648                 MXCSR &= ~(_MM_FLUSH_ZERO_ON | 0x40);
649                 break;
650
651         case DenormalFTZ:
652                 if (fpu->has_flush_to_zero()) {
653                         MXCSR |= _MM_FLUSH_ZERO_ON;
654                 }
655                 break;
656
657         case DenormalDAZ:
658                 MXCSR &= ~_MM_FLUSH_ZERO_ON;
659                 if (fpu->has_denormals_are_zero()) {
660                         MXCSR |= 0x40;
661                 }
662                 break;
663
664         case DenormalFTZDAZ:
665                 if (fpu->has_flush_to_zero()) {
666                         if (fpu->has_denormals_are_zero()) {
667                                 MXCSR |= _MM_FLUSH_ZERO_ON | 0x40;
668                         } else {
669                                 MXCSR |= _MM_FLUSH_ZERO_ON;
670                         }
671                 }
672                 break;
673         }
674
675         _mm_setcsr (MXCSR);
676
677 #endif
678 }
679
680 /* this can be changed to modify the translation behaviour for
681    cases where the user has never expressed a preference.
682 */
683 static const bool translate_by_default = true;
684
685 string
686 ARDOUR::translation_enable_path ()
687 {
688         return Glib::build_filename (user_config_directory(), ".translate");
689 }
690
691 bool
692 ARDOUR::translations_are_enabled ()
693 {
694         int fd = g_open (ARDOUR::translation_enable_path().c_str(), O_RDONLY, 0444);
695
696         if (fd < 0) {
697                 return translate_by_default;
698         }
699
700         char c;
701         bool ret = false;
702
703         if (::read (fd, &c, 1) == 1 && c == '1') {
704                 ret = true;
705         }
706
707         ::close (fd);
708
709         return ret;
710 }
711
712 bool
713 ARDOUR::set_translations_enabled (bool yn)
714 {
715         string i18n_enabler = ARDOUR::translation_enable_path();
716         int fd = g_open (i18n_enabler.c_str(), O_WRONLY|O_CREAT|O_TRUNC, 0644);
717
718         if (fd < 0) {
719                 return false;
720         }
721
722         char c;
723
724         if (yn) {
725                 c = '1';
726         } else {
727                 c = '0';
728         }
729
730         (void) ::write (fd, &c, 1);
731         (void) ::close (fd);
732
733         Config->ParameterChanged ("enable-translation");
734         return true;
735 }
736
737
738 vector<SyncSource>
739 ARDOUR::get_available_sync_options ()
740 {
741         vector<SyncSource> ret;
742
743         boost::shared_ptr<AudioBackend> backend = AudioEngine::instance()->current_backend();
744         if (backend && backend->name() == "JACK") {
745                 ret.push_back (Engine);
746         }
747
748         ret.push_back (MTC);
749         ret.push_back (MIDIClock);
750         ret.push_back (LTC);
751
752         return ret;
753 }
754
755 /** Return a monotonic value for the number of microseconds that have elapsed
756  * since an arbitrary zero origin.
757  */
758
759 #ifdef __MACH__
760 /* Thanks Apple for not implementing this basic SUSv2, POSIX.1-2001 function
761  */
762 #include <mach/mach_time.h>
763 #define CLOCK_REALTIME 0
764 #define CLOCK_MONOTONIC 0
765 int
766 clock_gettime (int /*clk_id*/, struct timespec *t)
767 {
768         static bool initialized = false;
769         static mach_timebase_info_data_t timebase;
770         if (!initialized) {
771                 mach_timebase_info(&timebase);
772                 initialized = true;
773         }
774         uint64_t time;
775         time = mach_absolute_time();
776         double nseconds = ((double)time * (double)timebase.numer)/((double)timebase.denom);
777         double seconds = ((double)time * (double)timebase.numer)/((double)timebase.denom * 1e9);
778         t->tv_sec = seconds;
779         t->tv_nsec = nseconds;
780         return 0;
781 }
782 #endif
783
784 microseconds_t
785 ARDOUR::get_microseconds ()
786 {
787 #ifdef PLATFORM_WINDOWS
788         microseconds_t ret = 0;
789         LARGE_INTEGER freq, time;
790
791         if (QueryPerformanceFrequency(&freq))
792                 if (QueryPerformanceCounter(&time))
793                         ret = (microseconds_t)((time.QuadPart * 1000000) / freq.QuadPart);
794
795         return ret;
796 #else
797         struct timespec ts;
798         if (clock_gettime (CLOCK_MONOTONIC, &ts) != 0) {
799                 /* EEEK! */
800                 return 0;
801         }
802         return (microseconds_t) ts.tv_sec * 1000000 + (ts.tv_nsec/1000);
803 #endif
804 }
805
806 /** Return the number of bits per sample for a given sample format.
807  *
808  * This is closely related to sndfile_data_width() but does NOT
809  * return a "magic" value to differentiate between 32 bit integer
810  * and 32 bit floating point values.
811  */
812
813 int
814 ARDOUR::format_data_width (ARDOUR::SampleFormat format)
815 {
816
817
818
819         switch (format) {
820         case ARDOUR::FormatInt16:
821                 return 16;
822         case ARDOUR::FormatInt24:
823                 return 24;
824         default:
825                 return 32;
826         }
827 }