headless: Use direct x-thread wakeup instead of sleep/spin
[ardour.git] / headless / load_session.cc
index 712e32c168a69f4bbc52966758c9bf50baad623b..47fd5151b19f3d084a1a7d947b1eb88b31ce54b3 100644 (file)
@@ -2,33 +2,42 @@
 #include <cstdlib>
 #include <getopt.h>
 
+#ifndef PLATFORM_WINDOWS
+#include <signal.h>
+#endif
+
+#include <glibmm.h>
+
+#include "pbd/convert.h"
+#include "pbd/crossthread.h"
 #include "pbd/failed_constructor.h"
 #include "pbd/error.h"
 #include "pbd/debug.h"
 
 #include "ardour/ardour.h"
 #include "ardour/audioengine.h"
+#include "ardour/revision.h"
 #include "ardour/session.h"
 
+#include "control_protocol/control_protocol.h"
+
 #include "misc.h"
 
 using namespace std;
 using namespace ARDOUR;
 using namespace PBD;
 
-#ifdef PLATFORM_WINDOWS
-#include <windows.h>
-#define sleep(X) Sleep((X) * 1000)
-#endif
-
 static const char* localedir = LOCALEDIR;
 
-TestReceiver test_receiver;
+static string backend_client_name;
+static string backend_name = "JACK";
+static CrossThreadChannel xthread (true);
+static TestReceiver test_receiver;
 
 /** @param dir Session directory.
  *  @param state Session state file, without .ardour suffix.
  */
-Session *
+static Session *
 load_session (string dir, string state)
 {
        SessionEvent::create_per_thread_pool ("test", 512);
@@ -40,8 +49,8 @@ load_session (string dir, string state)
 
        AudioEngine* engine = AudioEngine::create ();
 
-       if (!engine->set_default_backend ()) {
-               std::cerr << "Cannot create Audio/MIDI engine\n";
+       if (!engine->set_backend (backend_name, backend_client_name, "")) {
+               std::cerr << "Cannot set Audio/MIDI engine backend\n";
                ::exit (1);
        }
 
@@ -55,15 +64,50 @@ load_session (string dir, string state)
        return session;
 }
 
-string session_name = "";
-string backend_client_name = "ardour";
-string backend_session_uuid;
-bool just_version = false;
-bool use_vst = true;
-bool try_hw_optimization = true;
-bool no_connect_ports = false;
+static void
+access_action (const std::string& action_group, const std::string& action_item)
+{
+       if (action_group == "Common" && action_item == "Quit") {
+               xthread.deliver ('x');
+       }
+}
+
+static void
+engine_halted (const char* reason)
+{
+       cerr << "The audio backend has been shutdown";
+       if (reason && strlen (reason) > 0) {
+               cerr << ": " << reason;
+       } else {
+               cerr << ".";
+       }
+       cerr << endl;
+       xthread.deliver ('x');
+}
+
+#ifndef PLATFORM_WINDOWS
+static void wearedone (int) {
+       cerr << "caught signal - terminating." << endl;
+       xthread.deliver ('x');
+}
+#endif
+
+static void
+print_version ()
+{
+       cout
+               << PROGRAM_NAME
+               << VERSIONSTRING
+               << " (built using "
+               << ARDOUR::revision
+#ifdef __GNUC__
+               << " and GCC version " << __VERSION__
+#endif
+               << ')'
+               << endl;
+}
 
-void
+static void
 print_help ()
 {
        cout << "Usage: hardour [OPTIONS]... DIR SNAPSHOT_NAME\n\n"
@@ -103,6 +147,11 @@ int main (int argc, char* argv[])
        int option_index = 0;
        int c = 0;
 
+       bool use_vst = true;
+       bool try_hw_optimization = true;
+
+       backend_client_name = PBD::downcase (std::string(PROGRAM_NAME));
+
        while (1) {
                c = getopt_long (argc, argv, optstring, longopts, &option_index);
 
@@ -115,7 +164,8 @@ int main (int argc, char* argv[])
                        break;
 
                case 'v':
-                       just_version = true;
+                       print_version ();
+                       ::exit (0);
                        break;
 
                case 'h':
@@ -146,7 +196,7 @@ int main (int argc, char* argv[])
                        break;
 
                case 'P':
-                       no_connect_ports = true;
+                       ARDOUR::Port::set_connecting_blocked (true);
                        break;
 
                case 'V':
@@ -155,10 +205,6 @@ int main (int argc, char* argv[])
 #endif /* WINDOWS_VST_SUPPORT */
                        break;
 
-               case 'U':
-                       backend_session_uuid = optarg;
-                        break;
-
                default:
                        print_help ();
                        ::exit (1);
@@ -170,7 +216,7 @@ int main (int argc, char* argv[])
                ::exit (1);
        }
 
-       if (!ARDOUR::init (false, true, localedir)) {
+       if (!ARDOUR::init (use_vst, try_hw_optimization, localedir)) {
                cerr << "Ardour failed to initialize\n" << endl;
                ::exit (1);
        }
@@ -193,9 +239,19 @@ int main (int argc, char* argv[])
                exit (EXIT_FAILURE);
        }
 
+       PBD::ScopedConnectionList con;
+       BasicUI::AccessAction.connect_same_thread (con, boost::bind (&access_action, _1, _2));
+       AudioEngine::instance()->Halted.connect_same_thread (con, boost::bind (&engine_halted, _1));
+
+#ifndef PLATFORM_WINDOWS
+       signal(SIGINT, wearedone);
+       signal(SIGTERM, wearedone);
+#endif
+
        s->request_transport_speed (1.0);
 
-       sleep (-1);
+       char msg;
+       do {} while (0 == xthread.receive (msg, true));
 
        AudioEngine::instance()->remove_session ();
        delete s;