summaryrefslogtreecommitdiff
path: root/headless
diff options
context:
space:
mode:
authorPaul Davis <paul@linuxaudiosystems.com>2014-02-24 13:49:58 -0500
committerPaul Davis <paul@linuxaudiosystems.com>2014-02-24 13:51:31 -0500
commit90d0d4d8786b5778b632487e840394fc4be2110e (patch)
tree6caf8a39c6ed0f9d882cde61f0b22f3366b078e8 /headless
parente58b337c84d4e7fcea52c7ef79811f3bb8c5adec (diff)
new headless (GUI-free) version of ardour. run waf, cd headless and run ./hardev DIR SNAPSHOT_NAME. not bug free yet (startup race condition)
Diffstat (limited to 'headless')
-rwxr-xr-xheadless/hardbg5
-rwxr-xr-xheadless/hardev4
-rw-r--r--headless/hardev_common.sh.in39
-rw-r--r--headless/load_session.cc199
-rw-r--r--headless/misc.cc46
-rw-r--r--headless/misc.h13
-rw-r--r--headless/wscript96
7 files changed, 402 insertions, 0 deletions
diff --git a/headless/hardbg b/headless/hardbg
new file mode 100755
index 0000000000..ffab6221b0
--- /dev/null
+++ b/headless/hardbg
@@ -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
index 0000000000..75c29e54de
--- /dev/null
+++ b/headless/hardev
@@ -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
index 0000000000..703e388e5a
--- /dev/null
+++ b/headless/hardev_common.sh.in
@@ -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
index 0000000000..20c83ed628
--- /dev/null
+++ b/headless/load_session.cc
@@ -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
index 0000000000..a18989bee4
--- /dev/null
+++ b/headless/misc.cc
@@ -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
index 0000000000..36fcd6a2ec
--- /dev/null
+++ b/headless/misc.h
@@ -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
index 0000000000..3df0e09e93
--- /dev/null
+++ b/headless/wscript
@@ -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)