globally remove all trailing whitespace from ardour code base.
[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 <windows.h> // for LARGE_INTEGER
45 #endif
46
47 #ifdef WINDOWS_VST_SUPPORT
48 #include <fst.h>
49 #endif
50
51 #ifdef LXVST_SUPPORT
52 #include "ardour/linux_vst_support.h"
53 #endif
54
55 #ifdef AUDIOUNIT_SUPPORT
56 #include "ardour/audio_unit.h"
57 #endif
58
59 #if defined(__SSE__) || defined(USE_XMMINTRIN)
60 #include <xmmintrin.h>
61 #endif
62
63 #ifdef check
64 #undef check /* stupid Apple and their un-namespaced, generic Carbon macros */
65 #endif
66
67 #include <glibmm/fileutils.h>
68 #include <glibmm/miscutils.h>
69
70 #ifdef HAVE_LRDF
71 #include <lrdf.h>
72 #endif
73
74 #include "pbd/cpus.h"
75 #include "pbd/error.h"
76 #include "pbd/id.h"
77 #include "pbd/pbd.h"
78 #include "pbd/strsplit.h"
79 #include "pbd/fpu.h"
80 #include "pbd/file_utils.h"
81 #include "pbd/enumwriter.h"
82 #include "pbd/basename.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/midiport_manager.h"
100 #include "ardour/mix.h"
101 #include "ardour/operations.h"
102 #include "ardour/panner_manager.h"
103 #include "ardour/plugin_manager.h"
104 #include "ardour/process_thread.h"
105 #include "ardour/profile.h"
106 #include "ardour/rc_configuration.h"
107 #include "ardour/region.h"
108 #include "ardour/route_group.h"
109 #include "ardour/runtime_functions.h"
110 #include "ardour/session_event.h"
111 #include "ardour/source_factory.h"
112 #include "ardour/uri_map.h"
113
114 #include "audiographer/routines.h"
115
116 #if defined (__APPLE__)
117        #include <Carbon/Carbon.h> // For Gestalt
118 #endif
119
120 #include "i18n.h"
121
122 ARDOUR::RCConfiguration* ARDOUR::Config = 0;
123 ARDOUR::RuntimeProfile* ARDOUR::Profile = 0;
124 ARDOUR::AudioLibrary* ARDOUR::Library = 0;
125
126 using namespace ARDOUR;
127 using namespace std;
128 using namespace PBD;
129
130 bool libardour_initialized = false;
131
132 compute_peak_t          ARDOUR::compute_peak = 0;
133 find_peaks_t            ARDOUR::find_peaks = 0;
134 apply_gain_to_buffer_t  ARDOUR::apply_gain_to_buffer = 0;
135 mix_buffers_with_gain_t ARDOUR::mix_buffers_with_gain = 0;
136 mix_buffers_no_gain_t   ARDOUR::mix_buffers_no_gain = 0;
137 copy_vector_t                   ARDOUR::copy_vector = 0;
138
139 PBD::Signal1<void,std::string> ARDOUR::BootMessage;
140 PBD::Signal3<void,std::string,std::string,bool> ARDOUR::PluginScanMessage;
141 PBD::Signal1<void,int> ARDOUR::PluginScanTimeout;
142 PBD::Signal0<void> ARDOUR::GUIIdle;
143 PBD::Signal3<bool,std::string,std::string,int> ARDOUR::CopyConfigurationFiles;
144
145 std::vector<std::string> ARDOUR::reserved_io_names;
146
147 static bool have_old_configuration_files = false;
148
149 namespace ARDOUR {
150 extern void setup_enum_writer ();
151 }
152
153 /* this is useful for quite a few things that want to check
154    if any bounds-related property has changed
155 */
156 PBD::PropertyChange ARDOUR::bounds_change;
157
158 void
159 setup_hardware_optimization (bool try_optimization)
160 {
161         bool generic_mix_functions = true;
162
163         if (try_optimization) {
164
165                 FPU* fpu = FPU::instance();
166
167 #if defined (ARCH_X86) && defined (BUILD_SSE_OPTIMIZATIONS)
168
169 #ifdef PLATFORM_WINDOWS
170                 /* We have AVX-optimized code for Windows */
171                 
172                 if (fpu->has_avx()) {
173 #else                   
174                 /* AVX code doesn't compile on Linux yet */
175                 
176                 if (false) {
177 #endif                  
178                         info << "Using AVX optimized routines" << endmsg;
179                         
180                         // AVX SET
181                         compute_peak          = x86_sse_avx_compute_peak;
182                         find_peaks            = x86_sse_avx_find_peaks;
183                         apply_gain_to_buffer  = x86_sse_avx_apply_gain_to_buffer;
184                         mix_buffers_with_gain = x86_sse_avx_mix_buffers_with_gain;
185                         mix_buffers_no_gain   = x86_sse_avx_mix_buffers_no_gain;
186                         copy_vector           = x86_sse_avx_copy_vector;
187
188                         generic_mix_functions = false;
189
190                 } else if (fpu->has_sse()) {
191
192                         info << "Using SSE optimized routines" << endmsg;
193
194                         // SSE SET
195                         compute_peak          = x86_sse_compute_peak;
196                         find_peaks            = x86_sse_find_peaks;
197                         apply_gain_to_buffer  = x86_sse_apply_gain_to_buffer;
198                         mix_buffers_with_gain = x86_sse_mix_buffers_with_gain;
199                         mix_buffers_no_gain   = x86_sse_mix_buffers_no_gain;
200                         copy_vector           = default_copy_vector;
201
202                         generic_mix_functions = false;
203
204                 }
205
206 #elif defined (__APPLE__) && defined (BUILD_VECLIB_OPTIMIZATIONS)
207                 SInt32 sysVersion = 0;
208
209                 if (noErr != Gestalt(gestaltSystemVersion, &sysVersion))
210                         sysVersion = 0;
211
212                 if (sysVersion >= 0x00001040) { // Tiger at least
213                         compute_peak           = veclib_compute_peak;
214                         find_peaks             = veclib_find_peaks;
215                         apply_gain_to_buffer   = veclib_apply_gain_to_buffer;
216                         mix_buffers_with_gain  = veclib_mix_buffers_with_gain;
217                         mix_buffers_no_gain    = veclib_mix_buffers_no_gain;
218                         copy_vector            = default_copy_vector;
219
220                         generic_mix_functions = false;
221
222                         info << "Apple VecLib H/W specific optimizations in use" << endmsg;
223                 }
224 #endif
225
226                 /* consider FPU denormal handling to be "h/w optimization" */
227
228                 setup_fpu ();
229         }
230
231         if (generic_mix_functions) {
232
233                 compute_peak          = default_compute_peak;
234                 find_peaks            = default_find_peaks;
235                 apply_gain_to_buffer  = default_apply_gain_to_buffer;
236                 mix_buffers_with_gain = default_mix_buffers_with_gain;
237                 mix_buffers_no_gain   = default_mix_buffers_no_gain;
238                 copy_vector           = default_copy_vector;
239
240                 info << "No H/W specific optimizations in use" << endmsg;
241         }
242
243         AudioGrapher::Routines::override_compute_peak (compute_peak);
244         AudioGrapher::Routines::override_apply_gain_to_buffer (apply_gain_to_buffer);
245 }
246
247 static void
248 lotsa_files_please ()
249 {
250 #ifndef PLATFORM_WINDOWS
251         struct rlimit rl;
252
253         if (getrlimit (RLIMIT_NOFILE, &rl) == 0) {
254
255 #ifdef __APPLE__
256                 /* See the COMPATIBILITY note on the Apple setrlimit() man page */
257                 rl.rlim_cur = min ((rlim_t) OPEN_MAX, rl.rlim_max);
258 #else
259                 rl.rlim_cur = rl.rlim_max;
260 #endif
261
262                 if (setrlimit (RLIMIT_NOFILE, &rl) != 0) {
263                         if (rl.rlim_cur == RLIM_INFINITY) {
264                                 error << _("Could not set system open files limit to \"unlimited\"") << endmsg;
265                         } else {
266                                 error << string_compose (_("Could not set system open files limit to %1"), rl.rlim_cur) << endmsg;
267                         }
268                 } else {
269                         if (rl.rlim_cur != RLIM_INFINITY) {
270                                 info << string_compose (_("Your system is configured to limit %1 to only %2 open files"), PROGRAM_NAME, rl.rlim_cur) << endmsg;
271                         }
272                 }
273         } else {
274                 error << string_compose (_("Could not get system open files limit (%1)"), strerror (errno)) << endmsg;
275         }
276 #endif
277 }
278
279 static int
280 copy_configuration_files (string const & old_dir, string const & new_dir, int old_version)
281 {
282         string old_name;
283         string new_name;
284
285         /* ensure target directory exists */
286
287         if (g_mkdir_with_parents (new_dir.c_str(), 0755)) {
288                 return -1;
289         }
290         
291         if (old_version == 3) {
292         
293                 old_name = Glib::build_filename (old_dir, X_("recent"));
294                 new_name = Glib::build_filename (new_dir, X_("recent"));
295
296                 copy_file (old_name, new_name);
297
298                 old_name = Glib::build_filename (old_dir, X_("sfdb"));
299                 new_name = Glib::build_filename (new_dir, X_("sfdb"));
300
301                 copy_file (old_name, new_name);
302
303                 /* can only copy ardour.rc/config - UI config is not compatible */
304
305                 /* users who have been using git/nightlies since the last
306                  * release of 3.5 will have $CONFIG/config rather than
307                  * $CONFIG/ardour.rc. Pick up the newer "old" config file,
308                  * to avoid confusion.
309                  */
310                 
311                 string old_name = Glib::build_filename (old_dir, X_("config"));
312
313                 if (!Glib::file_test (old_name, Glib::FILE_TEST_EXISTS)) {
314                         old_name = Glib::build_filename (old_dir, X_("ardour.rc"));
315                 }
316
317                 new_name = Glib::build_filename (new_dir, X_("config"));
318
319                 copy_file (old_name, new_name);
320
321                 /* copy templates and route templates */
322
323                 old_name = Glib::build_filename (old_dir, X_("templates"));
324                 new_name = Glib::build_filename (new_dir, X_("templates"));
325
326                 copy_recurse (old_name, new_name);
327
328                 old_name = Glib::build_filename (old_dir, X_("route_templates"));
329                 new_name = Glib::build_filename (new_dir, X_("route_templates"));
330
331                 copy_recurse (old_name, new_name);
332
333                 /* presets */
334
335                 old_name = Glib::build_filename (old_dir, X_("presets"));
336                 new_name = Glib::build_filename (new_dir, X_("presets"));
337                 
338                 copy_recurse (old_name, new_name);
339
340                 /* presets */
341
342                 old_name = Glib::build_filename (old_dir, X_("plugin_statuses"));
343                 new_name = Glib::build_filename (new_dir, X_("plugin_statuses"));
344
345                 copy_file (old_name, new_name);
346                 
347                 /* export formats */
348
349                 old_name = Glib::build_filename (old_dir, export_formats_dir_name);
350                 new_name = Glib::build_filename (new_dir, export_formats_dir_name);
351                 
352                 vector<string> export_formats;
353                 g_mkdir_with_parents (Glib::build_filename (new_dir, export_formats_dir_name).c_str(), 0755);
354                 find_files_matching_pattern (export_formats, old_name, X_("*.format"));
355                 for (vector<string>::iterator i = export_formats.begin(); i != export_formats.end(); ++i) {
356                         std::string from = *i;
357                         std::string to = Glib::build_filename (new_name, Glib::path_get_basename (*i));
358                         copy_file (from, to);
359                 }
360         }
361
362         return 0;
363 }
364
365 void
366 ARDOUR::check_for_old_configuration_files ()
367 {
368         int current_version = atoi (X_(PROGRAM_VERSION));
369         
370         if (current_version <= 1) {
371                 return;
372         }
373
374         int old_version = current_version - 1;
375
376         string old_config_dir = user_config_directory (old_version);
377         /* pass in the current version explicitly to avoid creation */
378         string current_config_dir = user_config_directory (current_version);
379
380         if (!Glib::file_test (current_config_dir, Glib::FILE_TEST_IS_DIR)) {
381                 if (Glib::file_test (old_config_dir, Glib::FILE_TEST_IS_DIR)) {
382                         have_old_configuration_files = true;
383                 }
384         }
385 }
386
387 int
388 ARDOUR::handle_old_configuration_files (boost::function<bool (std::string const&, std::string const&, int)> ui_handler)
389 {
390         if (have_old_configuration_files) {
391                 int current_version = atoi (X_(PROGRAM_VERSION));
392                 assert (current_version > 1); // established in check_for_old_configuration_files ()
393                 int old_version = current_version - 1;
394                 string old_config_dir = user_config_directory (old_version);
395                 string current_config_dir = user_config_directory (current_version);
396
397                 if (ui_handler (old_config_dir, current_config_dir, old_version)) {
398                         copy_configuration_files (old_config_dir, current_config_dir, old_version);
399                         return 1;
400                 }
401         }
402         return 0;
403 }
404
405 bool
406 ARDOUR::init (bool use_windows_vst, bool try_optimization, const char* localedir)
407 {
408         if (libardour_initialized) {
409                 return true;
410         }
411
412         if (!PBD::init()) return false;
413
414 #ifdef ENABLE_NLS
415         (void) bindtextdomain(PACKAGE, localedir);
416         (void) bind_textdomain_codeset (PACKAGE, "UTF-8");
417 #endif
418
419         SessionEvent::init_event_pool ();
420
421         Operations::make_operations_quarks ();
422         SessionObject::make_property_quarks ();
423         Region::make_property_quarks ();
424         MidiRegion::make_property_quarks ();
425         AudioRegion::make_property_quarks ();
426         RouteGroup::make_property_quarks ();
427         Playlist::make_property_quarks ();
428         AudioPlaylist::make_property_quarks ();
429
430         /* this is a useful ready to use PropertyChange that many
431            things need to check. This avoids having to compose
432            it every time we want to check for any of the relevant
433            property changes.
434         */
435
436         bounds_change.add (ARDOUR::Properties::start);
437         bounds_change.add (ARDOUR::Properties::position);
438         bounds_change.add (ARDOUR::Properties::length);
439
440         /* provide a state version for the few cases that need it and are not
441            driven by reading state from disk (e.g. undo/redo)
442         */
443
444         Stateful::current_state_version = CURRENT_SESSION_FILE_VERSION;
445
446         ARDOUR::setup_enum_writer ();
447
448         // allow ardour the absolute maximum number of open files
449         lotsa_files_please ();
450
451 #ifdef HAVE_LRDF
452         lrdf_init();
453 #endif
454         Library = new AudioLibrary;
455
456         BootMessage (_("Loading configuration"));
457
458         Config = new RCConfiguration;
459
460         if (Config->load_state ()) {
461                 return false;
462         }
463
464         Config->set_use_windows_vst (use_windows_vst);
465 #ifdef LXVST_SUPPORT
466         Config->set_use_lxvst(true);
467 #endif
468
469         Profile = new RuntimeProfile;
470
471
472 #ifdef WINDOWS_VST_SUPPORT
473         if (Config->get_use_windows_vst() && fst_init (0)) {
474                 return false;
475         }
476 #endif
477
478 #ifdef LXVST_SUPPORT
479         if (Config->get_use_lxvst() && vstfx_init (0)) {
480                 return false;
481         }
482 #endif
483
484 #ifdef AUDIOUNIT_SUPPORT
485         AUPluginInfo::load_cached_info ();
486 #endif
487
488         setup_hardware_optimization (try_optimization);
489
490         SourceFactory::init ();
491         Analyser::init ();
492
493         /* singletons - first object is "it" */
494         (void) PluginManager::instance();
495 #ifdef LV2_SUPPORT
496         (void) URIMap::instance();
497 #endif
498         (void) EventTypeMap::instance();
499
500         ProcessThread::init ();
501         /* the + 4 is a bit of a handwave. i don't actually know
502            how many more per-thread buffer sets we need above
503            the h/w concurrency, but its definitely > 1 more.
504         */
505         BufferManager::init (hardware_concurrency() + 4);
506
507         PannerManager::instance().discover_panners();
508
509         ARDOUR::AudioEngine::create ();
510
511         /* it is unfortunate that we need to include reserved names here that
512            refer to control surfaces. But there's no way to ensure a complete
513            lack of collisions without doing this, since the control surface
514            support may not even be active. Without adding an API to control
515            surface support that would list their port names, we do have to
516            list them here.
517         */
518         
519         char const * const reserved[] = {
520                 _("Monitor"),
521                 _("Master"),
522                 _("Control"),
523                 _("Click"),
524                 _("Mackie"),
525                 0
526         };
527
528         for (int n = 0; reserved[n]; ++n) {
529                 reserved_io_names.push_back (reserved[n]);
530         }
531         
532         libardour_initialized = true;
533
534         return true;
535 }
536
537 void
538 ARDOUR::init_post_engine ()
539 {
540         ControlProtocolManager::instance().discover_control_protocols ();
541
542         XMLNode* node;
543         if ((node = Config->control_protocol_state()) != 0) {
544                 ControlProtocolManager::instance().set_state (*node, Stateful::loading_state_version);
545         }
546
547         /* find plugins */
548
549         ARDOUR::PluginManager::instance().refresh (!Config->get_discover_vst_on_start());
550 }
551
552 void
553 ARDOUR::cleanup ()
554 {
555         if (!libardour_initialized) {
556                 return;
557         }
558
559         ARDOUR::AudioEngine::destroy ();
560
561         delete Library;
562 #ifdef HAVE_LRDF
563         lrdf_cleanup ();
564 #endif
565         delete &ControlProtocolManager::instance();
566 #ifdef WINDOWS_VST_SUPPORT
567         fst_exit ();
568 #endif
569
570 #ifdef LXVST_SUPPORT
571         vstfx_exit();
572 #endif
573         delete &PluginManager::instance();
574         delete Config;
575         PBD::cleanup ();
576
577         return;
578 }
579
580 void
581 ARDOUR::find_bindings_files (map<string,string>& files)
582 {
583         vector<std::string> found;
584         Searchpath spath = ardour_config_search_path();
585
586         if (getenv ("ARDOUR_SAE")) {
587                 find_files_matching_pattern (found, spath, "*SAE-*.bindings");
588         } else {
589                 find_files_matching_pattern (found, spath, "*.bindings");
590         }
591
592         if (found.empty()) {
593                 return;
594         }
595
596         for (vector<std::string>::iterator x = found.begin(); x != found.end(); ++x) {
597                 std::string path(*x);
598                 pair<string,string> namepath;
599                 namepath.second = path;
600                 namepath.first = PBD::basename_nosuffix (path);
601                 files.insert (namepath);
602         }
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         return true;
725 }
726
727
728 vector<SyncSource>
729 ARDOUR::get_available_sync_options ()
730 {
731         vector<SyncSource> ret;
732
733         boost::shared_ptr<AudioBackend> backend = AudioEngine::instance()->current_backend();
734         if (backend && backend->name() == "JACK") {
735                 ret.push_back (Engine);
736         }
737
738         ret.push_back (MTC);
739         ret.push_back (MIDIClock);
740         ret.push_back (LTC);
741
742         return ret;
743 }
744
745 /** Return a monotonic value for the number of microseconds that have elapsed
746  * since an arbitrary zero origin.
747  */
748
749 #ifdef __MACH__
750 /* Thanks Apple for not implementing this basic SUSv2, POSIX.1-2001 function
751  */
752 #include <mach/mach_time.h>
753 #define CLOCK_REALTIME 0
754 #define CLOCK_MONOTONIC 0
755 int
756 clock_gettime (int /*clk_id*/, struct timespec *t)
757 {
758         static bool initialized = false;
759         static mach_timebase_info_data_t timebase;
760         if (!initialized) {
761                 mach_timebase_info(&timebase);
762                 initialized = true;
763         }
764         uint64_t time;
765         time = mach_absolute_time();
766         double nseconds = ((double)time * (double)timebase.numer)/((double)timebase.denom);
767         double seconds = ((double)time * (double)timebase.numer)/((double)timebase.denom * 1e9);
768         t->tv_sec = seconds;
769         t->tv_nsec = nseconds;
770         return 0;
771 }
772 #endif
773
774 microseconds_t
775 ARDOUR::get_microseconds ()
776 {
777 #ifdef PLATFORM_WINDOWS
778         microseconds_t ret = 0;
779         LARGE_INTEGER freq, time;
780
781         if (QueryPerformanceFrequency(&freq))
782                 if (QueryPerformanceCounter(&time))
783                         ret = (microseconds_t)((time.QuadPart * 1000000) / freq.QuadPart);
784
785         return ret;
786 #else
787         struct timespec ts;
788         if (clock_gettime (CLOCK_MONOTONIC, &ts) != 0) {
789                 /* EEEK! */
790                 return 0;
791         }
792         return (microseconds_t) ts.tv_sec * 1000000 + (ts.tv_nsec/1000);
793 #endif
794 }
795
796 /** Return the number of bits per sample for a given sample format.
797  *
798  * This is closely related to sndfile_data_width() but does NOT
799  * return a "magic" value to differentiate between 32 bit integer
800  * and 32 bit floating point values.
801  */
802
803 int
804 ARDOUR::format_data_width (ARDOUR::SampleFormat format)
805 {
806
807
808
809         switch (format) {
810         case ARDOUR::FormatInt16:
811                 return 16;
812         case ARDOUR::FormatInt24:
813                 return 24;
814         default:
815                 return 32;
816         }
817 }