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