2 * Copyright (C) 2005-2019 Paul Davis <paul@linuxaudiosystems.com>
3 * Copyright (C) 2005 Taybin Rutkin <taybin@taybin.com>
4 * Copyright (C) 2006-2008 Doug McLain <doug@nostar.net>
5 * Copyright (C) 2006-2015 David Robillard <d@drobilla.net>
6 * Copyright (C) 2006-2017 Tim Mayberry <mojofunk@gmail.com>
7 * Copyright (C) 2006 Sampo Savolainen <v2@iki.fi>
8 * Copyright (C) 2009-2012 Carl Hetherington <carl@carlh.net>
9 * Copyright (C) 2012-2019 Robin Gareus <robin@gareus.org>
10 * Copyright (C) 2013-2015 John Emmas <john@creativepost.co.uk>
12 * This program is free software; you can redistribute it and/or modify
13 * it under the terms of the GNU General Public License as published by
14 * the Free Software Foundation; either version 2 of the License, or
15 * (at your option) any later version.
17 * This program is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 * GNU General Public License for more details.
22 * You should have received a copy of the GNU General Public License along
23 * with this program; if not, write to the Free Software Foundation, Inc.,
24 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
28 #include "libardour-config.h"
35 #include <cstdio> // Needed so that libraptor (included in lrdf) won't complain
38 #include <sys/types.h>
40 #ifndef PLATFORM_WINDOWS
41 #include <sys/resource.h>
49 #include "pbd/gstdio_compat.h"
51 #ifdef PLATFORM_WINDOWS
52 #include <stdio.h> // for _setmaxstdio
53 #include <windows.h> // for LARGE_INTEGER
60 #ifdef WINDOWS_VST_SUPPORT
65 #include "ardour/linux_vst_support.h"
68 #ifdef AUDIOUNIT_SUPPORT
69 #include "ardour/audio_unit.h"
72 #if defined(__SSE__) || defined(USE_XMMINTRIN)
73 #include <xmmintrin.h>
77 #undef check /* stupid Apple and their un-namespaced, generic Carbon macros */
80 #include <glibmm/fileutils.h>
81 #include <glibmm/miscutils.h>
88 #include "pbd/error.h"
91 #include "pbd/strsplit.h"
93 #include "pbd/file_utils.h"
94 #include "pbd/enumwriter.h"
96 #include "midi++/port.h"
97 #include "midi++/mmc.h"
99 #include "LuaBridge/LuaBridge.h"
101 #include "ardour/analyser.h"
102 #include "ardour/audio_library.h"
103 #include "ardour/audio_backend.h"
104 #include "ardour/audioengine.h"
105 #include "ardour/audioplaylist.h"
106 #include "ardour/audioregion.h"
107 #include "ardour/buffer_manager.h"
108 #include "ardour/control_protocol_manager.h"
109 #include "ardour/directory_names.h"
110 #include "ardour/event_type_map.h"
111 #include "ardour/filesystem_paths.h"
112 #include "ardour/midi_region.h"
113 #include "ardour/midi_ui.h"
114 #include "ardour/midiport_manager.h"
115 #include "ardour/mix.h"
116 #include "ardour/operations.h"
117 #include "ardour/panner_manager.h"
118 #include "ardour/plugin_manager.h"
119 #include "ardour/presentation_info.h"
120 #include "ardour/process_thread.h"
121 #include "ardour/profile.h"
122 #include "ardour/rc_configuration.h"
123 #include "ardour/region.h"
124 #include "ardour/route_group.h"
125 #include "ardour/runtime_functions.h"
126 #include "ardour/session_event.h"
127 #include "ardour/source_factory.h"
128 #include "ardour/transport_fsm.h"
129 #include "ardour/transport_master_manager.h"
131 #include "ardour/uri_map.h"
133 #include "audiographer/routines.h"
135 #if defined (__APPLE__)
136 #include <CoreFoundation/CoreFoundation.h>
139 #include "pbd/i18n.h"
141 ARDOUR::RCConfiguration* ARDOUR::Config = 0;
142 ARDOUR::RuntimeProfile* ARDOUR::Profile = 0;
143 ARDOUR::AudioLibrary* ARDOUR::Library = 0;
145 using namespace ARDOUR;
149 bool libardour_initialized = false;
151 compute_peak_t ARDOUR::compute_peak = 0;
152 find_peaks_t ARDOUR::find_peaks = 0;
153 apply_gain_to_buffer_t ARDOUR::apply_gain_to_buffer = 0;
154 mix_buffers_with_gain_t ARDOUR::mix_buffers_with_gain = 0;
155 mix_buffers_no_gain_t ARDOUR::mix_buffers_no_gain = 0;
156 copy_vector_t ARDOUR::copy_vector = 0;
158 PBD::Signal1<void,std::string> ARDOUR::BootMessage;
159 PBD::Signal3<void,std::string,std::string,bool> ARDOUR::PluginScanMessage;
160 PBD::Signal1<void,int> ARDOUR::PluginScanTimeout;
161 PBD::Signal0<void> ARDOUR::GUIIdle;
162 PBD::Signal3<bool,std::string,std::string,int> ARDOUR::CopyConfigurationFiles;
164 std::map<std::string, bool> ARDOUR::reserved_io_names;
166 static bool have_old_configuration_files = false;
167 static bool running_from_gui = false;
170 extern void setup_enum_writer ();
173 /* this is useful for quite a few things that want to check
174 if any bounds-related property has changed
176 PBD::PropertyChange ARDOUR::bounds_change;
178 static PBD::ScopedConnection engine_startup_connection;
181 setup_hardware_optimization (bool try_optimization)
183 bool generic_mix_functions = true;
185 if (try_optimization) {
187 FPU* fpu = FPU::instance();
189 #if defined (ARCH_X86) && defined (BUILD_SSE_OPTIMIZATIONS)
191 #ifdef PLATFORM_WINDOWS
192 /* We have AVX-optimized code for Windows */
195 /* AVX code doesn't compile on Linux yet */
199 info << "Using AVX optimized routines" << endmsg;
202 compute_peak = x86_sse_avx_compute_peak;
203 find_peaks = x86_sse_avx_find_peaks;
204 apply_gain_to_buffer = x86_sse_avx_apply_gain_to_buffer;
205 mix_buffers_with_gain = x86_sse_avx_mix_buffers_with_gain;
206 mix_buffers_no_gain = x86_sse_avx_mix_buffers_no_gain;
207 copy_vector = x86_sse_avx_copy_vector;
209 generic_mix_functions = false;
211 } else if (fpu->has_sse()) {
213 info << "Using SSE optimized routines" << endmsg;
216 compute_peak = x86_sse_compute_peak;
217 find_peaks = x86_sse_find_peaks;
218 apply_gain_to_buffer = x86_sse_apply_gain_to_buffer;
219 mix_buffers_with_gain = x86_sse_mix_buffers_with_gain;
220 mix_buffers_no_gain = x86_sse_mix_buffers_no_gain;
221 copy_vector = default_copy_vector;
223 generic_mix_functions = false;
227 #elif defined (__APPLE__) && defined (BUILD_VECLIB_OPTIMIZATIONS)
229 if (floor (kCFCoreFoundationVersionNumber) > kCFCoreFoundationVersionNumber10_4) { /* at least Tiger */
230 compute_peak = veclib_compute_peak;
231 find_peaks = veclib_find_peaks;
232 apply_gain_to_buffer = veclib_apply_gain_to_buffer;
233 mix_buffers_with_gain = veclib_mix_buffers_with_gain;
234 mix_buffers_no_gain = veclib_mix_buffers_no_gain;
235 copy_vector = default_copy_vector;
237 generic_mix_functions = false;
239 info << "Apple VecLib H/W specific optimizations in use" << endmsg;
243 /* consider FPU denormal handling to be "h/w optimization" */
248 if (generic_mix_functions) {
250 compute_peak = default_compute_peak;
251 find_peaks = default_find_peaks;
252 apply_gain_to_buffer = default_apply_gain_to_buffer;
253 mix_buffers_with_gain = default_mix_buffers_with_gain;
254 mix_buffers_no_gain = default_mix_buffers_no_gain;
255 copy_vector = default_copy_vector;
257 info << "No H/W specific optimizations in use" << endmsg;
260 AudioGrapher::Routines::override_compute_peak (compute_peak);
261 AudioGrapher::Routines::override_apply_gain_to_buffer (apply_gain_to_buffer);
265 lotsa_files_please ()
267 #ifndef PLATFORM_WINDOWS
270 if (getrlimit (RLIMIT_NOFILE, &rl) == 0) {
273 /* See the COMPATIBILITY note on the Apple setrlimit() man page */
274 rl.rlim_cur = min ((rlim_t) OPEN_MAX, rl.rlim_max);
276 rl.rlim_cur = rl.rlim_max;
279 if (setrlimit (RLIMIT_NOFILE, &rl) != 0) {
280 if (rl.rlim_cur == RLIM_INFINITY) {
281 error << _("Could not set system open files limit to \"unlimited\"") << endmsg;
283 error << string_compose (_("Could not set system open files limit to %1"), rl.rlim_cur) << endmsg;
286 if (rl.rlim_cur != RLIM_INFINITY) {
287 info << string_compose (_("Your system is configured to limit %1 to %2 open files"), PROGRAM_NAME, rl.rlim_cur) << endmsg;
291 error << string_compose (_("Could not get system open files limit (%1)"), strerror (errno)) << endmsg;
294 /* this only affects stdio. 2048 is the maxium possible (512 the default).
296 * If we want more, we'll have to replaces the POSIX I/O interfaces with
297 * Win32 API calls (CreateFile, WriteFile, etc) which allows for 16K.
299 * see http://stackoverflow.com/questions/870173/is-there-a-limit-on-number-of-open-files-in-windows
300 * and http://bugs.mysql.com/bug.php?id=24509
302 int newmax = _setmaxstdio (2048);
304 info << string_compose (_("Your system is configured to limit %1 to %2 open files"), PROGRAM_NAME, newmax) << endmsg;
306 error << string_compose (_("Could not set system open files limit. Current limit is %1 open files"), _getmaxstdio()) << endmsg;
312 copy_configuration_files (string const & old_dir, string const & new_dir, int old_version)
317 /* ensure target directory exists */
319 if (g_mkdir_with_parents (new_dir.c_str(), 0755)) {
323 if (old_version >= 3) {
325 old_name = Glib::build_filename (old_dir, X_("recent"));
326 new_name = Glib::build_filename (new_dir, X_("recent"));
328 copy_file (old_name, new_name);
330 old_name = Glib::build_filename (old_dir, X_("sfdb"));
331 new_name = Glib::build_filename (new_dir, X_("sfdb"));
333 copy_file (old_name, new_name);
335 /* can only copy ardour.rc/config - UI config is not compatible */
337 /* users who have been using git/nightlies since the last
338 * release of 3.5 will have $CONFIG/config rather than
339 * $CONFIG/ardour.rc. Pick up the newer "old" config file,
340 * to avoid confusion.
343 string old_name = Glib::build_filename (old_dir, X_("config"));
345 if (!Glib::file_test (old_name, Glib::FILE_TEST_EXISTS)) {
346 old_name = Glib::build_filename (old_dir, X_("ardour.rc"));
349 new_name = Glib::build_filename (new_dir, X_("config"));
351 copy_file (old_name, new_name);
353 /* copy templates and route templates */
355 old_name = Glib::build_filename (old_dir, X_("templates"));
356 new_name = Glib::build_filename (new_dir, X_("templates"));
358 copy_recurse (old_name, new_name);
360 old_name = Glib::build_filename (old_dir, X_("route_templates"));
361 new_name = Glib::build_filename (new_dir, X_("route_templates"));
363 copy_recurse (old_name, new_name);
367 old_name = Glib::build_filename (old_dir, X_("presets"));
368 new_name = Glib::build_filename (new_dir, X_("presets"));
370 copy_recurse (old_name, new_name);
373 g_mkdir_with_parents (Glib::build_filename (new_dir, plugin_metadata_dir_name).c_str(), 0755);
375 old_name = Glib::build_filename (old_dir, X_("plugin_statuses")); /* until 6.0 */
376 new_name = Glib::build_filename (new_dir, plugin_metadata_dir_name, X_("plugin_statuses"));
377 copy_file (old_name, new_name); /* can fail silently */
379 old_name = Glib::build_filename (old_dir, plugin_metadata_dir_name, X_("plugin_statuses"));
380 copy_file (old_name, new_name);
384 old_name = Glib::build_filename (old_dir, plugin_metadata_dir_name, X_("plugin_tags"));
385 new_name = Glib::build_filename (new_dir, plugin_metadata_dir_name, X_("plugin_tags"));
387 copy_file (old_name, new_name);
391 old_name = Glib::build_filename (old_dir, export_formats_dir_name);
392 new_name = Glib::build_filename (new_dir, export_formats_dir_name);
394 vector<string> export_formats;
395 g_mkdir_with_parents (Glib::build_filename (new_dir, export_formats_dir_name).c_str(), 0755);
396 find_files_matching_pattern (export_formats, old_name, X_("*.format"));
397 for (vector<string>::iterator i = export_formats.begin(); i != export_formats.end(); ++i) {
398 std::string from = *i;
399 std::string to = Glib::build_filename (new_name, Glib::path_get_basename (*i));
400 copy_file (from, to);
408 ARDOUR::check_for_old_configuration_files ()
410 int current_version = atoi (X_(PROGRAM_VERSION));
412 if (current_version <= 1) {
416 int old_version = current_version - 1;
418 string old_config_dir = user_config_directory (old_version);
419 /* pass in the current version explicitly to avoid creation */
420 string current_config_dir = user_config_directory (current_version);
422 if (!Glib::file_test (current_config_dir, Glib::FILE_TEST_IS_DIR)) {
423 if (Glib::file_test (old_config_dir, Glib::FILE_TEST_IS_DIR)) {
424 have_old_configuration_files = true;
430 ARDOUR::handle_old_configuration_files (boost::function<bool (std::string const&, std::string const&, int)> ui_handler)
432 if (have_old_configuration_files) {
433 int current_version = atoi (X_(PROGRAM_VERSION));
434 assert (current_version > 1); // established in check_for_old_configuration_files ()
435 int old_version = current_version - 1;
436 string old_config_dir = user_config_directory (old_version);
437 string current_config_dir = user_config_directory (current_version);
439 if (ui_handler (old_config_dir, current_config_dir, old_version)) {
440 copy_configuration_files (old_config_dir, current_config_dir, old_version);
448 ARDOUR::init (bool use_windows_vst, bool try_optimization, const char* localedir, bool with_gui)
450 if (libardour_initialized) {
454 running_from_gui = with_gui;
457 if (getenv("ARDOUR_LUA_METATABLES")) {
458 luabridge::Security::setHideMetatables (false);
463 fftwf_make_planner_thread_safe ();
466 if (!PBD::init()) return false;
469 (void) bindtextdomain(PACKAGE, localedir);
470 (void) bind_textdomain_codeset (PACKAGE, "UTF-8");
473 SessionEvent::init_event_pool ();
474 TransportFSM::Event::init_pool ();
476 Operations::make_operations_quarks ();
477 SessionObject::make_property_quarks ();
478 Region::make_property_quarks ();
479 MidiRegion::make_property_quarks ();
480 AudioRegion::make_property_quarks ();
481 RouteGroup::make_property_quarks ();
482 Playlist::make_property_quarks ();
483 AudioPlaylist::make_property_quarks ();
484 PresentationInfo::make_property_quarks ();
485 TransportMaster::make_property_quarks ();
487 /* this is a useful ready to use PropertyChange that many
488 things need to check. This avoids having to compose
489 it every time we want to check for any of the relevant
493 bounds_change.add (ARDOUR::Properties::start);
494 bounds_change.add (ARDOUR::Properties::position);
495 bounds_change.add (ARDOUR::Properties::length);
497 /* provide a state version for the few cases that need it and are not
498 driven by reading state from disk (e.g. undo/redo)
501 Stateful::current_state_version = CURRENT_SESSION_FILE_VERSION;
503 ARDOUR::setup_enum_writer ();
505 // allow ardour the absolute maximum number of open files
506 lotsa_files_please ();
511 Library = new AudioLibrary;
513 BootMessage (_("Loading configuration"));
515 Config = new RCConfiguration;
517 if (Config->load_state ()) {
521 Config->set_use_windows_vst (use_windows_vst);
523 Config->set_use_lxvst(true);
526 Profile = new RuntimeProfile;
529 #ifdef WINDOWS_VST_SUPPORT
530 if (Config->get_use_windows_vst() && fst_init (0)) {
536 if (Config->get_use_lxvst() && vstfx_init (0)) {
541 #ifdef AUDIOUNIT_SUPPORT
542 AUPluginInfo::load_cached_info ();
545 setup_hardware_optimization (try_optimization);
547 SourceFactory::init ();
550 /* singletons - first object is "it" */
551 (void) PluginManager::instance();
553 (void) URIMap::instance();
555 (void) EventTypeMap::instance();
557 ControlProtocolManager::instance().discover_control_protocols ();
559 /* for each control protocol, check for a request buffer factory method
560 and if it exists, store it in the EventLoop list of such
561 methods. This allows the relevant threads to register themselves
562 with EventLoops so that signal emission can be RT-safe.
565 ControlProtocolManager::instance().register_request_buffer_factories ();
566 /* it would be nice if this could auto-register itself in the
567 constructor, since MidiControlUI is a singleton, but it can't be
568 created until after the engine is running. Therefore we have to
569 explicitly register it here.
571 EventLoop::register_request_buffer_factory (X_("midiUI"), MidiControlUI::request_factory);
573 /* the + 4 is a bit of a handwave. i don't actually know
574 how many more per-thread buffer sets we need above
575 the h/w concurrency, but its definitely > 1 more.
577 BufferManager::init (hardware_concurrency() + 4);
579 PannerManager::instance().discover_panners();
581 ARDOUR::AudioEngine::create ();
582 TransportMasterManager::create ();
584 /* it is unfortunate that we need to include reserved names here that
585 refer to control surfaces. But there's no way to ensure a complete
586 lack of collisions without doing this, since the control surface
587 support may not even be active. Without adding an API to control
588 surface support that would list their port names, we do have to
591 We also need to know if the given I/O is an actual route.
592 For routes (e.g. "master"), bus creation needs to be allowed the first time,
593 while for pure I/O (e.g. "Click") track/bus creation must always fail.
596 reserved_io_names[_("Monitor")] = true;
597 reserved_io_names[_("Master")] = true;
598 reserved_io_names["auditioner"] = true; // auditioner.cc Track (s, "auditioner",...)
599 reserved_io_names[_("Virtual Keyboard")] = false;
602 reserved_io_names[X_("Click")] = false; // session.cc ClickIO (*this, X_("Click")
603 reserved_io_names[_("Control")] = false;
604 reserved_io_names[_("Mackie")] = false;
605 reserved_io_names[_("FaderPort Recv")] = false;
606 reserved_io_names[_("FaderPort Send")] = false;
607 reserved_io_names[_("FaderPort2 Recv")] = false;
608 reserved_io_names[_("FaderPort2 Send")] = false;
609 reserved_io_names[_("FaderPort8 Recv")] = false;
610 reserved_io_names[_("FaderPort8 Send")] = false;
611 reserved_io_names[_("FaderPort16 Recv")] = false;
612 reserved_io_names[_("FaderPort16 Send")] = false;
614 libardour_initialized = true;
620 ARDOUR::init_post_engine (uint32_t start_cnt)
624 if (start_cnt == 0) {
626 if (!running_from_gui) {
628 /* find plugins, but only using the existing cache (i.e. do
629 * not discover new ones. GUIs are responsible for
630 * invoking this themselves after the engine is
631 * started, with whatever options they want.
634 ARDOUR::PluginManager::instance().refresh (true);
637 if ((node = Config->control_protocol_state()) != 0) {
638 ControlProtocolManager::instance().set_state (*node, 0 /* here: global-config state */);
643 TransportMasterManager::instance().restart ();
650 if (!libardour_initialized) {
654 engine_startup_connection.disconnect ();
656 delete &ControlProtocolManager::instance();
657 ARDOUR::AudioEngine::destroy ();
663 #ifdef WINDOWS_VST_SUPPORT
670 delete &PluginManager::instance();
678 ARDOUR::no_auto_connect()
680 return getenv ("ARDOUR_NO_AUTOCONNECT") != 0;
686 FPU* fpu = FPU::instance ();
688 if (getenv ("ARDOUR_RUNNING_UNDER_VALGRIND")) {
689 // valgrind doesn't understand this assembler stuff
690 // September 10th, 2007
694 #if defined(ARCH_X86) && defined(USE_XMMINTRIN)
695 /* see also https://carlh.net/plugins/denormals.php */
699 if (!fpu->has_flush_to_zero() && !fpu->has_denormals_are_zero()) {
703 MXCSR = _mm_getcsr();
705 #ifdef DEBUG_DENORMAL_EXCEPTION
706 /* This will raise a FP exception if a denormal is detected */
707 MXCSR &= ~_MM_MASK_DENORM;
710 switch (Config->get_denormal_model()) {
712 MXCSR &= ~(_MM_FLUSH_ZERO_ON | 0x40);
716 if (fpu->has_flush_to_zero()) {
717 MXCSR |= _MM_FLUSH_ZERO_ON;
722 MXCSR &= ~_MM_FLUSH_ZERO_ON;
723 if (fpu->has_denormals_are_zero()) {
729 if (fpu->has_flush_to_zero()) {
730 if (fpu->has_denormals_are_zero()) {
731 MXCSR |= _MM_FLUSH_ZERO_ON | 0x40;
733 MXCSR |= _MM_FLUSH_ZERO_ON;
741 #elif defined(__aarch64__)
742 /* http://infocenter.arm.com/help/topic/com.arm.doc.ddi0488d/CIHCACFF.html
743 * bit 24: flush-to-zero */
744 if (Config->get_denormal_model() != DenormalNone) {
746 __asm__ __volatile__ (
748 "orr %0, %0, #0x1000000 \n"
751 : "=r"(cw) :: "memory");
754 #elif defined(__arm__)
755 /* http://infocenter.arm.com/help/topic/com.arm.doc.dui0068b/BCFHFBGA.html
756 * bit 24: flush-to-zero */
757 if (Config->get_denormal_model() != DenormalNone) {
759 __asm__ __volatile__ (
761 "orr %0, %0, #0x1000000 \n"
763 : "=r"(cw) :: "memory");
769 /* this can be changed to modify the translation behaviour for
770 cases where the user has never expressed a preference.
772 static const bool translate_by_default = true;
775 ARDOUR::translation_enable_path ()
777 return Glib::build_filename (user_config_directory(), ".translate");
781 ARDOUR::translations_are_enabled ()
783 int fd = g_open (ARDOUR::translation_enable_path().c_str(), O_RDONLY, 0444);
786 return translate_by_default;
792 if (::read (fd, &c, 1) == 1 && c == '1') {
802 ARDOUR::set_translations_enabled (bool yn)
804 string i18n_enabler = ARDOUR::translation_enable_path();
805 int fd = g_open (i18n_enabler.c_str(), O_WRONLY|O_CREAT|O_TRUNC, 0644);
819 (void) ::write (fd, &c, 1);
822 Config->ParameterChanged ("enable-translation");
828 ARDOUR::get_available_sync_options ()
830 vector<SyncSource> ret;
832 boost::shared_ptr<AudioBackend> backend = AudioEngine::instance()->current_backend();
833 if (backend && backend->name() == "JACK") {
834 ret.push_back (Engine);
838 ret.push_back (MIDIClock);
844 /** Return a monotonic value for the number of microseconds that have elapsed
845 * since an arbitrary zero origin.
849 /* Thanks Apple for not implementing this basic SUSv2, POSIX.1-2001 function
851 #include <mach/mach_time.h>
852 #define CLOCK_REALTIME 0
853 #define CLOCK_MONOTONIC 0
855 clock_gettime (int /*clk_id*/, struct timespec *t)
857 static bool initialized = false;
858 static mach_timebase_info_data_t timebase;
860 mach_timebase_info(&timebase);
864 time = mach_absolute_time();
865 double nseconds = ((double)time * (double)timebase.numer)/((double)timebase.denom);
866 double seconds = ((double)time * (double)timebase.numer)/((double)timebase.denom * 1e9);
868 t->tv_nsec = nseconds;
874 ARDOUR::get_microseconds ()
876 #ifdef PLATFORM_WINDOWS
877 microseconds_t ret = 0;
878 LARGE_INTEGER freq, time;
880 if (QueryPerformanceFrequency(&freq))
881 if (QueryPerformanceCounter(&time))
882 ret = (microseconds_t)((time.QuadPart * 1000000) / freq.QuadPart);
887 if (clock_gettime (CLOCK_MONOTONIC, &ts) != 0) {
891 return (microseconds_t) ts.tv_sec * 1000000 + (ts.tv_nsec/1000);
895 /** Return the number of bits per sample for a given sample format.
897 * This is closely related to sndfile_data_width() but does NOT
898 * return a "magic" value to differentiate between 32 bit integer
899 * and 32 bit floating point values.
903 ARDOUR::format_data_width (ARDOUR::SampleFormat format)
909 case ARDOUR::FormatInt16:
911 case ARDOUR::FormatInt24: