finished merge of cairocanvas with windows and windows+cc branches
[ardour.git] / libs / ardour / globals.cc
index 1406bbd43ac3eb225c68c51f934424acfbd14ce3..5874ac3b1b25d183cea69ba2766e2497605947b8 100644 (file)
@@ -35,6 +35,7 @@
 #include <unistd.h>
 #include <fcntl.h>
 #include <errno.h>
+#include <time.h>
 
 #ifdef WINDOWS_VST_SUPPORT
 #include <fst.h>
 #include "pbd/basename.h"
 
 #include "midi++/port.h"
-#include "midi++/manager.h"
 #include "midi++/mmc.h"
 
 #include "ardour/analyser.h"
 #include "ardour/audio_library.h"
+#include "ardour/audio_backend.h"
 #include "ardour/audioengine.h"
 #include "ardour/audioplaylist.h"
 #include "ardour/audioregion.h"
@@ -86,6 +87,7 @@
 #include "ardour/control_protocol_manager.h"
 #include "ardour/filesystem_paths.h"
 #include "ardour/midi_region.h"
+#include "ardour/midiport_manager.h"
 #include "ardour/mix.h"
 #include "ardour/panner_manager.h"
 #include "ardour/plugin_manager.h"
@@ -342,6 +344,8 @@ ARDOUR::init (bool use_windows_vst, bool try_optimization, const char* localedir
        EventTypeMap::instance().new_parameter(EnvelopeAutomation);
        EventTypeMap::instance().new_parameter(MidiCCAutomation);
 
+       ARDOUR::AudioEngine::create ();
+
        libardour_initialized = true;
 
        return true;
@@ -350,9 +354,6 @@ ARDOUR::init (bool use_windows_vst, bool try_optimization, const char* localedir
 void
 ARDOUR::init_post_engine ()
 {
-       /* the MIDI Manager is needed by the ControlProtocolManager */
-       MIDI::Manager::create (AudioEngine::instance()->jack());
-
        ControlProtocolManager::instance().discover_control_protocols ();
 
        XMLNode* node;
@@ -365,9 +366,15 @@ ARDOUR::init_post_engine ()
        ARDOUR::PluginManager::instance().refresh ();
 }
 
-int
-ARDOUR::cleanup ()
+void
+ARDOUR::cleanup () 
 {
+       if (!libardour_initialized) {
+               return;
+       }
+
+       ARDOUR::AudioEngine::destroy ();
+
        delete Library;
 #ifdef HAVE_LRDF
        lrdf_cleanup ();
@@ -381,7 +388,8 @@ ARDOUR::cleanup ()
        vstfx_exit();
 #endif
        PBD::cleanup ();
-       return 0;
+
+       return;
 }
 
 void
@@ -531,8 +539,8 @@ ARDOUR::set_translations_enabled (bool yn)
                c = '0';
        }
        
-       ::write (fd, &c, 1);
-       ::close (fd);
+       (void) ::write (fd, &c, 1);
+       (void) ::close (fd);
 
        return true;
 }
@@ -543,10 +551,65 @@ ARDOUR::get_available_sync_options ()
 {
        vector<SyncSource> ret;
 
-       ret.push_back (JACK);
+       boost::shared_ptr<AudioBackend> backend = AudioEngine::instance()->current_backend();
+       if (backend && backend->name() == "JACK") {
+               ret.push_back (Engine);
+       }
+
        ret.push_back (MTC);
        ret.push_back (MIDIClock);
        ret.push_back (LTC);
 
        return ret;
 }
+
+/** Return a monotonic value for the number of microseconds that have elapsed
+ * since an arbitrary zero origin.
+ */
+
+#ifdef __MACH__
+/* Thanks Apple for not implementing this basic SUSv2, POSIX.1-2001 function
+ */
+#include <mach/mach_time.h>
+#define CLOCK_REALTIME 0
+#define CLOCK_MONOTONIC 0
+int 
+clock_gettime (int /*clk_id*/, struct timespec *t)
+{
+        static bool initialized = false;
+        static mach_timebase_info_data_t timebase;
+        if (!initialized) {
+                mach_timebase_info(&timebase);
+                initialized = true;
+        }
+        uint64_t time;
+        time = mach_absolute_time();
+        double nseconds = ((double)time * (double)timebase.numer)/((double)timebase.denom);
+        double seconds = ((double)time * (double)timebase.numer)/((double)timebase.denom * 1e9);
+        t->tv_sec = seconds;
+        t->tv_nsec = nseconds;
+        return 0;
+}
+#endif
+microseconds_t
+ARDOUR::get_microseconds ()
+{
+#ifdef PLATFORM_WINDOWS
+       microseconds_t ret = 0;
+       LARGE_INTEGER freq, time;
+
+       if (QueryPerformanceFrequency(&freq))
+               if (QueryPerformanceCounter(&time))
+                       ret = (microseconds_t)((time.QuadPart * 1000000) / freq.QuadPart);
+
+       return ret;
+#else
+       struct timespec ts;
+       if (clock_gettime (CLOCK_MONOTONIC, &ts) != 0) {
+               /* EEEK! */
+               return 0;
+       }
+       return (microseconds_t) ts.tv_sec * 1000000 + (ts.tv_nsec/1000);
+#endif
+}