weak/runtime jack linking: load libjack dynamically at runtime
[ardour.git] / libs / backends / jack / jack_audiobackend.cc
index 8df97a1e303e41589df44829cfbb5d397e8e50ad..64991c16231fff4bff29d84cf8f0d9e5dba0514f 100644 (file)
@@ -27,9 +27,6 @@
 
 #include "pbd/error.h"
 
-#include "jack/jack.h"
-#include "jack/thread.h"
-
 #include "ardour/audioengine.h"
 #include "ardour/session.h"
 #include "ardour/types.h"
@@ -50,14 +47,13 @@ using std::vector;
 #define GET_PRIVATE_JACK_POINTER(localvar)  jack_client_t* localvar = _jack_connection->jack(); if (!(localvar)) { return; }
 #define GET_PRIVATE_JACK_POINTER_RET(localvar,r) jack_client_t* localvar = _jack_connection->jack(); if (!(localvar)) { return r; }
 
-JACKAudioBackend::JACKAudioBackend (AudioEngine& e, boost::shared_ptr<JackConnection> jc)
-       : AudioBackend (e)
+JACKAudioBackend::JACKAudioBackend (AudioEngine& e, AudioBackendInfo& info, boost::shared_ptr<JackConnection> jc)
+       : AudioBackend (e, info)
        , _jack_connection (jc)
        , _running (false)
        , _freewheeling (false)
        , _target_sample_rate (48000)
        , _target_buffer_size (1024)
-       , _target_sample_format (FormatFloat)
        , _target_interleaved (false)
        , _target_input_channels (0)
        , _target_output_channels (0)
@@ -267,18 +263,6 @@ JACKAudioBackend::set_buffer_size (uint32_t nframes)
        return jack_set_buffer_size (_priv_jack, nframes);
 }
 
-int
-JACKAudioBackend::set_sample_format (SampleFormat sf)
-{
-       /* as far as JACK clients are concerned, the hardware is always
-        * floating point format.
-        */
-       if (sf == FormatFloat) {
-               return 0;
-       }
-       return -1;
-}
-
 int
 JACKAudioBackend::set_interleaved (bool yn)
 {
@@ -397,12 +381,6 @@ JACKAudioBackend::buffer_size () const
        return _target_buffer_size;
 }
 
-SampleFormat
-JACKAudioBackend::sample_format () const
-{
-       return FormatFloat;
-}
-
 bool
 JACKAudioBackend::interleaved () const
 {
@@ -573,6 +551,7 @@ JACKAudioBackend::_start (bool for_latency_measurement)
 int
 JACKAudioBackend::stop ()
 {
+       _running = false; // no 'engine halted message'.
        GET_PRIVATE_JACK_POINTER_RET (_priv_jack, -1);
        
        _jack_connection->close ();
@@ -765,11 +744,9 @@ int
 JACKAudioBackend::jack_sync_callback (jack_transport_state_t state, jack_position_t* pos)
 {
        TransportState tstate;
+       bool tstate_valid = true;
 
        switch (state) {
-       case JackTransportStopped:
-               tstate = TransportStopped;
-               break;
        case JackTransportRolling:
                tstate = TransportRolling;
                break;
@@ -779,9 +756,18 @@ JACKAudioBackend::jack_sync_callback (jack_transport_state_t state, jack_positio
        case JackTransportStarting:
                tstate = TransportStarting;
                break;
+       case JackTransportStopped:
+               tstate = TransportStopped;
+               break;
+       default:
+               // ignore "unofficial" states like JackTransportNetStarting (jackd2)
+               tstate_valid = false;
+               break;
        }
 
-       return engine.sync_callback (tstate, pos->frame);
+       if (tstate_valid) {
+               return engine.sync_callback (tstate, pos->frame);
+       }
 
        return true;
 }
@@ -873,6 +859,16 @@ JACKAudioBackend::join_process_threads ()
 bool
 JACKAudioBackend::in_process_thread ()
 {
+#ifdef COMPILER_MINGW
+       if (_main_thread == GetCurrentThread()) {
+               return true;
+       }
+#else // pthreads
+       if (pthread_equal (_main_thread, pthread_self()) != 0) {
+               return true;
+       }
+#endif
+
        for (std::vector<jack_native_thread_t>::const_iterator i = _jack_threads.begin ();
             i != _jack_threads.end(); i++) {
 
@@ -920,6 +916,13 @@ JACKAudioBackend::process_thread ()
         /* JACK doesn't do this for us when we use the wait API
          */
 
+#ifdef COMPILER_MINGW
+       _main_thread = GetCurrentThread();
+#else
+       _main_thread = pthread_self ();
+#endif
+
+
         AudioEngine::thread_init_callback (this);
 
         while (1) {
@@ -1015,7 +1018,7 @@ JACKAudioBackend::disconnected (const char* why)
 }
 
 float 
-JACKAudioBackend::cpu_load() const 
+JACKAudioBackend::dsp_load() const 
 {
        GET_PRIVATE_JACK_POINTER_RET(_priv_jack,0);
        return jack_cpu_load (_priv_jack);
@@ -1087,6 +1090,8 @@ JACKAudioBackend::control_app_name () const
                                appname = "hdspconf";
                        } else if (_target_device == "M Audio Delta 1010") {
                                appname = "mudita24";
+                       } else if (_target_device == "M2496") {
+                               appname = "mudita24";
                        }
                }
        } else {
@@ -1160,9 +1165,18 @@ JACKAudioBackend::speed_and_position (double& speed, framepos_t& position)
                // don't adjust speed here, just leave it as it was
                break;
        default:
+               starting = true; // jack2: JackTransportNetStarting
                std::cerr << "WARNING: Unknown JACK transport state: " << state << std::endl;
        }
 
        position = pos.frame;
        return starting;
 }
+
+int
+JACKAudioBackend::reset_device ()
+{
+        /* XXX need to figure out what this means for JACK
+         */
+        return 0;
+}