new headless (GUI-free) version of ardour. run waf, cd headless and run ./hardev...
authorPaul Davis <paul@linuxaudiosystems.com>
Mon, 24 Feb 2014 18:49:58 +0000 (13:49 -0500)
committerPaul Davis <paul@linuxaudiosystems.com>
Mon, 24 Feb 2014 18:51:31 +0000 (13:51 -0500)
headless/hardbg [new file with mode: 0755]
headless/hardev [new file with mode: 0755]
headless/hardev_common.sh.in [new file with mode: 0644]
headless/load_session.cc [new file with mode: 0644]
headless/misc.cc [new file with mode: 0644]
headless/misc.h [new file with mode: 0644]
headless/wscript [new file with mode: 0644]

diff --git a/headless/hardbg b/headless/hardbg
new file mode 100755 (executable)
index 0000000..ffab622
--- /dev/null
@@ -0,0 +1,5 @@
+#!/bin/sh
+. `dirname "$0"`/../build/headless/hardev_common_waf.sh
+LD_LIBRARY_PATH=$LD_LIBRARY_PATH
+export ARDOUR_INSIDE_GDB=1
+exec gdb --args $TOP/$EXECUTABLE $@
diff --git a/headless/hardev b/headless/hardev
new file mode 100755 (executable)
index 0000000..75c29e5
--- /dev/null
@@ -0,0 +1,4 @@
+#!/bin/sh
+. `dirname "$0"`/../build/headless/hardev_common_waf.sh
+export UBUNTU_MENUPROXY=""
+exec $TOP/$EXECUTABLE "$@"
diff --git a/headless/hardev_common.sh.in b/headless/hardev_common.sh.in
new file mode 100644 (file)
index 0000000..703e388
--- /dev/null
@@ -0,0 +1,39 @@
+TOP=`dirname "$0"`/..
+
+#export G_DEBUG=fatal_criticals
+
+libs=$TOP/@LIBS@
+
+#
+# when running ardev, the various parts of Ardour have not been consolidated into the locations that they 
+# would normally end up after an install. We therefore need to set up environment variables so that we
+# can find all the components. 
+#
+
+export ARDOUR_PATH=$TOP/gtk2_ardour/icons:$TOP/gtk2_ardour/pixmaps:$TOP/build/gtk2_ardour:$TOP/gtk2_ardour:.
+export ARDOUR_SURFACES_PATH=$libs/surfaces/osc:$libs/surfaces/generic_midi:$libs/surfaces/tranzport:$libs/surfaces/powermate:$libs/surfaces/mackie:$libs/surfaces/wiimote
+export ARDOUR_PANNER_PATH=$libs/panners
+export ARDOUR_DATA_PATH=$TOP:$TOP/build:$TOP/gtk2_ardour:$TOP/build/gtk2_ardour:.
+export ARDOUR_MIDIMAPS_PATH=$TOP/midi_maps:.
+export ARDOUR_MCP_PATH=$TOP/mcp:.
+export ARDOUR_EXPORT_FORMATS_PATH=$TOP/export:.
+export ARDOUR_BACKEND_PATH=$libs/backends/jack
+
+#
+# even though we set the above variables, ardour requires that these 
+# two also be set. the above settings will override them.
+#
+
+export ARDOUR_CONFIG_PATH=$TOP:$TOP/gtk2_ardour:$TOP/build:$TOP/build/gtk2_ardour
+export ARDOUR_DLL_PATH=$libs
+
+export GTK_PATH=~/.ardour3:$libs/clearlooks-newer
+export VAMP_PATH=$libs/vamp-plugins${VAMP_PATH:+:$VAMP_PATH}
+
+export LD_LIBRARY_PATH=$libs/qm-dsp:$libs/vamp-sdk:$libs/surfaces:$libs/surfaces/control_protocol:$libs/ardour:$libs/midi++2:$libs/pbd:$libs/rubberband:$libs/soundtouch:$libs/gtkmm2ext:$libs/gnomecanvas:$libs/libsndfile:$libs/appleutility:$libs/taglib:$libs/evoral:$libs/evoral/src/libsmf:$libs/audiographer:$libs/timecode:$libs/libltc:$libs/canvas${LD_LIBRARY_PATH:+:$LD_LIBRARY_PATH}
+
+# DYLD_LIBRARY_PATH is for darwin.
+export DYLD_FALLBACK_LIBRARY_PATH=$LD_LIBRARY_PATH
+
+ARDOURVERSION=@VERSION@
+EXECUTABLE=@EXECUTABLE@
diff --git a/headless/load_session.cc b/headless/load_session.cc
new file mode 100644 (file)
index 0000000..20c83ed
--- /dev/null
@@ -0,0 +1,199 @@
+#include <iostream>
+#include <cstdlib>
+#include <getopt.h>
+
+#include "pbd/failed_constructor.h"
+#include "pbd/error.h"
+#include "pbd/debug.h"
+
+#include "ardour/ardour.h"
+#include "ardour/audioengine.h"
+#include "ardour/session.h"
+
+#include "misc.h"
+
+using namespace std;
+using namespace ARDOUR;
+using namespace PBD;
+
+static const char* localedir = LOCALEDIR;
+
+TestReceiver test_receiver;
+
+/** @param dir Session directory.
+ *  @param state Session state file, without .ardour suffix.
+ */
+Session *
+load_session (string dir, string state)
+{
+       SessionEvent::create_per_thread_pool ("test", 512);
+
+       test_receiver.listen_to (error);
+       test_receiver.listen_to (info);
+       test_receiver.listen_to (fatal);
+       test_receiver.listen_to (warning);
+
+       AudioEngine* engine = AudioEngine::create ();
+
+       if (!engine->set_default_backend ()) {
+               std::cerr << "Cannot create Audio/MIDI engine\n";
+               ::exit (1);
+       }
+
+       init_post_engine ();
+
+       if (engine->start () != 0) {
+               std::cerr << "Cannot start Audio/MIDI engine\n";
+               ::exit (1);
+       }
+
+       Session* session = new Session (*engine, dir, state);
+       engine->set_session (session);
+       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;
+
+void
+print_help ()
+{
+       cout << "Usage: hardour [OPTIONS]... DIR SNAPSHOT_NAME\n\n"
+            << "  DIR                         Directory/Folder to load session from\n"
+            << "  SNAPSHOT_NAME               Name of session/snapshot to load (without .ardour at end\n"
+            << "  -v, --version               Show version information\n"
+            << "  -h, --help                  Print this message\n"
+            << "  -c, --name <name>           Use a specific backend client name, default is ardour\n"
+            << "  -d, --disable-plugins       Disable all plugins in an existing session\n"
+            << "  -D, --debug <options>       Set debug flags. Use \"-D list\" to see available options\n"
+            << "  -O, --no-hw-optimizations   Disable h/w specific optimizations\n"
+            << "  -P, --no-connect-ports      Do not connect any ports at startup\n"
+#ifdef WINDOWS_VST_SUPPORT
+            << "  -V, --novst                 Do not use VST support\n"
+#endif
+               ;
+}
+
+int main (int argc, char* argv[])
+{
+       const char *optstring = "vhdD:c:VOU:P";
+
+       const struct option longopts[] = {
+               { "version", 0, 0, 'v' },
+               { "help", 0, 0, 'h' },
+               { "disable-plugins", 1, 0, 'd' },
+               { "debug", 1, 0, 'D' },
+               { "name", 1, 0, 'c' },
+               { "novst", 0, 0, 'V' },
+               { "no-hw-optimizations", 0, 0, 'O' },
+               { "uuid", 1, 0, 'U' },
+               { "no-connect-ports", 0, 0, 'P' },
+               { 0, 0, 0, 0 }
+       };
+
+       int option_index = 0;
+       int c = 0;
+
+       while (1) {
+               c = getopt_long (argc, argv, optstring, longopts, &option_index);
+
+               if (c == -1) {
+                       break;
+               }
+
+               switch (c) {
+               case 0:
+                       break;
+
+               case 'v':
+                       just_version = true;
+                       break;
+
+               case 'h':
+                       print_help ();
+                       exit (0);
+                       break;
+
+               case 'c':
+                       backend_client_name = optarg;
+                       break;
+
+               case 'd':
+                       ARDOUR::Session::set_disable_all_loaded_plugins (true);
+                       break;
+
+               case 'D':
+                       if (PBD::parse_debug_options (optarg)) {
+                               ::exit (1);
+                       }
+                       break;
+
+               case 'O':
+                       try_hw_optimization = false;
+                       break;
+
+               case 'P':
+                       no_connect_ports = true;
+                       break;
+
+               case 'V':
+#ifdef WINDOWS_VST_SUPPORT
+                       use_vst = false;
+#endif /* WINDOWS_VST_SUPPORT */
+                       break;
+
+               case 'U':
+                       backend_session_uuid = optarg;
+                        break;
+
+               default:
+                       print_help ();
+                       ::exit (1);
+               }
+       }
+
+       if (argc < 3) {
+               print_help ();
+               ::exit (1);
+       }
+
+       if (!ARDOUR::init (false, true, localedir)) {
+               cerr << "Ardour failed to initialize\n" << endl;
+               ::exit (1);
+       }
+
+       Session* s = 0;
+       
+       try {
+               s = load_session (argv[optind], argv[optind+1]);
+       } catch (failed_constructor& e) {
+               cerr << "failed_constructor: " << e.what() << "\n";
+               exit (EXIT_FAILURE);
+       } catch (AudioEngine::PortRegistrationFailure& e) {
+               cerr << "PortRegistrationFailure: " << e.what() << "\n";
+               exit (EXIT_FAILURE);
+       } catch (exception& e) {
+               cerr << "exception: " << e.what() << "\n";
+               exit (EXIT_FAILURE);
+       } catch (...) {
+               cerr << "unknown exception.\n";
+               exit (EXIT_FAILURE);
+       }
+
+       s->request_transport_speed (1.0);
+       
+       sleep (-1);
+
+       AudioEngine::instance()->remove_session ();
+       delete s;
+       AudioEngine::instance()->stop ();
+
+       AudioEngine::destroy ();
+
+       return 0;
+}
diff --git a/headless/misc.cc b/headless/misc.cc
new file mode 100644 (file)
index 0000000..a18989b
--- /dev/null
@@ -0,0 +1,46 @@
+#include <iostream>
+#include <cstdlib>
+
+#include "misc.h"
+
+void
+TestReceiver::receive (Transmitter::Channel chn, const char * str)
+{
+       const char *prefix = "";
+       
+       switch (chn) {
+       case Transmitter::Error:
+               prefix = ": [ERROR]: ";
+               break;
+       case Transmitter::Info:
+               /* ignore */
+               return;
+       case Transmitter::Warning:
+               prefix = ": [WARNING]: ";
+               break;
+       case Transmitter::Fatal:
+               prefix = ": [FATAL]: ";
+               break;
+       case Transmitter::Throw:
+               /* this isn't supposed to happen */
+               abort ();
+       }
+       
+       /* note: iostreams are already thread-safe: no external
+          lock required.
+       */
+       
+       std::cout << prefix << str << std::endl;
+       
+       if (chn == Transmitter::Fatal) {
+               ::exit (9);
+       }
+}
+
+/* temporarily required due to some code design confusion (Feb 2014) */
+
+#include "ardour/vst_types.h"
+
+int vstfx_init (void*) { return 0; }
+void vstfx_exit () {}
+void vstfx_destroy_editor (VSTState*) {}
diff --git a/headless/misc.h b/headless/misc.h
new file mode 100644 (file)
index 0000000..36fcd6a
--- /dev/null
@@ -0,0 +1,13 @@
+#ifndef __hardour_misc_h__
+#define __hardour_misc_h__
+
+#include "pbd/transmitter.h"
+#include "pbd/receiver.h"
+
+class TestReceiver : public Receiver 
+{
+  protected:
+    void receive (Transmitter::Channel chn, const char * str);
+};
+
+#endif /* __hardour_misc_h__ */
diff --git a/headless/wscript b/headless/wscript
new file mode 100644 (file)
index 0000000..3df0e09
--- /dev/null
@@ -0,0 +1,96 @@
+#!/usr/bin/env python
+from waflib.extras import autowaf as autowaf
+from waflib import Options, TaskGen
+import waflib.Logs as Logs, waflib.Utils as Utils
+import os
+import shutil
+import sys
+import re
+import time
+from waflib.Task import Task
+
+# Mandatory variables
+top = '.'
+out = 'build'
+
+hardour_sources = [
+        'load_session.cc',
+        'misc.cc',
+]
+
+def options(opt):
+    autowaf.set_options(opt)
+
+def configure(conf):
+    conf.load('misc')
+    conf.load('compiler_cxx')
+    autowaf.configure(conf)
+
+
+def build(bld):
+
+    VERSION = "%s.%s" % (bld.env['MAJOR'], bld.env['MINOR'])
+    
+    # just the normal executable version of the GTK GUI
+    obj = bld (features = 'cxx c cxxprogram')
+    obj.source    = hardour_sources
+    obj.target = 'hardour-' + bld.env['VERSION']
+    obj.includes = ['.']
+
+    # at this point, "obj" refers to either the normal native executable
+    # OR the shared library built for use with wine on linux.
+
+    obj.use      = [ 'libpbd',
+                     'libardour',
+                     'libardour_cp',
+                     'libtimecode',
+                     'libmidipp',
+                     ]
+
+    obj.defines = [
+        'VERSIONSTRING="' + bld.env['VERSION'] + '"',
+        'DATA_DIR="' + os.path.normpath(bld.env['DATADIR']) + '"',
+        'CONFIG_DIR="' + os.path.normpath(bld.env['SYSCONFDIR']) + '"',
+        'LOCALEDIR="' + os.path.join(os.path.normpath(bld.env['DATADIR']), 'locale') + '"',
+        'PROGRAM_NAME="' + bld.env['PROGRAM_NAME'] + '"'
+        ]
+    obj.install_path = os.path.join(bld.env['LIBDIR'], 'ardour3')
+    obj.uselib       = 'UUID FLAC FONTCONFIG GLIBMM GTHREAD OGG CURL DL'
+    obj.uselib       += ' FFTW3F'
+    obj.uselib       += ' AUDIOUNITS OSX LO '
+    obj.uselib       += ' TAGLIB '
+
+    if sys.platform == 'darwin':
+        obj.uselib += ' AUDIOUNITS OSX'
+        obj.use    += ' libappleutility'
+    obj.includes += ['../libs']
+
+    if bld.env['build_target'] == 'mingw':
+       if bld.env['DEBUG'] == False:
+            obj.linkflags = ['-mwindows']
+
+    if bld.is_defined('NEED_INTL'):
+        obj.linkflags = ' -lintl'
+
+    # Wrappers
+
+    wrapper_subst_dict = {
+            'INSTALL_PREFIX' : bld.env['PREFIX'],
+            'LIBDIR'         : os.path.normpath(bld.env['LIBDIR']),
+            'DATADIR'        : os.path.normpath(bld.env['DATADIR']),
+            'SYSCONFDIR'     : os.path.normpath(bld.env['SYSCONFDIR']),
+            'LIBS'           : 'build/libs',
+            'VERSION'        : bld.env['VERSION'],
+            'EXECUTABLE'     : 'build/headless/hardour-' + bld.env['VERSION']
+    }
+
+    def set_subst_dict(obj, dict):
+        for i in dict:
+            setattr(obj, i, dict[i])
+
+    obj              = bld(features = 'subst', rule= 'chmod 0755 ${TGT}')
+    obj.source       = 'hardev_common.sh.in'
+    obj.target       = 'hardev_common_waf.sh'
+    obj.chmod        = Utils.O755
+    obj.dict         = wrapper_subst_dict
+    set_subst_dict(obj, wrapper_subst_dict)