summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid Robillard <d@drobilla.net>2006-12-12 12:45:33 +0000
committerDavid Robillard <d@drobilla.net>2006-12-12 12:45:33 +0000
commit71f632d459471c2e75ed04b808df9671539a182c (patch)
tree2fe3c25243e7b915656c02dd46bca5a0d317b599
parent9e2a757e026abf79d0cdcf12a18796fa89973356 (diff)
downloadingen-71f632d459471c2e75ed04b808df9671539a182c.tar.gz
ingen-71f632d459471c2e75ed04b808df9671539a182c.tar.bz2
ingen-71f632d459471c2e75ed04b808df9671539a182c.zip
Connection loading.
Command line parameter for server to allow connecting to specific JACK server. git-svn-id: http://svn.drobilla.net/lad/ingen@217 a436a847-0d15-0410-975c-d299462d15a1
-rw-r--r--configure.ac2
-rw-r--r--src/libs/client/Loader.cpp44
-rw-r--r--src/libs/client/RDFQuery.cpp8
-rw-r--r--src/libs/engine/Engine.cpp44
-rw-r--r--src/libs/engine/Engine.h35
-rw-r--r--src/libs/engine/EventSource.h8
-rw-r--r--src/libs/engine/JackAudioDriver.cpp31
-rw-r--r--src/libs/engine/JackAudioDriver.h9
-rw-r--r--src/libs/engine/Makefile.am2
-rw-r--r--src/libs/engine/QueuedEngineInterface.cpp4
-rw-r--r--src/libs/engine/events.h1
-rw-r--r--src/libs/engine/events/ActivateEvent.cpp38
-rw-r--r--src/libs/engine/events/ActivateEvent.h40
-rw-r--r--src/progs/ingenuity/ConnectWindow.cpp16
-rw-r--r--src/progs/server/cmdline.c324
-rw-r--r--src/progs/server/cmdline.ggo5
-rw-r--r--src/progs/server/cmdline.h34
-rw-r--r--src/progs/server/main.cpp17
18 files changed, 475 insertions, 187 deletions
diff --git a/configure.ac b/configure.ac
index 3e79663f..2074e0df 100644
--- a/configure.ac
+++ b/configure.ac
@@ -72,7 +72,7 @@ AC_ARG_ENABLE(debug,
[debug="$enableval"])
if test "$debug" = "yes"; then
debug_symbols="yes"
- assertions="yes"
+ debug_assertions="yes"
fi
AC_ARG_ENABLE(debug_symbols,
diff --git a/src/libs/client/Loader.cpp b/src/libs/client/Loader.cpp
index fe1af795..e1590540 100644
--- a/src/libs/client/Loader.cpp
+++ b/src/libs/client/Loader.cpp
@@ -52,7 +52,7 @@ Loader::load(const Glib::ustring& filename,
/* Load nodes */
RDFQuery query(Glib::ustring(
- "SELECT DISTINCT ?name ?plugin ?floatkey ?floatval FROM <") + filename + "> WHERE {\n"
+ "SELECT DISTINCT ?patch ?name ?plugin ?floatkey ?floatval FROM <") + filename + "> WHERE {\n"
"?patch ingen:node ?node .\n"
"?node ingen:name ?name ;\n"
" ingen:plugin ?plugin ;\n"
@@ -63,8 +63,12 @@ Loader::load(const Glib::ustring& filename,
RDFQuery::Results nodes = query.run(filename);
for (RDFQuery::Results::iterator i = nodes.begin(); i != nodes.end(); ++i) {
+
+ const Glib::ustring& patch = (*i)["patch"];
const Glib::ustring& name = (*i)["name"];
const Glib::ustring& plugin = (*i)["plugin"];
+
+ cerr << "LOADING NODE IN PATCH : " << patch << endl;
if (created.find(name) == created.end()) {
_engine->create_node(parent.base() + name, plugin, false);
@@ -103,7 +107,7 @@ Loader::load(const Glib::ustring& filename,
const Glib::ustring& datatype = (*i)["datatype"];
if (created.find(name) == created.end()) {
- cerr << "TYPE: " << type << endl;
+ //cerr << "TYPE: " << type << endl;
bool is_output = (type == "ingen:OutputPort"); // FIXME: check validity
_engine->create_port(parent.base() + name, datatype, is_output);
created[name] = true;
@@ -117,6 +121,42 @@ Loader::load(const Glib::ustring& filename,
_engine->set_metadata(parent.base() + name, floatkey, Atom(val));
}
}
+
+ /* Load connections */
+
+ query = RDFQuery(Glib::ustring(
+ "SELECT DISTINCT ?srcnode ?src ?dstnode ?dst FROM <") + filename + "> WHERE {\n"
+ "?srcnoderef ingen:port ?srcref .\n"
+ "?dstnoderef ingen:port ?dstref .\n"
+ "?dstref ingen:connectedTo ?srcref .\n"
+ "?srcref ingen:name ?src .\n"
+ "?dstref ingen:name ?dst .\n"
+ "OPTIONAL { ?srcnoderef ingen:name ?srcnode } .\n"
+ "OPTIONAL { ?dstnoderef ingen:name ?dstnode }\n"
+ "}\n");
+
+ cerr << "*************\n" << query.string() << "*****************\n";
+
+ RDFQuery::Results connections = query.run(filename);
+
+ for (RDFQuery::Results::iterator i = connections.begin(); i != connections.end(); ++i) {
+ // FIXME: kludge
+ Path src_node = string("/");
+ if ((*i).find("srcnode") != (*i).end())
+ src_node += string((*i)["srcnode"]);
+ Path src_port = src_node.base() + string((*i)["src"]);
+
+ Path dst_node = string("/");
+ if ((*i).find("dstnode") != (*i).end())
+ dst_node += string((*i)["dstnode"]);
+ Path dst_port = dst_node.base() + string((*i)["dst"]);
+
+ cerr << "CONNECTION: " << src_port << " -> " << dst_port << endl;
+
+ _engine->connect(src_port, dst_port);
+ }
+
+
}
diff --git a/src/libs/client/RDFQuery.cpp b/src/libs/client/RDFQuery.cpp
index 02a491bb..3993de20 100644
--- a/src/libs/client/RDFQuery.cpp
+++ b/src/libs/client/RDFQuery.cpp
@@ -48,8 +48,12 @@ RDFQuery::run(const Glib::ustring filename) const
rasqal_literal* rvalue = rasqal_query_results_get_binding_value(results, i);
Glib::ustring name((const char*)rname);
- Glib::ustring value((const char*)rasqal_literal_as_string(rvalue));
- bindings.insert(std::make_pair(name, value));
+ const unsigned char* str = rasqal_literal_as_string(rvalue);
+
+ if (str) {
+ Glib::ustring value((const char*)str);
+ bindings.insert(std::make_pair(name, value));
+ }
}
result.push_back(bindings);
diff --git a/src/libs/engine/Engine.cpp b/src/libs/engine/Engine.cpp
index 6cf50f52..56245534 100644
--- a/src/libs/engine/Engine.cpp
+++ b/src/libs/engine/Engine.cpp
@@ -14,6 +14,7 @@
* 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
+#include <cassert>
#include "Engine.h"
#include "config.h"
#include "tuning.h"
@@ -48,16 +49,8 @@ using std::cout; using std::cerr; using std::endl;
namespace Ingen {
-Engine::Engine(AudioDriver* audio_driver)
-: m_event_source(NULL),
- m_audio_driver( (audio_driver) ? audio_driver : new JackAudioDriver(*this) ),
-#ifdef HAVE_JACK_MIDI
- m_midi_driver(new JackMidiDriver(((JackAudioDriver*)m_audio_driver)->jack_client())),
-#elif HAVE_ALSA_MIDI
- m_midi_driver(new AlsaMidiDriver(m_audio_driver)),
-#else
- m_midi_driver(new DummyMidiDriver()),
-#endif
+Engine::Engine()
+: m_midi_driver(NULL),
m_maid(new Maid(maid_queue_size)),
m_post_processor(new PostProcessor(*m_maid, post_processor_queue_size)),
m_broadcaster(new ClientBroadcaster()),
@@ -88,7 +81,6 @@ Engine::~Engine()
delete m_broadcaster;
delete m_node_factory;
delete m_midi_driver;
- delete m_audio_driver;
delete m_maid;
@@ -105,7 +97,7 @@ Engine::~Engine()
template<>
Driver<MidiMessage>* Engine::driver<MidiMessage>() { return m_midi_driver; }
template<>
-Driver<Sample>* Engine::driver<Sample>() { return m_audio_driver; }
+Driver<Sample>* Engine::driver<Sample>() { return m_audio_driver.get(); }
int
@@ -147,12 +139,28 @@ Engine::main_iteration()
}
-void
-Engine::activate()
+bool
+Engine::activate(SharedPtr<AudioDriver> ad, SharedPtr<EventSource> es)
{
if (m_activated)
- return;
+ return false;
+
+ // Setup drivers
+ m_audio_driver = ad;
+#ifdef HAVE_JACK_MIDI
+ m_midi_driver = new JackMidiDriver(((JackAudioDriver*)m_audio_driver.get())->jack_client());
+#elif HAVE_ALSA_MIDI
+ m_midi_driver = new AlsaMidiDriver(m_audio_driver);
+#else
+ m_midi_driver = new DummyMidiDriver();
+#endif
+ // Set event source (FIXME: handle multiple sources)
+ m_event_source = es;
+
+ m_audio_driver->activate();
+ m_event_source->activate();
+
// Create root patch
CreatePatchEvent create_ev(*this, SharedPtr<Responder>(new Responder()), 0, "/", 1);
create_ev.pre_process();
@@ -173,6 +181,8 @@ Engine::activate()
m_post_processor->start();
m_activated = true;
+
+ return true;
}
@@ -199,6 +209,10 @@ Engine::deactivate()
m_post_processor->whip();
m_post_processor->stop();
+ m_audio_driver.reset();
+
+ m_event_source.reset();
+
m_activated = false;
}
diff --git a/src/libs/engine/Engine.h b/src/libs/engine/Engine.h
index f584ee6d..01aaa3a1 100644
--- a/src/libs/engine/Engine.h
+++ b/src/libs/engine/Engine.h
@@ -19,6 +19,7 @@
#include <cassert>
#include <boost/utility.hpp>
+#include <raul/SharedPtr.h>
template<typename T> class Queue;
class Maid;
@@ -41,17 +42,15 @@ template <typename T> class Driver;
/** The main class for the Engine.
*
- * With access to this you can find any object that's a part of the engine.
- * Access to this should be limited as possible, it basically exists so
- * there's something to pass Event constructors so they can access what
- * they need to perform their function.
+ * This is a (GoF) facade for the engine. Pointers to all components are
+ * available for more advanced control than this facade allows.
*
* \ingroup engine
*/
class Engine : boost::noncopyable
{
public:
- Engine(AudioDriver* audio_driver = 0);
+ Engine();
~Engine();
int main();
@@ -61,15 +60,13 @@ public:
* Note that it will take some time. */
void quit() { m_quit_flag = true; }
- void activate();
+ bool activate(SharedPtr<AudioDriver> ad, SharedPtr<EventSource> es);
void deactivate();
bool activated() { return m_activated; }
- void set_event_source(EventSource* es) { m_event_source = es; }
-
- EventSource* event_source() const { return m_event_source; }
- AudioDriver* audio_driver() const { return m_audio_driver; }
+ EventSource* event_source() const { return m_event_source.get(); }
+ AudioDriver* audio_driver() const { return m_audio_driver.get(); }
MidiDriver* midi_driver() const { return m_midi_driver; }
Maid* maid() const { return m_maid; }
PostProcessor* post_processor() const { return m_post_processor; }
@@ -82,15 +79,15 @@ public:
template<typename T> Driver<T>* driver();
private:
- EventSource* m_event_source;
- AudioDriver* m_audio_driver;
- MidiDriver* m_midi_driver;
- Maid* m_maid;
- PostProcessor* m_post_processor;
- ClientBroadcaster* m_broadcaster;
- ObjectStore* m_object_store;
- NodeFactory* m_node_factory;
- LashDriver* m_lash_driver;
+ SharedPtr<EventSource> m_event_source;
+ SharedPtr<AudioDriver> m_audio_driver;
+ MidiDriver* m_midi_driver;
+ Maid* m_maid;
+ PostProcessor* m_post_processor;
+ ClientBroadcaster* m_broadcaster;
+ ObjectStore* m_object_store;
+ NodeFactory* m_node_factory;
+ LashDriver* m_lash_driver;
bool m_quit_flag;
bool m_activated;
diff --git a/src/libs/engine/EventSource.h b/src/libs/engine/EventSource.h
index d251cac5..cb78e4dd 100644
--- a/src/libs/engine/EventSource.h
+++ b/src/libs/engine/EventSource.h
@@ -44,7 +44,13 @@ public:
virtual ~EventSource() {}
- virtual void process(PostProcessor& dest, SampleCount nframes, FrameTime cycle_start, FrameTime cycle_end) = 0;
+ virtual void activate() = 0;
+ virtual void deactivate() = 0;
+
+ virtual void process(PostProcessor& dest,
+ SampleCount nframes,
+ FrameTime cycle_start,
+ FrameTime cycle_end) = 0;
protected:
EventSource() {}
diff --git a/src/libs/engine/JackAudioDriver.cpp b/src/libs/engine/JackAudioDriver.cpp
index 756cfd68..81f15a78 100644
--- a/src/libs/engine/JackAudioDriver.cpp
+++ b/src/libs/engine/JackAudioDriver.cpp
@@ -118,7 +118,9 @@ JackAudioPort::prepare_buffer(jack_nframes_t nframes)
//// JackAudioDriver ////
-JackAudioDriver::JackAudioDriver(Engine& engine, jack_client_t* jack_client)
+JackAudioDriver::JackAudioDriver(Engine& engine,
+ std::string server_name,
+ jack_client_t* jack_client)
: _engine(engine),
_client(jack_client),
_buffer_size(jack_client ? jack_get_buffer_size(jack_client) : 0),
@@ -128,11 +130,29 @@ JackAudioDriver::JackAudioDriver(Engine& engine, jack_client_t* jack_client)
_root_patch(NULL)
{
if (!_client) {
- _client = jack_client_new("Ingen");
- if (_client == NULL) {
+ // Try supplied server name
+ if (server_name != "") {
+ _client = jack_client_open("Ingen", JackServerName, NULL, server_name.c_str());
+ if (_client)
+ cerr << "[JackAudioDriver] Connected to JACK server '" <<
+ server_name << "'" << endl;
+ }
+
+ // Either server name not specified, or supplied server name does not exist
+ // Connect to default server
+ if (!_client) {
+ _client = jack_client_open("Ingen", JackNullOption, NULL);
+
+ if (_client)
+ cerr << "[JackAudioDriver] Connected to default JACK server." << endl;
+ }
+
+ // Still failed
+ if (!_client) {
cerr << "[JackAudioDriver] Unable to connect to Jack. Exiting." << endl;
exit(EXIT_FAILURE);
}
+
_buffer_size = jack_get_buffer_size(_client);
_sample_rate = jack_get_sample_rate(_client);
}
@@ -272,11 +292,14 @@ JackAudioDriver::_process_cb(jack_nframes_t nframes)
if (_engine.event_source())
_engine.event_source()->process(*_engine.post_processor(), nframes, start_of_last_cycle, start_of_current_cycle);
+ assert(_engine.midi_driver());
_engine.midi_driver()->prepare_block(start_of_last_cycle, start_of_current_cycle);
// Set buffers of patch ports to Jack port buffers (zero-copy processing)
- for (List<JackAudioPort*>::iterator i = _ports.begin(); i != _ports.end(); ++i)
+ for (List<JackAudioPort*>::iterator i = _ports.begin(); i != _ports.end(); ++i) {
+ assert(*i);
(*i)->prepare_buffer(nframes);
+ }
// Run root patch
assert(_root_patch != NULL);
diff --git a/src/libs/engine/JackAudioDriver.h b/src/libs/engine/JackAudioDriver.h
index 3780c180..15651c26 100644
--- a/src/libs/engine/JackAudioDriver.h
+++ b/src/libs/engine/JackAudioDriver.h
@@ -72,7 +72,10 @@ private:
class JackAudioDriver : public AudioDriver
{
public:
- JackAudioDriver(Engine& engine, jack_client_t *jack_client = 0);
+ JackAudioDriver(Engine& engine,
+ std::string server_name = "",
+ jack_client_t* jack_client = 0);
+
~JackAudioDriver();
void activate();
@@ -136,23 +139,27 @@ private:
inline int JackAudioDriver::process_cb(jack_nframes_t nframes, void* jack_driver)
{
+ assert(jack_driver);
return ((JackAudioDriver*)jack_driver)->_process_cb(nframes);
}
inline void JackAudioDriver::shutdown_cb(void* jack_driver)
{
+ assert(jack_driver);
return ((JackAudioDriver*)jack_driver)->_shutdown_cb();
}
inline int JackAudioDriver::buffer_size_cb(jack_nframes_t nframes, void* jack_driver)
{
+ assert(jack_driver);
return ((JackAudioDriver*)jack_driver)->_buffer_size_cb(nframes);
}
inline int JackAudioDriver::sample_rate_cb(jack_nframes_t nframes, void* jack_driver)
{
+ assert(jack_driver);
return ((JackAudioDriver*)jack_driver)->_sample_rate_cb(nframes);
}
diff --git a/src/libs/engine/Makefile.am b/src/libs/engine/Makefile.am
index 0b12e524..3e4edf2c 100644
--- a/src/libs/engine/Makefile.am
+++ b/src/libs/engine/Makefile.am
@@ -93,8 +93,6 @@ libingen_la_SOURCES = \
events/UnregisterClientEvent.h \
events/UnregisterClientEvent.cpp \
events/PingQueuedEvent.h \
- events/ActivateEvent.h \
- events/ActivateEvent.cpp \
events/DeactivateEvent.h \
events/DeactivateEvent.cpp \
events/SetPortValueEvent.h \
diff --git a/src/libs/engine/QueuedEngineInterface.cpp b/src/libs/engine/QueuedEngineInterface.cpp
index 4628bdfd..ca6cf8cf 100644
--- a/src/libs/engine/QueuedEngineInterface.cpp
+++ b/src/libs/engine/QueuedEngineInterface.cpp
@@ -98,9 +98,9 @@ QueuedEngineInterface::load_plugins()
void
-QueuedEngineInterface::activate()
+QueuedEngineInterface::activate()
{
- push_queued(new ActivateEvent(*_engine.get(), _responder, now()));
+ push_queued(new PingQueuedEvent(*_engine.get(), _responder, now()));
}
diff --git a/src/libs/engine/events.h b/src/libs/engine/events.h
index 056c302d..73cd2ae8 100644
--- a/src/libs/engine/events.h
+++ b/src/libs/engine/events.h
@@ -19,7 +19,6 @@
#include "config.h"
-#include "ActivateEvent.h"
#include "DeactivateEvent.h"
#include "EnablePatchEvent.h"
#include "DisablePatchEvent.h"
diff --git a/src/libs/engine/events/ActivateEvent.cpp b/src/libs/engine/events/ActivateEvent.cpp
deleted file mode 100644
index 6c64f190..00000000
--- a/src/libs/engine/events/ActivateEvent.cpp
+++ /dev/null
@@ -1,38 +0,0 @@
-/* This file is part of Ingen. Copyright (C) 2006 Dave Robillard.
- *
- * Ingen is free software; you can redistribute it and/or modify it under the
- * terms of the GNU General Public License as published by the Free Software
- * Foundation; either version 2 of the License, or (at your option) any later
- * version.
- *
- * Ingen is distributed in the hope that it will be useful, but WITHOUT ANY
- * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
- * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- */
-
-#include "ActivateEvent.h"
-#include "Responder.h"
-#include "Engine.h"
-
-namespace Ingen {
-
-
-ActivateEvent::ActivateEvent(Engine& engine, SharedPtr<Responder> responder, SampleCount timestamp)
-: QueuedEvent(engine, responder, timestamp)
-{
- _engine.activate();
-}
-
-void
-ActivateEvent::post_process()
-{
- _responder->respond_ok();
-}
-
-
-} // namespace Ingen
-
diff --git a/src/libs/engine/events/ActivateEvent.h b/src/libs/engine/events/ActivateEvent.h
deleted file mode 100644
index 642859a7..00000000
--- a/src/libs/engine/events/ActivateEvent.h
+++ /dev/null
@@ -1,40 +0,0 @@
-/* This file is part of Ingen. Copyright (C) 2006 Dave Robillard.
- *
- * Ingen is free software; you can redistribute it and/or modify it under the
- * terms of the GNU General Public License as published by the Free Software
- * Foundation; either version 2 of the License, or (at your option) any later
- * version.
- *
- * Ingen is distributed in the hope that it will be useful, but WITHOUT ANY
- * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
- * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- */
-
-#ifndef ACTIVATEEVENT_H
-#define ACTIVATEEVENT_H
-
-#include "QueuedEvent.h"
-
-namespace Ingen {
-
-
-/** Activates the engine.
- *
- * \ingroup engine
- */
-class ActivateEvent : public QueuedEvent
-{
-public:
- ActivateEvent(Engine& engine, SharedPtr<Responder> responder, SampleCount timestamp);
-
- void post_process();
-};
-
-
-} // namespace Ingen
-
-#endif // ACTIVATEEVENT_H
diff --git a/src/progs/ingenuity/ConnectWindow.cpp b/src/progs/ingenuity/ConnectWindow.cpp
index c2c746bf..302cb08a 100644
--- a/src/progs/ingenuity/ConnectWindow.cpp
+++ b/src/progs/ingenuity/ConnectWindow.cpp
@@ -29,8 +29,9 @@
#include "App.h"
#include "WindowFactory.h"
#ifdef MONOLITHIC_INGENUITY
- #include "engine/QueuedEngineInterface.h"
#include "engine/Engine.h"
+ #include "engine/JackAudioDriver.h"
+ #include "engine/QueuedEngineInterface.h"
#include "engine/DirectResponder.h"
#include "engine/tuning.h"
#endif
@@ -169,16 +170,19 @@ ConnectWindow::connect()
#ifdef MONOLITHIC_INGENUITY
} else if (_mode == INTERNAL) {
SharedPtr<Ingen::Engine> engine(new Ingen::Engine());
- QueuedModelEngineInterface* qmei = new QueuedModelEngineInterface(engine);
- SharedPtr<ModelEngineInterface> engine_interface(qmei);
+ SharedPtr<Ingen::AudioDriver> audio_driver(
+ new Ingen::JackAudioDriver(*engine.get()) );
+ SharedPtr<QueuedModelEngineInterface> engine_interface(
+ new QueuedModelEngineInterface(engine) );
ThreadedSigClientInterface* tsci = new ThreadedSigClientInterface(Ingen::event_queue_size);
SharedPtr<SigClientInterface> client(tsci);
App::instance().attach(engine_interface, client);
- qmei->set_responder(SharedPtr<Ingen::Responder>(new Ingen::DirectResponder(client, 1)));
- engine->set_event_source(qmei);
-
+ engine_interface->set_responder(SharedPtr<Ingen::Responder>(new Ingen::DirectResponder(client, 1)));
+
+ engine->activate(audio_driver, engine_interface);
+
Glib::signal_timeout().connect(
sigc::mem_fun(engine.get(), &Ingen::Engine::main_iteration), 1000);
diff --git a/src/progs/server/cmdline.c b/src/progs/server/cmdline.c
index 6b7ddf6a..6a697a04 100644
--- a/src/progs/server/cmdline.c
+++ b/src/progs/server/cmdline.c
@@ -1,27 +1,83 @@
/*
- File autogenerated by gengetopt version 2.10
+ File autogenerated by gengetopt version 2.18
generated with the following command:
- gengetopt
+ gengetopt -u
The developers of gengetopt consider the fixed text that goes in all
gengetopt output files to be in the public domain:
we make no copyright claims on it.
*/
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
/* If we use autoconf. */
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
#include "getopt.h"
#include "cmdline.h"
+const char *gengetopt_args_info_purpose = "";
+
+const char *gengetopt_args_info_usage = "Usage: Om - An OSC controlled realtime modular synthesizer [OPTIONS]... [FILES]...";
+
+const char *gengetopt_args_info_help[] = {
+ " -h, --help Print help and exit",
+ " -V, --version Print version and exit",
+ " -p, --port=STRING OSC port to listen on (default=`16180')",
+ " -j, --jack-server=STRING Name of Jack server to attach to",
+ " -i, --in-jackd Run engine as in-process JACK client (default=off)",
+ 0
+};
+
+static
+void clear_given (struct gengetopt_args_info *args_info);
+static
+void clear_args (struct gengetopt_args_info *args_info);
+
+static int
+cmdline_parser_internal (int argc, char * const *argv, struct gengetopt_args_info *args_info, int override, int initialize, int check_required, const char *additional_error);
+
+
+static char *
+gengetopt_strdup (const char *s);
+
+static
+void clear_given (struct gengetopt_args_info *args_info)
+{
+ args_info->help_given = 0 ;
+ args_info->version_given = 0 ;
+ args_info->port_given = 0 ;
+ args_info->jack_server_given = 0 ;
+ args_info->in_jackd_given = 0 ;
+}
+
+static
+void clear_args (struct gengetopt_args_info *args_info)
+{
+ args_info->port_arg = gengetopt_strdup ("16180");
+ args_info->port_orig = NULL;
+ args_info->jack_server_arg = NULL;
+ args_info->jack_server_orig = NULL;
+ args_info->in_jackd_flag = 0;
+
+}
+
+static
+void init_args_info(struct gengetopt_args_info *args_info)
+{
+ args_info->help_help = gengetopt_args_info_help[0] ;
+ args_info->version_help = gengetopt_args_info_help[1] ;
+ args_info->port_help = gengetopt_args_info_help[2] ;
+ args_info->jack_server_help = gengetopt_args_info_help[3] ;
+ args_info->in_jackd_help = gengetopt_args_info_help[4] ;
+
+}
+
void
cmdline_parser_print_version (void)
{
@@ -31,24 +87,124 @@ cmdline_parser_print_version (void)
void
cmdline_parser_print_help (void)
{
+ int i = 0;
cmdline_parser_print_version ();
- printf("\n"
- "Usage: %s [OPTIONS]...\n", CMDLINE_PARSER_PACKAGE);
- printf(" -h --help Print help and exit\n");
- printf(" -V --version Print version and exit\n");
- printf(" -pSTRING --port=STRING OSC port to listen on (default='16180')\n");
- printf(" -i --in-jackd Run engine as in-process JACK client (default=off)\n");
+
+ if (strlen(gengetopt_args_info_purpose) > 0)
+ printf("\n%s\n", gengetopt_args_info_purpose);
+
+ printf("\n%s\n\n", gengetopt_args_info_usage);
+ while (gengetopt_args_info_help[i])
+ printf("%s\n", gengetopt_args_info_help[i++]);
+}
+
+void
+cmdline_parser_init (struct gengetopt_args_info *args_info)
+{
+ clear_given (args_info);
+ clear_args (args_info);
+ init_args_info (args_info);
+
+ args_info->inputs = NULL;
+ args_info->inputs_num = 0;
+}
+
+static void
+cmdline_parser_release (struct gengetopt_args_info *args_info)
+{
+
+ unsigned int i;
+ if (args_info->port_arg)
+ {
+ free (args_info->port_arg); /* free previous argument */
+ args_info->port_arg = 0;
+ }
+ if (args_info->port_orig)
+ {
+ free (args_info->port_orig); /* free previous argument */
+ args_info->port_orig = 0;
+ }
+ if (args_info->jack_server_arg)
+ {
+ free (args_info->jack_server_arg); /* free previous argument */
+ args_info->jack_server_arg = 0;
+ }
+ if (args_info->jack_server_orig)
+ {
+ free (args_info->jack_server_orig); /* free previous argument */
+ args_info->jack_server_orig = 0;
+ }
+
+ for (i = 0; i < args_info->inputs_num; ++i)
+ free (args_info->inputs [i]);
+
+ if (args_info->inputs_num)
+ free (args_info->inputs);
+
+ clear_given (args_info);
+}
+
+int
+cmdline_parser_file_save(const char *filename, struct gengetopt_args_info *args_info)
+{
+ FILE *outfile;
+ int i = 0;
+
+ outfile = fopen(filename, "w");
+
+ if (!outfile)
+ {
+ fprintf (stderr, "%s: cannot open file for writing: %s\n", CMDLINE_PARSER_PACKAGE, filename);
+ return EXIT_FAILURE;
+ }
+
+ if (args_info->help_given) {
+ fprintf(outfile, "%s\n", "help");
+ }
+ if (args_info->version_given) {
+ fprintf(outfile, "%s\n", "version");
+ }
+ if (args_info->port_given) {
+ if (args_info->port_orig) {
+ fprintf(outfile, "%s=\"%s\"\n", "port", args_info->port_orig);
+ } else {
+ fprintf(outfile, "%s\n", "port");
+ }
+ }
+ if (args_info->jack_server_given) {
+ if (args_info->jack_server_orig) {
+ fprintf(outfile, "%s=\"%s\"\n", "jack-server", args_info->jack_server_orig);
+ } else {
+ fprintf(outfile, "%s\n", "jack-server");
+ }
+ }
+ if (args_info->in_jackd_given) {
+ fprintf(outfile, "%s\n", "in-jackd");
+ }
+
+ fclose (outfile);
+
+ i = EXIT_SUCCESS;
+ return i;
}
+void
+cmdline_parser_free (struct gengetopt_args_info *args_info)
+{
+ cmdline_parser_release (args_info);
+}
-static char *gengetopt_strdup (const char *s);
/* gengetopt_strdup() */
/* strdup.c replacement of strdup, which is not standard */
char *
gengetopt_strdup (const char *s)
{
- char *result = (char*)malloc(strlen(s) + 1);
+ char *result = NULL;
+ if (!s)
+ return result;
+
+ result = (char*)malloc(strlen(s) + 1);
if (result == (char*)0)
return (char*)0;
strcpy(result, s);
@@ -58,22 +214,46 @@ gengetopt_strdup (const char *s)
int
cmdline_parser (int argc, char * const *argv, struct gengetopt_args_info *args_info)
{
- int c; /* Character of the parsed option. */
- int missing_required_options = 0;
+ return cmdline_parser2 (argc, argv, args_info, 0, 1, 1);
+}
- args_info->help_given = 0 ;
- args_info->version_given = 0 ;
- args_info->port_given = 0 ;
- args_info->in_jackd_given = 0 ;
-#define clear_args() { \
- args_info->port_arg = gengetopt_strdup("16180") ;\
- args_info->in_jackd_flag = 0;\
+int
+cmdline_parser2 (int argc, char * const *argv, struct gengetopt_args_info *args_info, int override, int initialize, int check_required)
+{
+ int result;
+
+ result = cmdline_parser_internal (argc, argv, args_info, override, initialize, check_required, NULL);
+
+ if (result == EXIT_FAILURE)
+ {
+ cmdline_parser_free (args_info);
+ exit (EXIT_FAILURE);
+ }
+
+ return result;
+}
+
+int
+cmdline_parser_required (struct gengetopt_args_info *args_info, const char *prog_name)
+{
+ return EXIT_SUCCESS;
}
- clear_args();
+int
+cmdline_parser_internal (int argc, char * const *argv, struct gengetopt_args_info *args_info, int override, int initialize, int check_required, const char *additional_error)
+{
+ int c; /* Character of the parsed option. */
+
+ int error = 0;
+ struct gengetopt_args_info local_args_info;
+
+ if (initialize)
+ cmdline_parser_init (args_info);
+
+ cmdline_parser_init (&local_args_info);
optarg = 0;
- optind = 1;
+ optind = 0;
opterr = 1;
optopt = '?';
@@ -86,65 +266,125 @@ cmdline_parser (int argc, char * const *argv, struct gengetopt_args_info *args_i
{ "help", 0, NULL, 'h' },
{ "version", 0, NULL, 'V' },
{ "port", 1, NULL, 'p' },
+ { "jack-server", 1, NULL, 'j' },
{ "in-jackd", 0, NULL, 'i' },
{ NULL, 0, NULL, 0 }
};
stop_char = 0;
- c = getopt_long (argc, argv, "hVp:i", long_options, &option_index);
+ c = getopt_long (argc, argv, "hVp:j:i", long_options, &option_index);
if (c == -1) break; /* Exit from `while (1)' loop. */
switch (c)
{
case 'h': /* Print help and exit. */
- clear_args ();
cmdline_parser_print_help ();
+ cmdline_parser_free (&local_args_info);
exit (EXIT_SUCCESS);
case 'V': /* Print version and exit. */
- clear_args ();
cmdline_parser_print_version ();
+ cmdline_parser_free (&local_args_info);
exit (EXIT_SUCCESS);
case 'p': /* OSC port to listen on. */
- if (args_info->port_given)
+ if (local_args_info.port_given)
{
- fprintf (stderr, "%s: `--port' (`-p') option given more than once\n", CMDLINE_PARSER_PACKAGE);
- clear_args ();
- exit (EXIT_FAILURE);
+ fprintf (stderr, "%s: `--port' (`-p') option given more than once%s\n", argv[0], (additional_error ? additional_error : ""));
+ goto failure;
}
+ if (args_info->port_given && ! override)
+ continue;
+ local_args_info.port_given = 1;
args_info->port_given = 1;
+ if (args_info->port_arg)
+ free (args_info->port_arg); /* free previous string */
args_info->port_arg = gengetopt_strdup (optarg);
+ if (args_info->port_orig)
+ free (args_info->port_orig); /* free previous string */
+ args_info->port_orig = gengetopt_strdup (optarg);
+ break;
+
+ case 'j': /* Name of Jack server to attach to. */
+ if (local_args_info.jack_server_given)
+ {
+ fprintf (stderr, "%s: `--jack-server' (`-j') option given more than once%s\n", argv[0], (additional_error ? additional_error : ""));
+ goto failure;
+ }
+ if (args_info->jack_server_given && ! override)
+ continue;
+ local_args_info.jack_server_given = 1;
+ args_info->jack_server_given = 1;
+ if (args_info->jack_server_arg)
+ free (args_info->jack_server_arg); /* free previous string */
+ args_info->jack_server_arg = gengetopt_strdup (optarg);
+ if (args_info->jack_server_orig)
+ free (args_info->jack_server_orig); /* free previous string */
+ args_info->jack_server_orig = gengetopt_strdup (optarg);
break;
case 'i': /* Run engine as in-process JACK client. */
- if (args_info->in_jackd_given)
+ if (local_args_info.in_jackd_given)
{
- fprintf (stderr, "%s: `--in-jackd' (`-i') option given more than once\n", CMDLINE_PARSER_PACKAGE);
- clear_args ();
- exit (EXIT_FAILURE);
+ fprintf (stderr, "%s: `--in-jackd' (`-i') option given more than once%s\n", argv[0], (additional_error ? additional_error : ""));
+ goto failure;
}
+ if (args_info->in_jackd_given && ! override)
+ continue;
+ local_args_info.in_jackd_given = 1;
args_info->in_jackd_given = 1;
args_info->in_jackd_flag = !(args_info->in_jackd_flag);
break;
case 0: /* Long option with no short option */
-
case '?': /* Invalid option. */
/* `getopt_long' already printed an error message. */
- exit (EXIT_FAILURE);
+ goto failure;
default: /* bug: option not considered. */
- fprintf (stderr, "%s: option unknown: %c\n", CMDLINE_PARSER_PACKAGE, c);
+ fprintf (stderr, "%s: option unknown: %c%s\n", CMDLINE_PARSER_PACKAGE, c, (additional_error ? additional_error : ""));
abort ();
} /* switch */
} /* while */
- if ( missing_required_options )
- exit (EXIT_FAILURE);
+
+
+ cmdline_parser_release (&local_args_info);
+
+ if ( error )
+ return (EXIT_FAILURE);
+
+ if (optind < argc)
+ {
+ int i = 0 ;
+ int found_prog_name = 0;
+ /* whether program name, i.e., argv[0], is in the remaining args
+ (this may happen with some implementations of getopt,
+ but surely not with the one included by gengetopt) */
+
+ i = optind;
+ while (i < argc)
+ if (argv[i++] == argv[0]) {
+ found_prog_name = 1;
+ break;
+ }
+ i = 0;
+
+ args_info->inputs_num = argc - optind - found_prog_name;
+ args_info->inputs =
+ (char **)(malloc ((args_info->inputs_num)*sizeof(char *))) ;
+ while (optind < argc)
+ if (argv[optind++] != argv[0])
+ args_info->inputs[ i++ ] = gengetopt_strdup (argv[optind-1]) ;
+ }
return 0;
+
+failure:
+
+ cmdline_parser_release (&local_args_info);
+ return (EXIT_FAILURE);
}
diff --git a/src/progs/server/cmdline.ggo b/src/progs/server/cmdline.ggo
index 8c006ca7..ce50cea1 100644
--- a/src/progs/server/cmdline.ggo
+++ b/src/progs/server/cmdline.ggo
@@ -2,6 +2,7 @@
package "Om - An OSC controlled realtime modular synthesizer"
-option "port" p "OSC port to listen on" string default="16180" no
-option "in-jackd" i "Run engine as in-process JACK client" flag off
+option "port" p "OSC port to listen on" string default="16180" no
+option "jack-server" j "Name of Jack server to attach to" string no
+option "in-jackd" i "Run engine as in-process JACK client" flag off
diff --git a/src/progs/server/cmdline.h b/src/progs/server/cmdline.h
index fe36a969..8ced9534 100644
--- a/src/progs/server/cmdline.h
+++ b/src/progs/server/cmdline.h
@@ -1,6 +1,6 @@
/* cmdline.h */
-/* File autogenerated by gengetopt version 2.10 */
+/* File autogenerated by gengetopt version 2.18 */
#ifndef CMDLINE_H
#define CMDLINE_H
@@ -24,21 +24,49 @@ extern "C" {
struct gengetopt_args_info
{
+ const char *help_help; /* Print help and exit help description. */
+ const char *version_help; /* Print version and exit help description. */
char * port_arg; /* OSC port to listen on (default='16180'). */
+ char * port_orig; /* OSC port to listen on original value given at command line. */
+ const char *port_help; /* OSC port to listen on help description. */
+ char * jack_server_arg; /* Name of Jack server to attach to. */
+ char * jack_server_orig; /* Name of Jack server to attach to original value given at command line. */
+ const char *jack_server_help; /* Name of Jack server to attach to help description. */
int in_jackd_flag; /* Run engine as in-process JACK client (default=off). */
-
+ const char *in_jackd_help; /* Run engine as in-process JACK client help description. */
+
int help_given ; /* Whether help was given. */
int version_given ; /* Whether version was given. */
int port_given ; /* Whether port was given. */
+ int jack_server_given ; /* Whether jack-server was given. */
int in_jackd_given ; /* Whether in-jackd was given. */
+ char **inputs ; /* unamed options */
+ unsigned inputs_num ; /* unamed options number */
} ;
-int cmdline_parser (int argc, char * const *argv, struct gengetopt_args_info *args_info);
+extern const char *gengetopt_args_info_purpose;
+extern const char *gengetopt_args_info_usage;
+extern const char *gengetopt_args_info_help[];
+
+int cmdline_parser (int argc, char * const *argv,
+ struct gengetopt_args_info *args_info);
+int cmdline_parser2 (int argc, char * const *argv,
+ struct gengetopt_args_info *args_info,
+ int override, int initialize, int check_required);
+int cmdline_parser_file_save(const char *filename,
+ struct gengetopt_args_info *args_info);
void cmdline_parser_print_help(void);
void cmdline_parser_print_version(void);
+void cmdline_parser_init (struct gengetopt_args_info *args_info);
+void cmdline_parser_free (struct gengetopt_args_info *args_info);
+
+int cmdline_parser_required (struct gengetopt_args_info *args_info,
+ const char *prog_name);
+
+
#ifdef __cplusplus
}
#endif /* __cplusplus */
diff --git a/src/progs/server/main.cpp b/src/progs/server/main.cpp
index fa3548d3..73603e3a 100644
--- a/src/progs/server/main.cpp
+++ b/src/progs/server/main.cpp
@@ -22,6 +22,7 @@
#include "cmdline.h"
#include "tuning.h"
#include "Engine.h"
+#include "JackAudioDriver.h"
#include "OSCEngineReceiver.h"
#ifdef HAVE_LASH
#include "LashDriver.h"
@@ -139,11 +140,16 @@ main(int argc, char** argv)
engine = SharedPtr<Engine>(new Engine());
- OSCEngineReceiver* receiver = new OSCEngineReceiver(
- engine, pre_processor_queue_size, args_info.port_arg);
+ std::string jack_name
+ = (args_info.jack_server_given) ? args_info.jack_server_arg : "";
- receiver->activate();
- engine->set_event_source(receiver);
+ SharedPtr<AudioDriver> audio_driver(
+ new JackAudioDriver(*engine.get(), jack_name) );
+
+ SharedPtr<EventSource> event_source(new OSCEngineReceiver(
+ engine, pre_processor_queue_size, args_info.port_arg ));
+
+ engine->activate(audio_driver, event_source);
#ifdef HAVE_LASH
lash_driver = new LashDriver(engine, lash_args);
@@ -151,13 +157,12 @@ main(int argc, char** argv)
engine->main();
- receiver->deactivate();
+ event_source->deactivate();
#ifdef HAVE_LASH
delete lash_driver;
#endif
- delete receiver;
}
return ret;