diff options
author | David Robillard <d@drobilla.net> | 2008-09-30 16:50:21 +0000 |
---|---|---|
committer | David Robillard <d@drobilla.net> | 2008-09-30 16:50:21 +0000 |
commit | 93850c202de8b073a1ce1dd8bd246d407bce4e2f (patch) | |
tree | 6910b135bf4eff12de1af116cef73f6e9c107cd0 /src/libs/engine | |
parent | a8bf5272d096de73507d2eab47f282c345f4ca8a (diff) | |
download | ingen-93850c202de8b073a1ce1dd8bd246d407bce4e2f.tar.gz ingen-93850c202de8b073a1ce1dd8bd246d407bce4e2f.tar.bz2 ingen-93850c202de8b073a1ce1dd8bd246d407bce4e2f.zip |
Flatten ingen source directory heirarchy a bit.
git-svn-id: http://svn.drobilla.net/lad/trunk/ingen@1551 a436a847-0d15-0410-975c-d299462d15a1
Diffstat (limited to 'src/libs/engine')
165 files changed, 0 insertions, 19040 deletions
diff --git a/src/libs/engine/AudioBuffer.cpp b/src/libs/engine/AudioBuffer.cpp deleted file mode 100644 index 098103c0..00000000 --- a/src/libs/engine/AudioBuffer.cpp +++ /dev/null @@ -1,299 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard <http://drobilla.net> - * - * 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 <iostream> -#include <cassert> -#include <stdlib.h> -#include "AudioBuffer.hpp" - -using namespace std; - -/* TODO: Be sure these functions are vectorized by GCC when it's vectorizer - * stops sucking. Probably a good idea to inline them as well */ - -namespace Ingen { - - -AudioBuffer::AudioBuffer(size_t size) - : Buffer((size == 1) ? DataType::CONTROL : DataType::AUDIO, size) - , _data(NULL) - , _local_data(NULL) - , _size(size) - , _filled_size(0) - , _state(OK) - , _set_value(0) - , _set_time(0) -{ - assert(_size > 0); - allocate(); - assert(data()); -} - - -void -AudioBuffer::resize(size_t size) -{ - _size = size; - - Sample* const old_data = _data; - - const bool using_local_data = (_data == _local_data); - - deallocate(); - - const int ret = posix_memalign((void**)&_local_data, 16, _size * sizeof(Sample)); - if (ret != 0) { - cerr << "[Buffer] Failed to allocate buffer. Aborting." << endl; - exit(EXIT_FAILURE); - } - - assert(ret == 0); - assert(_local_data); - - if (using_local_data) - _data = _local_data; - else - _data = old_data; - - set_block(0, 0, _size-1); -} - - -/** Allocate and use a locally managed buffer (data). - */ -void -AudioBuffer::allocate() -{ - assert(!_joined_buf); - assert(_local_data == NULL); - assert(_size > 0); - - const int ret = posix_memalign((void**)&_local_data, 16, _size * sizeof(Sample)); - if (ret != 0) { - cerr << "[Buffer] Failed to allocate buffer. Aborting." << endl; - exit(EXIT_FAILURE); - } - - assert(ret == 0); - assert(_local_data); - - _data = _local_data; - - set_block(0, 0, _size-1); -} - - -/** Free locally allocated buffer. - */ -void -AudioBuffer::deallocate() -{ - assert(!_joined_buf); - free(_local_data); - _local_data = NULL; - _data = NULL; -} - - -/** Empty (ie zero) the buffer. - */ -void -AudioBuffer::clear() -{ - set_block(0, 0, _size-1); - _state = OK; - _filled_size = 0; -} - - -/** Set value of buffer to @a val after @a start_sample. - * - * The Buffer will handle setting the intial portion of the buffer to the - * value on the next cycle automatically (if @a start_sample is > 0), as - * long as pre_process() is called every cycle. - */ -void -AudioBuffer::set_value(Sample val, FrameTime cycle_start, FrameTime time) -{ - if (_size == 1) - time = cycle_start; - - FrameTime offset = time - cycle_start; - assert(offset <= _size); - - if (offset < _size) { - set_block(val, offset, _size - 1); - - if (offset > 0) - _state = HALF_SET_CYCLE_1; - } // else trigger at very end of block - - _set_time = time; - _set_value = val; -} - - -/** Set a block of buffer to @a val. - * - * @a start_sample and @a end_sample define the inclusive range to be set. - */ -void -AudioBuffer::set_block(Sample val, size_t start_offset, size_t end_offset) -{ - assert(end_offset >= start_offset); - assert(end_offset < _size); - - Sample* const buf = data(); - assert(buf); - - for (size_t i = start_offset; i <= end_offset; ++i) - buf[i] = val; -} - - -/** Scale a block of buffer by @a val. - * - * @a start_sample and @a end_sample define the inclusive range to be set. - */ -void -AudioBuffer::scale(Sample val, size_t start_sample, size_t end_sample) -{ - assert(end_sample >= start_sample); - assert(end_sample < _size); - - Sample* const buf = data(); - assert(buf); - - for (size_t i=start_sample; i <= end_sample; ++i) - buf[i] *= val; -} - - -/** Copy a block of @a src into buffer. - * - * @a start_sample and @a end_sample define the inclusive range to be set. - * This function only copies the same range in one buffer to another. - */ -void -AudioBuffer::copy(const Buffer* src, size_t start_sample, size_t end_sample) -{ - assert(end_sample >= start_sample); - assert(end_sample < _size); - assert(src); - assert(src->type() == DataType::CONTROL || DataType::AUDIO); - - Sample* const buf = data(); - assert(buf); - - const Sample* const src_buf = ((AudioBuffer*)src)->data(); - assert(src_buf); - - for (size_t i=start_sample; i <= end_sample; ++i) - buf[i] = src_buf[i]; -} - - -/** Accumulate a block of @a src into @a dst. - * - * @a start_sample and @a end_sample define the inclusive range to be accumulated. - * This function only adds the same range in one buffer to another. - */ -void -AudioBuffer::accumulate(const AudioBuffer* const src, size_t start_sample, size_t end_sample) -{ - assert(end_sample >= start_sample); - assert(end_sample < _size); - assert(src); - - Sample* const buf = data(); - assert(buf); - - const Sample* const src_buf = src->data(); - assert(src_buf); - - for (size_t i=start_sample; i <= end_sample; ++i) - buf[i] += src_buf[i]; - -} - - -/** Use another buffer's data instead of the local one. - * - * This buffer will essentially be identical to @a buf after this call. - */ -bool -AudioBuffer::join(Buffer* buf) -{ - AudioBuffer* abuf = dynamic_cast<AudioBuffer*>(buf); - if (!abuf) - return false; - - assert(abuf->size() >= _size); - - _joined_buf = abuf; - _filled_size = abuf->filled_size(); - - assert(_filled_size <= _size); - - return true; -} - - -void -AudioBuffer::unjoin() -{ - _joined_buf = NULL; - _data = _local_data; -} - - -void -AudioBuffer::prepare_read(FrameTime start, SampleCount nframes) -{ - // FIXME: nframes parameter doesn't actually work, - // writing starts from 0 every time - assert(_size == 1 || nframes == _size); - - switch (_state) { - case HALF_SET_CYCLE_1: - if (start > _set_time) - _state = HALF_SET_CYCLE_2; - break; - case HALF_SET_CYCLE_2: - set_block(_set_value, 0, _size-1); - _state = OK; - break; - default: - break; - } -} - - -/** Set the buffer (data) used. - * - * This is only to be used by Drivers (to provide zero-copy processing). - */ -void -AudioBuffer::set_data(Sample* buf) -{ - assert(buf); - assert(!_joined_buf); - _data = buf; -} - - -} // namespace Ingen diff --git a/src/libs/engine/AudioBuffer.hpp b/src/libs/engine/AudioBuffer.hpp deleted file mode 100644 index 513c188f..00000000 --- a/src/libs/engine/AudioBuffer.hpp +++ /dev/null @@ -1,84 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard <http://drobilla.net> - * - * 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 AUDIOBUFFER_H -#define AUDIOBUFFER_H - -#include <cstddef> -#include <cassert> -#include <boost/utility.hpp> -#include "types.hpp" -#include "Buffer.hpp" - -namespace Ingen { - - -class AudioBuffer : public Buffer -{ -public: - AudioBuffer(size_t capacity); - - void clear(); - void set_value(Sample val, FrameTime cycle_start, FrameTime time); - void set_block(Sample val, size_t start_offset, size_t end_offset); - void scale(Sample val, size_t start_sample, size_t end_sample); - void copy(const Buffer* src, size_t start_sample, size_t end_sample); - void accumulate(const AudioBuffer* src, size_t start_sample, size_t end_sample); - - bool join(Buffer* buf); - void unjoin(); - - /** For driver use only!! */ - void set_data(Sample* data); - - inline const void* raw_data() const { return _data; } - inline void* raw_data() { return _data; } - - inline Sample* data() const { return _data; } - - inline Sample& value_at(size_t offset) const - { assert(offset < _size); return data()[offset]; } - - void prepare_read(FrameTime start, SampleCount nframes); - void prepare_write(FrameTime start, SampleCount nframes) {} - - void rewind() const {} - void resize(size_t size); - - void filled_size(size_t size) { _filled_size = size; } - size_t filled_size() const { return _filled_size; } - size_t size() const { return _size; } - -private: - enum State { OK, HALF_SET_CYCLE_1, HALF_SET_CYCLE_2 }; - - void allocate(); - void deallocate(); - - Sample* _data; ///< Used data pointer (probably same as _local_data) - Sample* _local_data; ///< Locally allocated buffer (possibly unused if joined or set_data used) - size_t _size; ///< Allocated buffer size - size_t _filled_size; ///< Usable buffer size (for MIDI ports etc) - State _state; ///< State of buffer for setting values next cycle - Sample _set_value; ///< Value set by @ref set (may need to be set next cycle) - FrameTime _set_time; ///< Time _set_value was set (to reset next cycle) -}; - - -} // namespace Ingen - -#endif // AUDIOBUFFER_H diff --git a/src/libs/engine/AudioDriver.hpp b/src/libs/engine/AudioDriver.hpp deleted file mode 100644 index 6b5ea8dc..00000000 --- a/src/libs/engine/AudioDriver.hpp +++ /dev/null @@ -1,62 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard <http://drobilla.net> - * - * 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 AUDIODRIVER_H -#define AUDIODRIVER_H - -#include <raul/List.hpp> -#include <raul/Path.hpp> -#include "Driver.hpp" -#include "types.hpp" -#include "interface/DataType.hpp" - -namespace Ingen { - -class PatchImpl; -class AudioDriver; -class PortImpl; -class ProcessContext; - - -/** Audio driver abstract base class. - * - * \ingroup engine - */ -class AudioDriver : public Driver -{ -public: - AudioDriver() : Driver(DataType::AUDIO) {} - - virtual void set_root_patch(PatchImpl* patch) = 0; - virtual PatchImpl* root_patch() = 0; - - virtual void add_port(DriverPort* port) = 0; - virtual DriverPort* remove_port(const Raul::Path& path) = 0; - - virtual SampleCount buffer_size() const = 0; - virtual SampleCount sample_rate() const = 0; - virtual SampleCount frame_time() const = 0; - - virtual bool is_realtime() const = 0; - - virtual ProcessContext& context() = 0; -}; - - -} // namespace Ingen - -#endif // AUDIODRIVER_H diff --git a/src/libs/engine/Buffer.cpp b/src/libs/engine/Buffer.cpp deleted file mode 100644 index d019146c..00000000 --- a/src/libs/engine/Buffer.cpp +++ /dev/null @@ -1,38 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard <http://drobilla.net> - * - * 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 "AudioBuffer.hpp" -#include "EventBuffer.hpp" - -namespace Ingen { - - -Buffer* -Buffer::create(DataType type, size_t size) -{ - if (type.is_control()) - return new AudioBuffer(1); - else if (type.is_audio()) - return new AudioBuffer(size); - else if (type.is_event()) - return new EventBuffer(size); - else - throw; -} - - -} // namespace Ingen diff --git a/src/libs/engine/Buffer.hpp b/src/libs/engine/Buffer.hpp deleted file mode 100644 index e388e2e8..00000000 --- a/src/libs/engine/Buffer.hpp +++ /dev/null @@ -1,76 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard <http://drobilla.net> - * - * 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 BUFFER_H -#define BUFFER_H - -#include <cstddef> -#include <cassert> -#include <boost/utility.hpp> -#include <raul/Deletable.hpp> -#include "types.hpp" -#include "interface/DataType.hpp" - -namespace Ingen { - - -class Buffer : public boost::noncopyable, public Raul::Deletable -{ -public: - Buffer(Shared::DataType type, size_t size) - : _type(type) - , _size(size) - , _joined_buf(NULL) - {} - - static Buffer* create(Shared::DataType type, size_t size); - - /** Clear contents and reset state */ - virtual void clear() = 0; - - virtual void* raw_data() = 0; - virtual const void* raw_data() const = 0; - - /** Rewind (ie reset read pointer), but leave contents unchanged */ - virtual void rewind() const = 0; - - virtual void prepare_read(FrameTime start, SampleCount nframes) = 0; - virtual void prepare_write(FrameTime start, SampleCount nframes) = 0; - - bool is_joined() const { return (_joined_buf != NULL); } - Buffer* joined_buffer() const { return _joined_buf; } - - virtual bool join(Buffer* buf) = 0; - virtual void unjoin() = 0; - - virtual void copy(const Buffer* src, size_t start_sample, size_t end_sample) = 0; - - virtual void resize(size_t size) { _size = size; } - - Shared::DataType type() const { return _type; } - size_t size() const { return _size; } - -protected: - Shared::DataType _type; - size_t _size; - Buffer* _joined_buf; -}; - - -} // namespace Ingen - -#endif // BUFFER_H diff --git a/src/libs/engine/ClientBroadcaster.cpp b/src/libs/engine/ClientBroadcaster.cpp deleted file mode 100644 index d754f072..00000000 --- a/src/libs/engine/ClientBroadcaster.cpp +++ /dev/null @@ -1,271 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard <http://drobilla.net> - * - * 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 <cassert> -#include <iostream> -#include <unistd.h> -#include "interface/ClientInterface.hpp" -#include "ClientBroadcaster.hpp" -#include "EngineStore.hpp" -#include "NodeFactory.hpp" -#include "util.hpp" -#include "PatchImpl.hpp" -#include "NodeImpl.hpp" -#include "PluginImpl.hpp" -#include "PortImpl.hpp" -#include "ConnectionImpl.hpp" -#include "AudioDriver.hpp" -#include "ObjectSender.hpp" -#include "OSCClientSender.hpp" - -using namespace std; -using Ingen::Shared::ClientInterface; - -namespace Ingen { - - -/** Register a client to receive messages over the notification band. - */ -void -ClientBroadcaster::register_client(const string& uri, ClientInterface* client) -{ - Clients::iterator i = _clients.find(uri); - - if (i == _clients.end()) { - _clients[uri] = client; - cout << "[ClientBroadcaster] Registered client: " << uri << endl; - } else { - cout << "[ClientBroadcaster] Client already registered: " << uri << endl; - } -} - - -/** Remove a client from the list of registered clients. - * - * @return true if client was found and removed. - */ -bool -ClientBroadcaster::unregister_client(const string& uri) -{ - size_t erased = _clients.erase(uri); - - if (erased > 0) - cout << "Unregistered client: " << uri << endl; - else - cout << "Failed to find client to unregister: " << uri << endl; - - return (erased > 0); -} - - - -/** Looks up the client with the given @a source address (which is used as the - * unique identifier for registered clients). - * - * (A responder is passed to remove the dependency on liblo addresses in request - * events, in anticipation of libom and multiple ways of responding to clients). - */ -ClientInterface* -ClientBroadcaster::client(const string& uri) -{ - Clients::iterator i = _clients.find(uri); - if (i != _clients.end()) { - return (*i).second; - } else { - return NULL; - } -} - - -void -ClientBroadcaster::bundle_begin() -{ - for (Clients::const_iterator i = _clients.begin(); i != _clients.end(); ++i) - (*i).second->bundle_begin(); -} - - -void -ClientBroadcaster::bundle_end() -{ - for (Clients::const_iterator i = _clients.begin(); i != _clients.end(); ++i) - (*i).second->bundle_end(); -} - - -void -ClientBroadcaster::send_error(const string& msg) -{ - for (Clients::const_iterator i = _clients.begin(); i != _clients.end(); ++i) - (*i).second->error(msg); -} - -void -ClientBroadcaster::send_plugins_to(ClientInterface* client, const NodeFactory::Plugins& plugins) -{ - client->transfer_begin(); - - for (NodeFactory::Plugins::const_iterator i = plugins.begin(); i != plugins.end(); ++i) { - const PluginImpl* const plugin = i->second; - client->new_plugin(plugin->uri(), plugin->type_uri(), plugin->symbol(), plugin->name()); - } - - client->transfer_end(); -} - - -void -ClientBroadcaster::send_plugins(const NodeFactory::Plugins& plugins) -{ - for (Clients::const_iterator c = _clients.begin(); c != _clients.end(); ++c) - send_plugins_to((*c).second, plugins); -} - - -void -ClientBroadcaster::send_node(const NodeImpl* node, bool recursive) -{ - for (Clients::const_iterator i = _clients.begin(); i != _clients.end(); ++i) - ObjectSender::send_node((*i).second, node, recursive); -} - - -void -ClientBroadcaster::send_port(const PortImpl* port) -{ - for (Clients::const_iterator i = _clients.begin(); i != _clients.end(); ++i) - ObjectSender::send_port((*i).second, port); -} - - -void -ClientBroadcaster::send_destroyed(const string& path) -{ - assert(path != "/"); - for (Clients::const_iterator i = _clients.begin(); i != _clients.end(); ++i) - (*i).second->destroy(path); -} - - -void -ClientBroadcaster::send_patch_cleared(const string& patch_path) -{ - for (Clients::const_iterator i = _clients.begin(); i != _clients.end(); ++i) - (*i).second->patch_cleared(patch_path); -} - -void -ClientBroadcaster::send_connection(const SharedPtr<const ConnectionImpl> c) -{ - for (Clients::const_iterator i = _clients.begin(); i != _clients.end(); ++i) - (*i).second->connect(c->src_port()->path(), c->dst_port()->path()); -} - - -void -ClientBroadcaster::send_disconnection(const string& src_port_path, const string& dst_port_path) -{ - for (Clients::const_iterator i = _clients.begin(); i != _clients.end(); ++i) - (*i).second->disconnect(src_port_path, dst_port_path); -} - - -/** Send notification of a variable update. - * - * Like control changes, does not send update to client that set the variable, if applicable. - */ -void -ClientBroadcaster::send_variable_change(const string& node_path, const string& key, const Atom& value) -{ - for (Clients::const_iterator i = _clients.begin(); i != _clients.end(); ++i) - (*i).second->set_variable(node_path, key, value); -} - - -/** Send notification of a property update. - * - * Like control changes, does not send update to client that set the property, if applicable. - */ -void -ClientBroadcaster::send_property_change(const string& node_path, const string& key, const Atom& value) -{ - for (Clients::const_iterator i = _clients.begin(); i != _clients.end(); ++i) - (*i).second->set_property(node_path, key, value); -} - - -/** Send notification of a control change. - * - * If responder is specified, the notification will not be send to the address of - * that responder (to avoid sending redundant information back to clients and - * forcing clients to ignore things to avoid feedback loops etc). - */ -void -ClientBroadcaster::send_port_value(const string& port_path, const Raul::Atom& value) -{ - for (Clients::const_iterator i = _clients.begin(); i != _clients.end(); ++i) - (*i).second->set_port_value(port_path, value); -} - - -void -ClientBroadcaster::send_port_activity(const string& port_path) -{ - for (Clients::const_iterator i = _clients.begin(); i != _clients.end(); ++i) - (*i).second->port_activity(port_path); -} - - -void -ClientBroadcaster::send_program_add(const string& node_path, int bank, int program, const string& name) -{ - for (Clients::const_iterator i = _clients.begin(); i != _clients.end(); ++i) - (*i).second->program_add(node_path, bank, program, name); -} - - -void -ClientBroadcaster::send_program_remove(const string& node_path, int bank, int program) -{ - for (Clients::const_iterator i = _clients.begin(); i != _clients.end(); ++i) - (*i).second->program_remove(node_path, bank, program); -} - - -/** Send a patch. - * - * Sends all objects underneath Patch - contained Nodes, etc. - */ -void -ClientBroadcaster::send_patch(const PatchImpl* p, bool recursive) -{ - for (Clients::const_iterator i = _clients.begin(); i != _clients.end(); ++i) - ObjectSender::send_patch((*i).second, p, recursive); -} - - -/** Sends notification of an GraphObject's renaming - */ -void -ClientBroadcaster::send_rename(const string& old_path, const string& new_path) -{ - for (Clients::const_iterator i = _clients.begin(); i != _clients.end(); ++i) - (*i).second->object_renamed(old_path, new_path); -} - - -} // namespace Ingen diff --git a/src/libs/engine/ClientBroadcaster.hpp b/src/libs/engine/ClientBroadcaster.hpp deleted file mode 100644 index b0963610..00000000 --- a/src/libs/engine/ClientBroadcaster.hpp +++ /dev/null @@ -1,97 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard <http://drobilla.net> - * - * 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 CLIENTBROADCASTER_H -#define CLIENTBROADCASTER_H - -#include <string> -#include <list> -#include <map> -#include <lo/lo.h> -#include <pthread.h> -#include <raul/SharedPtr.hpp> -#include "interface/ClientInterface.hpp" -#include "types.hpp" -#include "NodeFactory.hpp" - -using std::string; - -namespace Ingen { - -class NodeImpl; -class PortImpl; -class PluginImpl; -class PatchImpl; -class ConnectionImpl; -using Shared::ClientInterface; - - -/** Broadcaster for all clients. - * - * This sends messages to all client simultaneously through the opaque - * ClientInterface. The clients may be OSC driver, in process, theoretically - * anything that implements ClientInterface. - * - * This also serves as the database of all registered clients. - * - * \ingroup engine - */ -class ClientBroadcaster -{ -public: - void register_client(const string& uri, ClientInterface* client); - bool unregister_client(const string& uri); - - ClientInterface* client(const string& uri); - - //void send_client_registration(const string& url, int client_id); - - void bundle_begin(); - void bundle_end(); - - // Error that isn't the direct result of a request - void send_error(const string& msg); - - void send_plugins(const NodeFactory::Plugins& plugin_list); - void send_patch(const PatchImpl* p, bool recursive); - void send_node(const NodeImpl* node, bool recursive); - void send_port(const PortImpl* port); - void send_destroyed(const string& path); - void send_patch_cleared(const string& patch_path); - void send_connection(const SharedPtr<const ConnectionImpl> connection); - void send_disconnection(const string& src_port_path, const string& dst_port_path); - void send_rename(const string& old_path, const string& new_path); - void send_variable_change(const string& node_path, const string& key, const Raul::Atom& value); - void send_property_change(const string& node_path, const string& key, const Raul::Atom& value); - void send_port_value(const string& port_path, const Raul::Atom& value); - void send_port_activity(const string& port_path); - void send_program_add(const string& node_path, int bank, int program, const string& name); - void send_program_remove(const string& node_path, int bank, int program); - - void send_plugins_to(ClientInterface*, const NodeFactory::Plugins& plugin_list); - -private: - typedef std::map<string, ClientInterface*> Clients; - Clients _clients; -}; - - - -} // namespace Ingen - -#endif // CLIENTBROADCASTER_H - diff --git a/src/libs/engine/CompiledPatch.hpp b/src/libs/engine/CompiledPatch.hpp deleted file mode 100644 index 9ca1d6e9..00000000 --- a/src/libs/engine/CompiledPatch.hpp +++ /dev/null @@ -1,83 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard <http://drobilla.net> - * - * 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 COMPILED_PATCH_HPP -#define COMPILED_PATCH_HPP - -#include <iostream> -#include <vector> -#include <raul/List.hpp> -#include <raul/Deletable.hpp> -#include <boost/utility.hpp> - -using Raul::List; - -using namespace std; - -namespace Ingen { - - -/** All information required about a node to execute it in an audio thread. - */ -struct CompiledNode { - CompiledNode(NodeImpl* n, size_t np, List<NodeImpl*>* d) - : _node(n), _n_providers(np) - { - // Copy to a vector for maximum iteration speed and cache optimization - // (Need to take a copy anyway) - - _dependants.reserve(d->size()); - for (List<NodeImpl*>::iterator i = d->begin(); i != d->end(); ++i) - _dependants.push_back(*i); - } - - NodeImpl* node() const { return _node; } - size_t n_providers() const { return _n_providers; } - const vector<NodeImpl*>& dependants() const { return _dependants; } - -private: - NodeImpl* _node; - size_t _n_providers; ///< Number of input ready signals to trigger run - vector<NodeImpl*> _dependants; ///< Nodes this one's output ports are connected to -}; - - -/** A patch and a set of connections, "compiled" into a flat structure with - * the correct order so the audio thread(s) can execute it without - * threading problems (since the preprocessor thread fiddles with other - * things). - * - * Currently objects still have some 'heavyweight' connection state, but - * eventually this should be the only place a particular set of connections - * in a patch is stored, so various "connection presets" can be switched - * in a realtime safe way. - * - * The nodes contained here are sorted in the order they must be executed. - * The parallel processing algorithm guarantees no node will be executed - * before it's providers, using this order as well as semaphores. - */ -struct CompiledPatch : public std::vector<CompiledNode> - , public Raul::Deletable - , public boost::noncopyable { - /*CompiledPatch() : std::vector<CompiledNode>() {} - CompiledPatch(size_t reserve) : std::vector<CompiledNode>(reserve) {}*/ -}; - - -} // namespace Ingen - -#endif // COMPILED_PATCH_HPP diff --git a/src/libs/engine/ConnectionImpl.cpp b/src/libs/engine/ConnectionImpl.cpp deleted file mode 100644 index d226b4dd..00000000 --- a/src/libs/engine/ConnectionImpl.cpp +++ /dev/null @@ -1,185 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard <http://drobilla.net> - * - * 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 <algorithm> -#include <raul/Maid.hpp> -#include "util.hpp" -#include "ConnectionImpl.hpp" -#include "NodeImpl.hpp" -#include "PortImpl.hpp" -#include "AudioBuffer.hpp" -#include "ProcessContext.hpp" - -#include <iostream> -using namespace std; - -namespace Ingen { - - -/** Constructor for a connection from a node's output port. - * - * This handles both polyphonic and monophonic nodes, transparently to the - * user (InputPort). - */ -ConnectionImpl::ConnectionImpl(PortImpl* src_port, PortImpl* dst_port) - : _src_port(src_port) - , _dst_port(dst_port) - , _local_buffer(NULL) - , _buffer_size(dst_port->buffer_size()) - /*, _must_mix( (src_port->poly() != dst_port->poly()) - || (src_port->buffer(0)->size() < dst_port->buffer(0)->size()) )*/ - , _must_mix( (src_port->polyphonic() && (! dst_port->polyphonic())) - || (src_port->poly() != dst_port->poly() ) - || (src_port->buffer(0)->size() < dst_port->buffer(0)->size()) ) - , _pending_disconnection(false) -{ - assert(src_port); - assert(dst_port); - assert(src_port != dst_port); - assert(src_port->path() != dst_port->path()); - assert(src_port->type() == dst_port->type() - || ( (src_port->type() == DataType::CONTROL || src_port->type() == DataType::AUDIO) - && (dst_port->type() == DataType::CONTROL || dst_port->type() == DataType::AUDIO) )); - - /*assert((src_port->parent_node()->poly() == dst_port->parent_node()->poly()) - || (src_port->parent_node()->poly() == 1 || dst_port->parent_node()->poly() == 1));*/ - - if (type() == DataType::EVENT) - _must_mix = false; // FIXME: kludge - - if (_must_mix) - _local_buffer = Buffer::create(dst_port->type(), dst_port->buffer(0)->size()); - - /* FIXME: 1->1 connections with a destination with fixed buffers copies unecessarily */ - //cerr << src_port->path() << " -> " << dst_port->path() << " must mix: " << _must_mix << endl; -} - - -ConnectionImpl::~ConnectionImpl() -{ - delete _local_buffer; -} - - -void -ConnectionImpl::set_buffer_size(size_t size) -{ - if (_must_mix) { - assert(_local_buffer); - delete _local_buffer; - - _local_buffer = Buffer::create(_dst_port->type(), _dst_port->buffer(0)->size()); - } - - _buffer_size = size; -} - - -void -ConnectionImpl::prepare_poly(uint32_t poly) -{ - _src_port->prepare_poly(poly); - - if (type() == DataType::CONTROL || type() == DataType::AUDIO) - _must_mix = (poly > 1) && ( - (_src_port->poly() != _dst_port->poly()) - || (_src_port->polyphonic() && !_dst_port->polyphonic()) - || (_src_port->parent()->polyphonic() && !_dst_port->parent()->polyphonic()) ); - - /*cerr << src_port()->path() << " * " << src_port()->poly() - << " -> " << dst_port()->path() << " * " << dst_port()->poly() - << "\t\tmust mix: " << _must_mix << " at poly " << poly << endl;*/ - - if (_must_mix && ! _local_buffer) - _local_buffer = Buffer::create(_dst_port->type(), _dst_port->buffer(0)->size()); -} - - -void -ConnectionImpl::apply_poly(Raul::Maid& maid, uint32_t poly) -{ - _src_port->apply_poly(maid, poly); - if (poly == 1 && _local_buffer && !_must_mix) { - maid.push(_local_buffer); - _local_buffer = NULL; - } -} - - -void -ConnectionImpl::process(ProcessContext& context) -{ - // FIXME: nframes parameter not used - assert(_buffer_size == 1 || _buffer_size == context.nframes()); - - /* Thought: A poly output port can be connected to multiple mono input - * ports, which means this mix down would have to happen many times. - * Adding a method to OutputPort that mixes down all it's outputs into - * a buffer (if it hasn't been done already this cycle) and returns that - * would avoid having to mix multiple times. Probably not a very common - * case, but it would be faster anyway. */ - - /*cerr << src_port()->path() << " * " << src_port()->poly() - << " -> " << dst_port()->path() << " * " << dst_port()->poly() - << "\t\tmust mix: " << _must_mix << endl;*/ - - if (_must_mix && (type() == DataType::CONTROL || type() == DataType::AUDIO)) { - - const AudioBuffer* const src_buffer = (AudioBuffer*)src_port()->buffer(0); - AudioBuffer* mix_buf = (AudioBuffer*)_local_buffer; - - assert(mix_buf); - - const size_t copy_size = std::min(src_buffer->size(), mix_buf->size()); - - // Copy src buffer to start of mix buffer - mix_buf->copy((AudioBuffer*)src_port()->buffer(0), 0, copy_size-1); - - // Write last value of src buffer to remainder of dst buffer, if necessary - if (copy_size < mix_buf->size()) - mix_buf->set_block(src_buffer->value_at(copy_size-1), copy_size, mix_buf->size()-1); - - // Accumulate the source's voices into local buffer starting at the second - // voice (buffer is already set to first voice above) - for (uint32_t j=1; j < src_port()->poly(); ++j) { - mix_buf->accumulate((AudioBuffer*)src_port()->buffer(j), 0, copy_size-1); - } - - // Find the summed value and write it to the remainder of dst buffer - if (copy_size < mix_buf->size()) { - float src_value = src_buffer->value_at(copy_size-1); - for (uint32_t j=1; j < src_port()->poly(); ++j) - src_value += ((AudioBuffer*)src_port()->buffer(j))->value_at(copy_size-1); - - mix_buf->set_block(src_value, copy_size, mix_buf->size()-1); - } - - // Scale the buffer down. - if (src_port()->poly() > 1) - mix_buf->scale(1.0f/(float)src_port()->poly(), 0, _buffer_size-1); - - } else if (_must_mix && type() == DataType::EVENT) { - - std::cerr << "WARNING: No event mixing." << std::endl; - - } - -} - - -} // namespace Ingen - diff --git a/src/libs/engine/ConnectionImpl.hpp b/src/libs/engine/ConnectionImpl.hpp deleted file mode 100644 index b3da1b54..00000000 --- a/src/libs/engine/ConnectionImpl.hpp +++ /dev/null @@ -1,101 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard <http://drobilla.net> - * - * 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 CONNECTIONIMPL_H -#define CONNECTIONIMPL_H - -#include <cstdlib> -#include <boost/utility.hpp> -#include <raul/Deletable.hpp> -#include "interface/DataType.hpp" -#include "interface/Connection.hpp" -#include "PortImpl.hpp" -#include "types.hpp" - -namespace Ingen { - -class PortImpl; -class Buffer; - - -/** Represents a single inbound connection for an InputPort. - * - * This can be a group of ports (ie coming from a polyphonic Node) or - * a single Port. This class exists basically as an abstraction of mixing - * down polyphonic inputs, so InputPort can just deal with mixing down - * multiple connections (oblivious to the polyphonic situation of the - * connection itself). - * - * \ingroup engine - */ -class ConnectionImpl : public Raul::Deletable, public Shared::Connection -{ -public: - ConnectionImpl(PortImpl* src_port, PortImpl* dst_port); - virtual ~ConnectionImpl(); - - PortImpl* src_port() const { return _src_port; } - PortImpl* dst_port() const { return _dst_port; } - - const Raul::Path src_port_path() const { return _src_port->path(); } - const Raul::Path dst_port_path() const { return _dst_port->path(); } - - /** Used by some (recursive) events to prevent double disconnections */ - bool pending_disconnection() { return _pending_disconnection; } - void pending_disconnection(bool b) { _pending_disconnection = b; } - - void process(ProcessContext& context); - - /** Get the buffer for a particular voice. - * A Connection is smart - it knows the destination port requesting the - * buffer, and will return accordingly (ie the same buffer for every voice - * in a mono->poly connection). - */ - inline Buffer* buffer(size_t voice) const; - - void set_buffer_size(size_t size); - void prepare_poly(uint32_t poly); - void apply_poly(Raul::Maid& maid, uint32_t poly); - - DataType type() const { return _src_port->type(); } - -protected: - PortImpl* const _src_port; - PortImpl* const _dst_port; - Buffer* _local_buffer; - size_t _buffer_size; - bool _must_mix; - bool _pending_disconnection; -}; - - -inline Buffer* -ConnectionImpl::buffer(size_t voice) const -{ - if (_must_mix) { - return _local_buffer; - } else if ( ! _src_port->polyphonic()) { - return _src_port->buffer(0); - } else { - return _src_port->buffer(voice); - } -} - - -} // namespace Ingen - -#endif // CONNECTIONIMPL_H diff --git a/src/libs/engine/Context.hpp b/src/libs/engine/Context.hpp deleted file mode 100644 index 2e000fb1..00000000 --- a/src/libs/engine/Context.hpp +++ /dev/null @@ -1,51 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard <http://drobilla.net> - * - * 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 CONTEXT_H -#define CONTEXT_H - -namespace Ingen { - -class Engine; - -class Context -{ -public: - enum ID { - AUDIO, - MESSAGE - }; - - Context(Engine& engine, ID id) - : _id(id) - , _engine(engine) - {} - - virtual ~Context() {} - - inline Engine& engine() const { return _engine; } - -protected: - ID _id; ///< Fast ID for this context - Engine& _engine; ///< Engine we're running in -}; - - -} // namespace Ingen - -#endif // CONTEXT_H - diff --git a/src/libs/engine/Driver.hpp b/src/libs/engine/Driver.hpp deleted file mode 100644 index 590b66b5..00000000 --- a/src/libs/engine/Driver.hpp +++ /dev/null @@ -1,98 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard <http://drobilla.net> - * - * 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 DRIVER_H -#define DRIVER_H - -#include <string> -#include <boost/utility.hpp> -#include <raul/Path.hpp> -#include "interface/DataType.hpp" -#include "DuplexPort.hpp" - -namespace Ingen { - -class DuplexPort; - - -/** Representation of a "system" (eg outside Ingen) port. - * - * This is the class through which the rest of the engine manages everything - * related to driver ports. Derived classes are expected to have a pointer to - * their driver (to be able to perform the operation necessary). - * - * \ingroup engine - */ -class DriverPort : boost::noncopyable { -public: - virtual ~DriverPort() {} - - /** Set the name of the system port */ - virtual void set_name(const std::string& name) = 0; - - bool is_input() const { return _patch_port->is_input(); } - DuplexPort* patch_port() const { return _patch_port; } - -protected: - /** is_input from the perspective outside of ingen */ - DriverPort(DuplexPort* port) : _patch_port(port) {} - - DuplexPort* _patch_port; -}; - - -/** Driver abstract base class. - * - * A Driver is, from the perspective of GraphObjects (nodes, patches, ports) an - * interface for managing system ports. An implementation of Driver basically - * needs to manage DriverPorts, and handle writing/reading data to/from them. - * - * \ingroup engine - */ -class Driver : boost::noncopyable -{ -public: - Driver(DataType type) - : _type(type) - {} - - virtual ~Driver() {} - - virtual void activate() = 0; - virtual void deactivate() = 0; - - virtual bool is_activated() const = 0; - - /** Create a port ready to be inserted with add_input (non realtime). - * - * May return NULL if the Driver can not drive the port for some reason. - */ - virtual DriverPort* create_port(DuplexPort* patch_port) = 0; - - virtual DriverPort* driver_port(const Raul::Path& path) = 0; - - virtual void add_port(DriverPort* port) = 0; - virtual DriverPort* remove_port(const Raul::Path& path) = 0; - -protected: - DataType _type; -}; - - -} // namespace Ingen - -#endif // DRIVER_H diff --git a/src/libs/engine/DuplexPort.cpp b/src/libs/engine/DuplexPort.cpp deleted file mode 100644 index 31bfbe09..00000000 --- a/src/libs/engine/DuplexPort.cpp +++ /dev/null @@ -1,108 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard <http://drobilla.net> - * - * 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 <iostream> -#include <cstdlib> -#include <cassert> -#include "util.hpp" -#include "DuplexPort.hpp" -#include "ConnectionImpl.hpp" -#include "OutputPort.hpp" -#include "NodeImpl.hpp" -#include "ProcessContext.hpp" -#include "EventBuffer.hpp" - -using namespace std; - -namespace Ingen { - - -DuplexPort::DuplexPort(NodeImpl* parent, const string& name, uint32_t index, uint32_t poly, DataType type, const Atom& value, size_t buffer_size, bool is_output) - : PortImpl(parent, name, index, poly, type, value, buffer_size) - , InputPort(parent, name, index, poly, type, value, buffer_size) - , OutputPort(parent, name, index, poly, type, value, buffer_size) - , _is_output(is_output) -{ - assert(PortImpl::_parent == parent); -} - - -void -DuplexPort::pre_process(ProcessContext& context) -{ - // <BrainHurt> - - /*cerr << endl << "{ duplex pre" << endl; - cerr << path() << " duplex pre: fixed buffers: " << fixed_buffers() << endl; - cerr << path() << " duplex pre: buffer: " << buffer(0) << endl; - cerr << path() << " duplex pre: is_output: " << _is_output << " { " << endl;*/ - - /*if (type() == DataType::EVENT) - for (uint32_t i=0; i < _poly; ++i) - cerr << path() << " (" << buffer(i) << ") # events: " - << ((EventBuffer*)buffer(i))->event_count() - << ", joined: " << _buffers->at(i)->is_joined() << endl;*/ - - if (_is_output) { - - for (uint32_t i=0; i < _poly; ++i) - if (!_buffers->at(i)->is_joined()) - _buffers->at(i)->prepare_write(context.start(), context.nframes()); - - } else { - - for (uint32_t i=0; i < _poly; ++i) - _buffers->at(i)->prepare_read(context.start(), context.nframes()); - - broadcast(context); - } - - //cerr << "} duplex pre " << path() << endl; - - // </BrainHurt> -} - - -void -DuplexPort::post_process(ProcessContext& context) -{ - // <BrainHurt> - - /*cerr << endl << "{ duplex post" << endl; - cerr << path() << " duplex post: fixed buffers: " << fixed_buffers() << endl; - cerr << path() << " duplex post: buffer: " << buffer(0) << endl; - cerr << path() << " duplex post: is_output: " << _is_output << " { " << endl; - - if (type() == DataType::EVENT) - for (uint32_t i=0; i < _poly; ++i) - cerr << path() << " (" << buffer(i) << ") # events: " - << ((EventBuffer*)buffer(i))->event_count() - << ", joined: " << _buffers->at(i)->is_joined() << endl;*/ - - if (_is_output) { - InputPort::pre_process(context); // Mix down inputs - broadcast(context); - } - - //cerr << "} duplex post " << path() << endl; - - // </BrainHurt> -} - - -} // namespace Ingen - diff --git a/src/libs/engine/DuplexPort.hpp b/src/libs/engine/DuplexPort.hpp deleted file mode 100644 index 43d202a9..00000000 --- a/src/libs/engine/DuplexPort.hpp +++ /dev/null @@ -1,68 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard <http://drobilla.net> - * - * 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 DUPLEXPORT_H -#define DUPLEXPORT_H - -#include <string> -#include <raul/Array.hpp> -#include "types.hpp" -#include "Buffer.hpp" -#include "InputPort.hpp" -#include "OutputPort.hpp" - -namespace Ingen { - -class NodeImpl; - - -/** A duplex port (which is both an InputPort and an OutputPort) - * - * This is used for Patch ports, since they need to appear as both an input - * and an output port based on context. Eg. a patch output appears as an - * input inside the patch, so nodes inside the patch can feed it data. - * - * \ingroup engine - */ -class DuplexPort : public InputPort, public OutputPort -{ -public: - DuplexPort(NodeImpl* parent, - const std::string& name, - uint32_t index, - uint32_t poly, - DataType type, - const Atom& value, - size_t buffer_size, - bool is_output); - - virtual ~DuplexPort() {} - - void pre_process(ProcessContext& context); - void post_process(ProcessContext& context); - - bool is_input() const { return !_is_output; } - bool is_output() const { return _is_output; } - -protected: - bool _is_output; -}; - - -} // namespace Ingen - -#endif // DUPLEXPORT_H diff --git a/src/libs/engine/Engine.cpp b/src/libs/engine/Engine.cpp deleted file mode 100644 index a08a37ca..00000000 --- a/src/libs/engine/Engine.cpp +++ /dev/null @@ -1,317 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard <http://drobilla.net> - * - * 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 <cassert> -#include <sys/mman.h> -#include <iostream> -#include <unistd.h> -#include <raul/Deletable.hpp> -#include <raul/Maid.hpp> -#include <raul/SharedPtr.hpp> -#include "Engine.hpp" -#include CONFIG_H_PATH -#include "tuning.hpp" -#include "Event.hpp" -#include "common/interface/EventType.hpp" -#include "shared/Store.hpp" -#include "JackAudioDriver.hpp" -#include "NodeFactory.hpp" -#include "ClientBroadcaster.hpp" -#include "PatchImpl.hpp" -#include "EngineStore.hpp" -#include "MidiDriver.hpp" -#include "OSCDriver.hpp" -#include "QueuedEventSource.hpp" -#include "PostProcessor.hpp" -#include "CreatePatchEvent.hpp" -#include "EnablePatchEvent.hpp" -#include "OSCEngineReceiver.hpp" -#ifdef HAVE_SOUP -#include "HTTPEngineReceiver.hpp" -#endif -#include "PostProcessor.hpp" -#include "ProcessSlave.hpp" -#include "ProcessContext.hpp" -#include "MessageContext.hpp" -#include "ThreadManager.hpp" -#ifdef HAVE_JACK_MIDI -#include "JackMidiDriver.hpp" -#endif -using namespace std; - -namespace Ingen { - - -Engine::Engine(Ingen::Shared::World* world) - : _world(world) - , _midi_driver(NULL) - , _osc_driver(NULL) - , _maid(new Raul::Maid(maid_queue_size)) - , _post_processor(new PostProcessor(*this, /**_maid, */post_processor_queue_size)) - , _broadcaster(new ClientBroadcaster()) - , _node_factory(new NodeFactory(world)) - , _message_context(new MessageContext(*this)) - , _quit_flag(false) - , _activated(false) -{ - if (world->store) { - assert(PtrCast<EngineStore>(world->store)); - } else { - world->store = SharedPtr<Store>(new EngineStore()); - } -} - - -Engine::~Engine() -{ - deactivate(); - - for (EngineStore::iterator i = engine_store()->begin(); - i != engine_store()->end(); ++i) { - if ( ! PtrCast<GraphObjectImpl>(i->second)->parent() ) - i->second.reset(); - } - - delete _broadcaster; - delete _node_factory; - delete _osc_driver; - delete _post_processor; - //delete _lash_driver; - - delete _maid; - - munlockall(); -} - - -SharedPtr<EngineStore> -Engine::engine_store() const -{ - return PtrCast<EngineStore>(_world->store); -} - - -Driver* -Engine::driver(DataType type, EventType event_type) -{ - if (type == DataType::AUDIO) { - return _audio_driver.get(); - } else if (type == DataType::EVENT) { - if (event_type == EventType::MIDI) { - return _midi_driver; - } else if (event_type == EventType::OSC) { - return _osc_driver; - } - } - - return NULL; -} - - -int -Engine::main() -{ - Thread::get().set_context(THREAD_POST_PROCESS); - - // Loop until quit flag is set (by OSCReceiver) - while ( ! _quit_flag) { - nanosleep(&main_rate, NULL); - main_iteration(); - } - cout << "[Main] Done main loop." << endl; - - deactivate(); - - return 0; -} - - -/** Run one iteration of the main loop. - * - * NOT realtime safe (this is where deletion actually occurs) - */ -bool -Engine::main_iteration() -{ -/*#ifdef HAVE_LASH - // Process any pending LASH events - if (lash_driver->enabled()) - lash_driver->process_events(); -#endif*/ - // Run the maid (garbage collector) - _post_processor->process(); - _maid->cleanup(); - - return !_quit_flag; -} - - -void -Engine::start_jack_driver() -{ - if ( ! _audio_driver) - _audio_driver = SharedPtr<AudioDriver>(new JackAudioDriver(*this)); - else - cerr << "[Engine::start_jack_driver] Audio driver already running" << endl; -} - - -void -Engine::start_osc_driver(int port) -{ - if (_event_source) { - cerr << "WARNING: Replacing event source" << endl; - _event_source.reset(); - } - - _event_source = SharedPtr<EventSource>(new OSCEngineReceiver( - *this, pre_processor_queue_size, port)); -} - - -void -Engine::start_http_driver(int port) -{ -#ifdef HAVE_SOUP - // FIXE: leak - HTTPEngineReceiver* server = new HTTPEngineReceiver(*this, port); - server->activate(); -#endif -} - - -SharedPtr<QueuedEngineInterface> -Engine::new_queued_interface() -{ - if (_event_source) { - cerr << "WARNING: Replacing event source" << endl; - _event_source.reset(); - } - - SharedPtr<QueuedEngineInterface> result(new QueuedEngineInterface( - *this, Ingen::event_queue_size, Ingen::event_queue_size)); - - _event_source = result; - - return result; -} - -/* -void -Engine::set_event_source(SharedPtr<EventSource> source) -{ - if (_event_source) - cerr << "Warning: Dropped event source (engine interface)" << endl; - - _event_source = source; -} -*/ - - -bool -Engine::activate(size_t parallelism) -{ - if (_activated) - return false; - - assert(_audio_driver); - assert(_event_source); - -#ifdef HAVE_JACK_MIDI - _midi_driver = new JackMidiDriver(((JackAudioDriver*)_audio_driver.get())->jack_client()); -#else - _midi_driver = new DummyMidiDriver(); -#endif - - _event_source->activate(); - - // Create root patch - - PatchImpl* root_patch = new PatchImpl(*this, "", 1, NULL, - _audio_driver->sample_rate(), _audio_driver->buffer_size(), 1); - root_patch->activate(); - _world->store->add(root_patch); - root_patch->compiled_patch(root_patch->compile()); - - assert(_audio_driver->root_patch() == NULL); - _audio_driver->set_root_patch(root_patch); - - _audio_driver->activate(); - - _process_slaves.clear(); - _process_slaves.reserve(parallelism); - for (size_t i=0; i < parallelism - 1; ++i) - _process_slaves.push_back(new ProcessSlave(*this, _audio_driver->is_realtime())); - - root_patch->enable(); - - //_post_processor->start(); - - _activated = true; - - return true; -} - - -void -Engine::deactivate() -{ - if (!_activated) - return; - - _event_source->deactivate(); - - /*for (Tree<GraphObject*>::iterator i = _engine_store->objects().begin(); - i != _engine_store->objects().end(); ++i) - if ((*i)->as_node() != NULL && (*i)->as_node()->parent() == NULL) - (*i)->as_node()->deactivate();*/ - - if (_midi_driver != NULL) { - _midi_driver->deactivate(); - delete _midi_driver; - _midi_driver = NULL; - } - - _audio_driver->deactivate(); - - _audio_driver->root_patch()->deactivate(); - - for (size_t i=0; i < _process_slaves.size(); ++i) { - delete _process_slaves[i]; - } - - _process_slaves.clear(); - - // Finalize any lingering events (unlikely) - _post_processor->process(); - - _audio_driver.reset(); - _event_source.reset(); - - _activated = false; -} - - -void -Engine::process_events(ProcessContext& context) -{ - if (_event_source) - _event_source->process(*_post_processor, context); -} - - -} // namespace Ingen diff --git a/src/libs/engine/Engine.hpp b/src/libs/engine/Engine.hpp deleted file mode 100644 index fce826db..00000000 --- a/src/libs/engine/Engine.hpp +++ /dev/null @@ -1,130 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard <http://drobilla.net> - * - * 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 ENGINE_H -#define ENGINE_H - -#include CONFIG_H_PATH -#include <cassert> -#include <vector> -#include <boost/utility.hpp> -#include <raul/SharedPtr.hpp> -#include "module/global.hpp" -#include "interface/DataType.hpp" -#include "interface/EventType.hpp" - -template<typename T> class Queue; - -namespace Raul { class Maid; } - -namespace Ingen { - -class AudioDriver; -class MidiDriver; -class OSCDriver; -class NodeFactory; -class ClientBroadcaster; -class EngineStore; -class EventSource; -class PostProcessor; -class Event; -class QueuedEvent; -class QueuedEngineInterface; -class Driver; -class ProcessSlave; -class ProcessContext; -class MessageContext; - - -/** The main class for the Engine. - * - * 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(Ingen::Shared::World* world); - - virtual ~Engine(); - - virtual int main(); - virtual bool main_iteration(); - - /** Set the quit flag that should kill all threads and exit cleanly. - * Note that it will take some time. */ - virtual void quit() { _quit_flag = true; } - - virtual void start_jack_driver(); - virtual void start_osc_driver(int port); - virtual void start_http_driver(int port); - - virtual SharedPtr<QueuedEngineInterface> new_queued_interface(); - - virtual bool activate(size_t parallelism); - virtual void deactivate(); - - void process_events(ProcessContext& context); - - virtual bool activated() { return _activated; } - - Raul::Maid* maid() const { return _maid; } - EventSource* event_source() const { return _event_source.get(); } - AudioDriver* audio_driver() const { return _audio_driver.get(); } - MidiDriver* midi_driver() const { return _midi_driver; } - OSCDriver* osc_driver() const { return _osc_driver; } - PostProcessor* post_processor() const { return _post_processor; } - ClientBroadcaster* broadcaster() const { return _broadcaster; } - NodeFactory* node_factory() const { return _node_factory; } - MessageContext* message_context() const { return _message_context; } - - SharedPtr<EngineStore> engine_store() const; - - /** Return the active driver for the given type */ - Driver* driver(DataType type, EventType event_type); - - Ingen::Shared::World* world() { return _world; } - - typedef std::vector<ProcessSlave*> ProcessSlaves; - inline const ProcessSlaves& process_slaves() const { return _process_slaves; } - inline ProcessSlaves& process_slaves() { return _process_slaves; } - -private: - ProcessSlaves _process_slaves; - - Ingen::Shared::World* _world; - - SharedPtr<EventSource> _event_source; - SharedPtr<AudioDriver> _audio_driver; - MidiDriver* _midi_driver; - OSCDriver* _osc_driver; - Raul::Maid* _maid; - PostProcessor* _post_processor; - ClientBroadcaster* _broadcaster; - NodeFactory* _node_factory; - MessageContext* _message_context; - - bool _quit_flag; - bool _activated; -}; - - -} // namespace Ingen - -#endif // ENGINE_H diff --git a/src/libs/engine/EngineStore.cpp b/src/libs/engine/EngineStore.cpp deleted file mode 100644 index 9fcd3806..00000000 --- a/src/libs/engine/EngineStore.cpp +++ /dev/null @@ -1,182 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard <http://drobilla.net> - * - * 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 <utility> -#include <vector> -#include <raul/List.hpp> -#include <raul/PathTable.hpp> -#include <raul/TableImpl.hpp> -#include "EngineStore.hpp" -#include "PatchImpl.hpp" -#include "NodeImpl.hpp" -#include "PortImpl.hpp" -#include "ThreadManager.hpp" - -using namespace std; -using namespace Raul; - -namespace Ingen { - - -/** Find the Patch at the given path. - */ -PatchImpl* -EngineStore::find_patch(const Path& path) -{ - GraphObjectImpl* const object = find_object(path); - return dynamic_cast<PatchImpl*>(object); -} - - -/** Find the Node at the given path. - */ -NodeImpl* -EngineStore::find_node(const Path& path) -{ - GraphObjectImpl* const object = find_object(path); - return dynamic_cast<NodeImpl*>(object); -} - - -/** Find the Port at the given path. - */ -PortImpl* -EngineStore::find_port(const Path& path) -{ - GraphObjectImpl* const object = find_object(path); - return dynamic_cast<PortImpl*>(object); -} - - -/** Find the Object at the given path. - */ -GraphObjectImpl* -EngineStore::find_object(const Path& path) -{ - iterator i = find(path); - return ((i == end()) ? NULL : dynamic_cast<GraphObjectImpl*>(i->second.get())); -} - - -/** Add an object to the store. Not realtime safe. - */ -void -EngineStore::add(GraphObject* obj) -{ - GraphObjectImpl* o = dynamic_cast<GraphObjectImpl*>(obj); - assert(o); - - assert(ThreadManager::current_thread_id() == THREAD_PRE_PROCESS); - - Store::add(obj); -} - - -/** Add a family of objects to the store. Not realtime safe. - */ -void -EngineStore::add(const Objects& table) -{ - assert(ThreadManager::current_thread_id() == THREAD_PRE_PROCESS); - - //cerr << "[EngineStore] Adding " << o[0].second->path() << endl; - cram(table); - - /*cerr << "[EngineStore] Adding Table:" << endl; - for (const_iterator i = table.begin(); i != table.end(); ++i) { - cerr << i->first << " = " << i->second->path() << endl; - }*/ -} - - -/** Remove an object from the store. - * - * Returned is a vector containing all descendants of the object removed - * including the object itself, in lexicographically sorted order by Path. - */ -SharedPtr<EngineStore::Objects> -EngineStore::remove(const Path& path) -{ - return remove(find(path)); -} - - -/** Remove an object from the store. - * - * Returned is a vector containing all descendants of the object removed - * including the object itself, in lexicographically sorted order by Path. - */ -SharedPtr<EngineStore::Objects> -EngineStore::remove(iterator object) -{ - assert(ThreadManager::current_thread_id() == THREAD_PRE_PROCESS); - - if (object != end()) { - iterator descendants_end = find_descendants_end(object); - //cout << "[EngineStore] Removing " << object->first << " {" << endl; - SharedPtr<Objects> removed = yank(object, descendants_end); - /*for (iterator i = removed->begin(); i != removed->end(); ++i) { - cout << "\t" << i->first << endl; - } - cout << "}" << endl;*/ - - return removed; - - } else { - cerr << "[EngineStore] WARNING: Removing " << object->first << " failed." << endl; - return SharedPtr<EngineStore>(); - } -} - - -/** Remove all children of an object from the store. - * - * Returned is a vector containing all descendants of the object removed - * in lexicographically sorted order by Path. - */ -SharedPtr<EngineStore::Objects> -EngineStore::remove_children(const Path& path) -{ - return remove_children(find(path)); -} - - -/** Remove all children of an object from the store. - * - * Returned is a vector containing all descendants of the object removed - * in lexicographically sorted order by Path. - */ -SharedPtr<EngineStore::Objects> -EngineStore::remove_children(iterator object) -{ - if (object != end()) { - iterator descendants_end = find_descendants_end(object); - if (descendants_end != object) { - iterator first_child = object; - ++first_child; - return yank(first_child, descendants_end); - } - } else { - cerr << "[EngineStore] WARNING: Removing children of " << object->first << " failed." << endl; - return SharedPtr<EngineStore::Objects>(); - } - - return SharedPtr<EngineStore::Objects>(); -} - - -} // namespace Ingen diff --git a/src/libs/engine/EngineStore.hpp b/src/libs/engine/EngineStore.hpp deleted file mode 100644 index ad656aeb..00000000 --- a/src/libs/engine/EngineStore.hpp +++ /dev/null @@ -1,68 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard <http://drobilla.net> - * - * 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 OBJECTSTORE_H -#define OBJECTSTORE_H - -#include <string> -#include <raul/PathTable.hpp> -#include <raul/SharedPtr.hpp> -#include "shared/Store.hpp" - -using std::string; -using namespace Raul; - -namespace Ingen { - -namespace Shared { class GraphObject; } - -class PatchImpl; -class NodeImpl; -class PortImpl; -class GraphObjectImpl; - - -/** Storage for all GraphObjects (tree of GraphObject's sorted by path). - * - * All looking up in pre_process() methods (and anything else that isn't in-band - * with the audio thread) should use this (to read and modify the GraphObject - * tree). - * - * Searching with find*() is fast (O(log(n)) binary search on contiguous - * memory) and realtime safe, but modification (add or remove) are neither. - */ -class EngineStore : public Shared::Store -{ -public: - PatchImpl* find_patch(const Path& path); - NodeImpl* find_node(const Path& path); - PortImpl* find_port(const Path& path); - GraphObjectImpl* find_object(const Path& path); - - void add(Shared::GraphObject* o); - void add(const Objects& family); - - SharedPtr<Objects> remove(const Path& path); - SharedPtr<Objects> remove(Objects::iterator i); - SharedPtr<Objects> remove_children(const Path& path); - SharedPtr<Objects> remove_children(Objects::iterator i); -}; - - -} // namespace Ingen - -#endif // OBJECTSTORE diff --git a/src/libs/engine/Event.cpp b/src/libs/engine/Event.cpp deleted file mode 100644 index 8e5c33da..00000000 --- a/src/libs/engine/Event.cpp +++ /dev/null @@ -1,49 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard <http://drobilla.net> - * - * 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 "Event.hpp" -#include "ThreadManager.hpp" -#include "ProcessContext.hpp" - -namespace Ingen { - - -void -Event::execute(ProcessContext& context) -{ - assert(ThreadManager::current_thread_id() == THREAD_PROCESS); - assert(!_executed); - assert(_time <= context.end()); - - // Missed the event, jitter, damnit. - if (_time < context.start()) - _time = context.start(); - - _executed = true; -} - - -void -Event::post_process() -{ - // FIXME: Not true witn monolithic GUI/engine - //assert(ThreadManager::current_thread_id() == THREAD_POST_PROCESS); -} - - -} // namespace Ingen - diff --git a/src/libs/engine/Event.hpp b/src/libs/engine/Event.hpp deleted file mode 100644 index 5860da2a..00000000 --- a/src/libs/engine/Event.hpp +++ /dev/null @@ -1,75 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard <http://drobilla.net> - * - * 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 EVENT_H -#define EVENT_H - -#include <cassert> -#include <raul/SharedPtr.hpp> -#include <raul/Deletable.hpp> -#include "types.hpp" - -namespace Ingen { - -class Engine; -class Responder; -class ProcessContext; - - -/** Base class for all events (both realtime and QueuedEvent). - * - * This is for time-critical events like note ons. There is no non-realtime - * pre-execute method as in QueuedEvent's, any lookups etc need to be done in the - * realtime execute() method. - * - * QueuedEvent extends this class with a pre_process() method for any work that needs - * to be done before processing in the realtime audio thread. - * - * \ingroup engine - */ -class Event : public Raul::Deletable -{ -public: - virtual ~Event() {} - - /** Execute this event in the audio thread (MUST be realtime safe). */ - virtual void execute(ProcessContext& context); - - /** Perform any actions after execution (ie send replies to commands) - * (no realtime requirements). */ - virtual void post_process(); - - inline SampleCount time() const { return _time; } - -protected: - Event(Engine& engine, SharedPtr<Responder> responder, FrameTime time) - : _engine(engine) - , _responder(responder) - , _time(time) - , _executed(false) - {} - - Engine& _engine; - SharedPtr<Responder> _responder; - FrameTime _time; - bool _executed; -}; - - -} // namespace Ingen - -#endif // EVENT_H diff --git a/src/libs/engine/EventBuffer.cpp b/src/libs/engine/EventBuffer.cpp deleted file mode 100644 index e8584597..00000000 --- a/src/libs/engine/EventBuffer.cpp +++ /dev/null @@ -1,318 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard <http://drobilla.net> - * - * 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 - */ - -#define __STDC_LIMIT_MACROS 1 -#include <stdint.h> -#include <iostream> -#include "EventBuffer.hpp" -#include "lv2ext/lv2_event.h" -#include "lv2ext/lv2_event_helpers.h" - -using namespace std; - -namespace Ingen { - - -/** Allocate a new event buffer. - * \a capacity is in bytes (not number of events). - */ -EventBuffer::EventBuffer(size_t capacity) - : Buffer(DataType(DataType::EVENT), capacity) - , _latest_frames(0) - , _latest_subframes(0) -{ - if (capacity > UINT32_MAX) { - cerr << "Event buffer size " << capacity << " too large, aborting." << endl; - throw std::bad_alloc(); - } - - int ret = posix_memalign((void**)&_local_buf, 16, sizeof(LV2_Event_Buffer) + capacity); - if (ret) { - cerr << "Failed to allocate event buffer. Aborting." << endl; - exit(EXIT_FAILURE); - } - - _local_buf->event_count = 0; - _local_buf->capacity = (uint32_t)capacity; - _local_buf->size = 0; - _local_buf->data = reinterpret_cast<uint8_t*>(_local_buf + 1); - _buf = _local_buf; - - reset(0); - - //cerr << "Creating MIDI Buffer " << _buf << ", capacity = " << _buf->capacity << endl; -} - - -EventBuffer::~EventBuffer() -{ - free(_local_buf); -} - - -/** Use another buffer's data instead of the local one. - * - * This buffer will essentially be identical to @a buf after this call. - */ -bool -EventBuffer::join(Buffer* buf) -{ - EventBuffer* mbuf = dynamic_cast<EventBuffer*>(buf); - if (mbuf) { - _buf = mbuf->local_data(); - _joined_buf = mbuf; - _iter = mbuf->_iter; - _iter.buf = _buf; - return false; - } else { - return false; - } - - //assert(mbuf->size() == _size); - - _joined_buf = mbuf; - - return true; -} - - -void -EventBuffer::unjoin() -{ - _joined_buf = NULL; - _buf = _local_buf; - reset(_this_nframes); -} - - -void -EventBuffer::prepare_read(FrameTime start, SampleCount nframes) -{ - //cerr << "\t" << this << " prepare_read: " << event_count() << endl; - rewind(); - _this_nframes = nframes; -} - - -void -EventBuffer::prepare_write(FrameTime start, SampleCount nframes) -{ - //cerr << "\t" << this << " prepare_write: " << event_count() << endl; - reset(nframes); -} - -/** FIXME: parameters ignored */ -void -EventBuffer::copy(const Buffer* src_buf, size_t start_sample, size_t end_sample) -{ - const EventBuffer* src = dynamic_cast<const EventBuffer*>(src_buf); - assert(src); - assert(_buf->capacity >= src->_buf->capacity); - - clear(); - src->rewind(); - - memcpy(_buf, src->_buf, src->_buf->size); -} - - -/** Increment the read position by one event. - * - * \return true if increment was successful, or false if end of buffer reached. - */ -bool -EventBuffer::increment() const -{ - if (lv2_event_is_valid(&_iter)) { - lv2_event_increment(&_iter); - return true; - } else { - return false; - } -} - - -/** - * \return true iff the cursor is valid (ie get_event is safe) - */ -bool -EventBuffer::is_valid() const -{ - return lv2_event_is_valid(&_iter); -} - - -/** Append an event to the buffer. - * - * \a timestamp must be >= the latest event in the buffer, - * and < this_nframes() - * - * \return true on success - */ -bool -EventBuffer::append(uint32_t frames, - uint32_t subframes, - uint16_t type, - uint16_t size, - const uint8_t* data) -{ -#ifndef NDEBUG - if (lv2_event_is_valid(&_iter)) { - LV2_Event* last_event = lv2_event_get(&_iter, NULL); - assert(last_event->frames < frames - || (last_event->frames == frames && last_event->subframes <= subframes)); - } -#endif - - /*cout << "Appending event type " << type << ", size " << size - << " @ " << frames << "." << subframes << endl;*/ - - const bool ret = lv2_event_write(&_iter, frames, subframes, type, size, data); - - if (!ret) - cerr << "ERROR: Failed to write event." << endl; - - _latest_frames = frames; - _latest_subframes = subframes; - - return ret; -} - - -/** Append a buffer of events to the buffer. - * - * \a timestamp must be >= the latest event in the buffer, - * and < this_nframes() - * - * \return true on success - */ -bool -EventBuffer::append(const LV2_Event_Buffer* buf) -{ - uint8_t** data; - bool ret = true; - - LV2_Event_Iterator iter; - for (lv2_event_begin(&iter, _buf); lv2_event_is_valid(&iter); lv2_event_increment(&iter)) { - LV2_Event* ev = lv2_event_get(&iter, data); - -#ifndef NDEBUG - assert((ev->frames > _latest_frames) - || (ev->frames == _latest_frames - && ev->subframes >= _latest_subframes)); -#endif - - if (!(ret = append(ev->frames, ev->subframes, ev->type, ev->size, *data))) { - cerr << "ERROR: Failed to write event." << endl; - break; - } - - _latest_frames = ev->frames; - _latest_subframes = ev->subframes; - } - - return ret; -} - - -/** Read an event from the current position in the buffer - * - * \return true if read was successful, or false if end of buffer reached - */ -bool -EventBuffer::get_event(uint32_t* frames, - uint32_t* subframes, - uint16_t* type, - uint16_t* size, - uint8_t** data) const -{ - if (lv2_event_is_valid(&_iter)) { - LV2_Event* ev = lv2_event_get(&_iter, data); - *frames = ev->frames; - *subframes = ev->subframes; - *type = ev->type; - *size = ev->size; - return true; - } else { - return false; - } -} - - -/** Clear, and merge \a a and \a b into this buffer. - * - * FIXME: This is slow. - * - * \return true if complete merge was successful - */ -bool -EventBuffer::merge(const EventBuffer& a, const EventBuffer& b) -{ - // Die if a merge isn't necessary as it's expensive - assert(a.size() > 0 && b.size() > 0); - - reset(_this_nframes); - - a.rewind(); - b.rewind(); - -#if 0 - uint32_t a_frames; - uint32_t a_subframes; - uint16_t a_type; - uint16_t a_size; - uint8_t* a_data; - - uint32_t b_frames; - uint32_t b_subframes; - uint16_t b_type; - uint16_t b_size; - uint8_t* b_data; -#endif - - cout << "FIXME: merge" << endl; -#if 0 - a.get_event(&a_frames, &a_subframes, &a_type, &a_size, &a_data); - b.get_event(&b_frames, &b_subframes, &b_type, &b_size, &b_data); - - while (true) { - if (a_data && (!b_data || (a_time < b_time))) { - append(a_time, a_size, a_data); - if (a.increment()) - a.get_event(&a_time, &a_size, &a_data); - else - a_data = NULL; - } else if (b_data) { - append(b_time, b_size, b_data); - if (b.increment()) - b.get_event(&b_time, &b_size, &b_data); - else - b_data = NULL; - } else { - break; - } - } - - _latest_stamp = max(a_time, b_time); -#endif - - return true; -} - - -} // namespace Ingen - diff --git a/src/libs/engine/EventBuffer.hpp b/src/libs/engine/EventBuffer.hpp deleted file mode 100644 index 0c80d452..00000000 --- a/src/libs/engine/EventBuffer.hpp +++ /dev/null @@ -1,104 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard <http://drobilla.net> - * - * 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 EVENTBUFFER_H -#define EVENTBUFFER_H - -#include <iostream> -#include <lv2ext/lv2_event.h> -#include <lv2ext/lv2_event_helpers.h> -#include "Buffer.hpp" -#include "interface/DataType.hpp" - -namespace Ingen { - - -class EventBuffer : public Buffer { -public: - EventBuffer(size_t capacity); - - ~EventBuffer(); - - void prepare_read(FrameTime start, SampleCount nframes); - void prepare_write(FrameTime start, SampleCount nframes); - - bool join(Buffer* buf); - void unjoin(); - - inline uint32_t this_nframes() const { return _this_nframes; } - inline uint32_t event_count() const { return _buf->event_count; } - - inline void* raw_data() { return _buf; } - inline const void* raw_data() const { return _buf; } - - inline LV2_Event_Buffer* local_data() { return _local_buf; } - inline const LV2_Event_Buffer* local_data() const { return _local_buf; } - - inline LV2_Event_Buffer* data() { return _buf; } - inline const LV2_Event_Buffer* data() const { return _buf; } - - void copy(const Buffer* src, size_t start_sample, size_t end_sample); - - inline void rewind() const { lv2_event_begin(&_iter, _buf); } - inline void clear() { reset(_this_nframes); } - inline void reset(SampleCount nframes) { - //std::cerr << this << " reset" << std::endl; - _this_nframes = nframes; - _latest_frames = 0; - _latest_subframes = 0; - _buf->event_count = 0; - _buf->size = 0; - rewind(); - } - - bool increment() const; - bool is_valid() const; - - uint32_t latest_frames() const { return _latest_frames; } - uint32_t latest_subframes() const { return _latest_subframes; } - - bool get_event(uint32_t* frames, - uint32_t* subframes, - uint16_t* type, - uint16_t* size, - uint8_t** data) const; - - bool append(uint32_t frames, - uint32_t subframes, - uint16_t type, - uint16_t size, - const uint8_t* data); - - bool append(const LV2_Event_Buffer* buf); - - bool merge(const EventBuffer& a, const EventBuffer& b); - -private: - LV2_Event_Buffer* _buf; ///< Contents (maybe belong to _joined_buf) - LV2_Event_Buffer* _local_buf; ///< Local contents - - mutable LV2_Event_Iterator _iter; ///< Iterator into _buf - - uint32_t _latest_frames; ///< Latest time of all events (frames) - uint32_t _latest_subframes; ///< Latest time of all events (subframes) - uint32_t _this_nframes; ///< Current cycle nframes -}; - - -} // namespace Ingen - -#endif // EVENTBUFFER_H diff --git a/src/libs/engine/EventSink.cpp b/src/libs/engine/EventSink.cpp deleted file mode 100644 index 6c775d4c..00000000 --- a/src/libs/engine/EventSink.cpp +++ /dev/null @@ -1,74 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard <http://drobilla.net> - * - * 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 <iostream> -#include "events/SendPortValueEvent.hpp" -#include "EventSink.hpp" -#include "PortImpl.hpp" - -using namespace std; - -namespace Ingen { - -#if 0 -void -EventSink::control_change(Port* port, FrameTime time, float val) -{ - //cerr << "CONTROL CHANGE: " << port->path() << " == " << val << endl; - SendPortValueEvent ev(_engine, time, port, false, 0, val); - _events.write(sizeof(ev), (uchar*)&ev); -} -#endif - -/** \a size is not size_t because an event will never be even remotely close - * to UINT32_MAX in size, so uint32_t saves wasted space on 64-bit. - */ -bool -EventSink::write(uint32_t size, const Event* ev) -{ - if (size > _events.write_space()) - return false; - - _events.write(sizeof(uint32_t), (uint8_t*)&size); - _events.write(size, (uint8_t*)ev); - - return true; -} - - -/** Read the next event into event_buffer. - * - * \a event_buffer can be casted to Event* and virtual methods called. - */ -bool -EventSink::read(uint32_t event_buffer_size, uint8_t* event_buffer) -{ - uint32_t read_size; - bool success = _events.full_read(sizeof(uint32_t), (uint8_t*)&read_size); - if (!success) - return false; - - assert(read_size <= event_buffer_size); - - if (read_size > 0) - return _events.full_read(read_size, event_buffer); - else - return false; -} - - -} // namespace Ingen diff --git a/src/libs/engine/EventSink.hpp b/src/libs/engine/EventSink.hpp deleted file mode 100644 index 9e937d1a..00000000 --- a/src/libs/engine/EventSink.hpp +++ /dev/null @@ -1,64 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard <http://drobilla.net> - * - * 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 EVENTSINK_H -#define EVENTSINK_H - -#include <list> -#include <utility> -#include <raul/RingBuffer.hpp> -#include "events/SendPortValueEvent.hpp" -#include "types.hpp" - -namespace Ingen { - -class PortImpl; -class Engine; -class SendPortValueEvent; - - -/** Sink for events generated in the audio thread. - * - * Implemented as a flat ringbuffer of events, which are constructed directly - * in the ringbuffer rather than allocated on the heap (in order to make - * writing realtime safe). - * - * \ingroup engine - */ -class EventSink -{ -public: - EventSink(Engine& engine, size_t capacity) : _engine(engine), _events(capacity) {} - - /* FIXME: Figure out variable sized event queues and make this a generic - * interface (ie don't add a method for every event type, crap..) */ - - bool write(uint32_t size, const Event* ev); - - bool read(uint32_t event_buffer_size, uint8_t* event_buffer); - -private: - Engine& _engine; - Raul::RingBuffer<uchar> _events; -}; - - - -} // namespace Ingen - -#endif // EVENTSINK_H - diff --git a/src/libs/engine/EventSource.hpp b/src/libs/engine/EventSource.hpp deleted file mode 100644 index 68532d16..00000000 --- a/src/libs/engine/EventSource.hpp +++ /dev/null @@ -1,60 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard <http://drobilla.net> - * - * 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 EVENTSOURCE_H -#define EVENTSOURCE_H - -#include "types.hpp" - -namespace Ingen { - -class Event; -class QueuedEvent; -class PostProcessor; - - -/** Source for events to run in the audio thread. - * - * The AudioDriver gets events from an EventSource in the process callback - * (realtime audio thread) and executes them, then they are sent to the - * PostProcessor and finalised (post-processing thread). - * - * There are two distinct classes of events - "queued" and "stamped". Queued - * events are events that require non-realtime pre-processing before being - * executed in the process thread. Stamped events are timestamped realtime - * events that require no pre-processing and can be executed immediately - * (with sample accuracy). - */ -class EventSource -{ -public: - virtual ~EventSource() {} - - virtual void activate() = 0; - virtual void deactivate() = 0; - - virtual void process(PostProcessor& dest, ProcessContext& context) = 0; - -protected: - size_t _capacity; -}; - - -} // namespace Ingen - -#endif // EVENTSOURCE_H - diff --git a/src/libs/engine/GraphObjectImpl.cpp b/src/libs/engine/GraphObjectImpl.cpp deleted file mode 100644 index 0e1abc57..00000000 --- a/src/libs/engine/GraphObjectImpl.cpp +++ /dev/null @@ -1,39 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard <http://drobilla.net> - * - * 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 "GraphObjectImpl.hpp" -#include "PatchImpl.hpp" -#include "EngineStore.hpp" - -namespace Ingen { - - -PatchImpl* -GraphObjectImpl::parent_patch() const -{ - return dynamic_cast<PatchImpl*>((NodeImpl*)_parent); -} - - -SharedPtr<GraphObject> -GraphObjectImpl::find_child(const string& name) const -{ - throw; -} - - -} // namespace Ingen diff --git a/src/libs/engine/GraphObjectImpl.hpp b/src/libs/engine/GraphObjectImpl.hpp deleted file mode 100644 index 9b1f675d..00000000 --- a/src/libs/engine/GraphObjectImpl.hpp +++ /dev/null @@ -1,132 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard <http://drobilla.net> - * - * 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 GRAPHOBJECTIMPL_H -#define GRAPHOBJECTIMPL_H - -#include <string> -#include <map> -#include <cstddef> -#include <cassert> -#include <raul/Deletable.hpp> -#include <raul/Path.hpp> -#include <raul/Atom.hpp> -#include "interface/GraphObject.hpp" -#include "types.hpp" - -using Raul::Atom; -using Raul::Path; -using Raul::Symbol; - -namespace Raul { class Maid; } - -namespace Ingen { - -class PatchImpl; -class ProcessContext; - - -/** An object on the audio graph - Patch, Node, Port, etc. - * - * Each of these is a Raul::Deletable and so can be deleted in a realtime safe - * way from anywhere, and they all have a map of variable for clients to store - * arbitrary values in (which the engine puts no significance to whatsoever). - * - * \ingroup engine - */ -class GraphObjectImpl : virtual public Ingen::Shared::GraphObject -{ -public: - virtual ~GraphObjectImpl() {} - - bool polyphonic() const { return _polyphonic; } - virtual bool set_polyphonic(Raul::Maid& maid, bool p) { _polyphonic = p; return true; } - - GraphObject* graph_parent() const { return _parent; } - - inline GraphObjectImpl* parent() const { return _parent; } - const Symbol symbol() const { return _name; } - - virtual void process(ProcessContext& context) = 0; - - /** Rename */ - virtual void set_path(const Path& new_path) { - assert(new_path.parent() == path().parent()); - _name = new_path.name(); - assert(_name.find("/") == std::string::npos); - } - - void set_variable(const std::string& key, const Atom& value) - { _variables[key] = value; } - - void set_property(const std::string& key, const Atom& value) - { _properties[key] = value; } - - const Atom& get_variable(const std::string& key) { - static Atom null_atom; - Variables::iterator i = _variables.find(key); - return (i != _variables.end()) ? (*i).second : null_atom; - } - - const Atom& get_property(const std::string& key) { - static Atom null_atom; - Properties::iterator i = _properties.find(key); - return (i != _properties.end()) ? (*i).second : null_atom; - } - - const Variables& variables() const { return _variables; } - const Properties& properties() const { return _properties; } - Variables& variables() { return _variables; } - Properties& properties() { return _properties; } - - /** The Patch this object is a child of. */ - virtual PatchImpl* parent_patch() const; - - /** Path is dynamically generated from parent to ease renaming */ - const Path path() const { - if (_parent == NULL) - return Path(std::string("/").append(_name)); - else if (_parent->path() == "/") - return Path(std::string("/").append(_name)); - else - return Path(_parent->path() +"/"+ _name); - } - - SharedPtr<GraphObject> find_child(const std::string& name) const; - -protected: - GraphObjectImpl(GraphObjectImpl* parent, const std::string& name, bool polyphonic=false) - : _parent(parent), _name(name), _polyphonic(polyphonic) - { - assert(parent == NULL || _name.length() > 0); - assert(_name.find("/") == std::string::npos); - assert(path().find("//") == std::string::npos); - } - - GraphObjectImpl* _parent; - std::string _name; - bool _polyphonic; - -private: - Variables _variables; - Properties _properties; -}; - - -} // namespace Ingen - -#endif // GRAPHOBJECTIMPL_H diff --git a/src/libs/engine/HTTPEngineReceiver.cpp b/src/libs/engine/HTTPEngineReceiver.cpp deleted file mode 100644 index 1b21e184..00000000 --- a/src/libs/engine/HTTPEngineReceiver.cpp +++ /dev/null @@ -1,207 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard <http://drobilla.net> - * - * 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 <iostream> -#include <cstdlib> -#include <cstdio> -#include <string> -#include <boost/format.hpp> -#include "types.hpp" -#include <raul/SharedPtr.hpp> -#include <raul/AtomLiblo.hpp> -#include "interface/ClientInterface.hpp" -#include "module/Module.hpp" -#include "serialisation/serialisation.hpp" -#include "serialisation/Serialiser.hpp" -#include "serialisation/Parser.hpp" -#include "engine/ThreadManager.hpp" -#include "HTTPEngineReceiver.hpp" -#include "QueuedEventSource.hpp" -#include "ClientBroadcaster.hpp" -#include "EngineStore.hpp" - -using namespace std; -using namespace Ingen::Shared; - -namespace Ingen { - - -HTTPEngineReceiver::HTTPEngineReceiver(Engine& engine, uint16_t port) - : QueuedEngineInterface(engine, 2, 2) - , _server(soup_server_new(SOUP_SERVER_PORT, port, NULL)) -{ - _receive_thread = new ReceiveThread(*this); - - soup_server_add_handler(_server, NULL, message_callback, this, NULL); - - cout << "Started HTTP server on port " << soup_server_get_port(_server) << endl; - Thread::set_name("HTTP receiver"); - - if (!engine.world()->serialisation_module) - engine.world()->serialisation_module = Ingen::Shared::load_module("ingen_serialisation"); - - if (engine.world()->serialisation_module) { - if (!engine.world()->serialiser) - engine.world()->serialiser = SharedPtr<Serialiser>( - Ingen::Serialisation::new_serialiser(engine.world(), engine.engine_store())); - - if (!engine.world()->parser) - engine.world()->parser = SharedPtr<Parser>( - Ingen::Serialisation::new_parser()); - } else { - cerr << "WARNING: Failed to load ingen_serialisation module, HTTP disabled." << endl; - } -} - - -HTTPEngineReceiver::~HTTPEngineReceiver() -{ - deactivate(); - - if (_server != NULL) { - soup_server_quit(_server); - _server = NULL; - } -} - - -void -HTTPEngineReceiver::activate() -{ - QueuedEventSource::activate(); - _receive_thread->set_name("HTTP Receiver"); - _receive_thread->start(); -} - - -void -HTTPEngineReceiver::deactivate() -{ - cout << "[HTTPEngineReceiver] Stopped HTTP listening thread" << endl; - _receive_thread->stop(); - QueuedEventSource::deactivate(); -} - - -void -HTTPEngineReceiver::message_callback(SoupServer* server, SoupMessage* msg, const char* path, - GHashTable *query, SoupClientContext* client, void* data) -{ - HTTPEngineReceiver* me = (HTTPEngineReceiver*)data; - - SharedPtr<Store> store = me->_engine.world()->store; - if (!store) { - soup_message_set_status (msg, SOUP_STATUS_INTERNAL_SERVER_ERROR); - return; - } - - if (!Path::is_valid(path)) { - soup_message_set_status (msg, SOUP_STATUS_BAD_REQUEST); - const string& err = (boost::format("Bad path: %1%") % path).str(); - soup_message_set_response (msg, "text/plain", SOUP_MEMORY_COPY, - err.c_str(), err.length()); - return; - } - - if (msg->method == SOUP_METHOD_GET) { - Glib::RWLock::ReaderLock lock(store->lock()); - - // Find object - Store::const_iterator start = store->find(path); - if (start == store->end()) { - soup_message_set_status (msg, SOUP_STATUS_NOT_FOUND); - const string& err = (boost::format("No such object: %1%") % path).str(); - soup_message_set_response (msg, "text/plain", SOUP_MEMORY_COPY, - err.c_str(), err.length()); - return; - } - - // Get serialiser - SharedPtr<Serialiser> serialiser = me->_engine.world()->serialiser; - if (!serialiser) { - soup_message_set_status (msg, SOUP_STATUS_INTERNAL_SERVER_ERROR); - soup_message_set_response (msg, "text/plain", SOUP_MEMORY_STATIC, - "No serialiser available\n", 24); - return; - } - -#if 0 - SoupMessageHeaders* in_head = msg->request_headers; - const char* str = soup_message_headers_get(in_head, "Accept"); - cout << "Accept: " << str << endl; -#endif - - // Serialise object - const string response = serialiser->to_string(start->second, - "http://example.org", GraphObject::Variables()); - -#if 0 - FILE* xhtml_file = fopen("/home/dave/ingen_ui.xhtml", "r"); - string response; - while (!feof(xhtml_file)) { - int c = fgetc(xhtml_file); - if (c != EOF) - response += (char)c; - } - fclose(xhtml_file); -#endif - - soup_message_set_status (msg, SOUP_STATUS_OK); - soup_message_set_response (msg, "text/plain", SOUP_MEMORY_COPY, - response.c_str(), response.length()); - - } else if (msg->method == SOUP_METHOD_PUT) { - Glib::RWLock::WriterLock lock(store->lock()); - - // Be sure object doesn't exist - Store::const_iterator start = store->find(path); - if (start != store->end()) { - soup_message_set_status (msg, SOUP_STATUS_CONFLICT); - return; - } - - // Get parser - SharedPtr<Parser> parser = me->_engine.world()->parser; - if (!parser) { - soup_message_set_status (msg, SOUP_STATUS_INTERNAL_SERVER_ERROR); - return; - } - - //cout << "POST: " << msg->request_body->data << endl; - - // Load object - soup_message_set_status (msg, SOUP_STATUS_NOT_IMPLEMENTED); - } else if (msg->method == SOUP_METHOD_POST) { - //cout << "PUT: " << msg->request_body->data << endl; - soup_message_set_status (msg, SOUP_STATUS_NOT_IMPLEMENTED); - } else { - soup_message_set_status (msg, SOUP_STATUS_NOT_IMPLEMENTED); - } -} - - -/** Override the semaphore driven _run method of QueuedEngineInterface - * to wait on HTTP requests and process them immediately in this thread. - */ -void -HTTPEngineReceiver::ReceiveThread::_run() -{ - soup_server_run(_receiver._server); -} - - -} // namespace Ingen diff --git a/src/libs/engine/HTTPEngineReceiver.hpp b/src/libs/engine/HTTPEngineReceiver.hpp deleted file mode 100644 index 34c425b2..00000000 --- a/src/libs/engine/HTTPEngineReceiver.hpp +++ /dev/null @@ -1,59 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2008 Dave Robillard <http://drobilla.net> - * - * 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 HTTPENGINERECEIVER_H -#define HTTPENGINERECEIVER_H - -#include CONFIG_H_PATH -#include <string> -#include <stdint.h> -#include <libsoup/soup.h> -#include <raul/SharedPtr.hpp> -#include "QueuedEngineInterface.hpp" - -namespace Ingen { - -class HTTPEngineReceiver : public QueuedEngineInterface -{ -public: - HTTPEngineReceiver(Engine& engine, uint16_t port); - ~HTTPEngineReceiver(); - - void activate(); - void deactivate(); - -private: - struct ReceiveThread : public Raul::Thread { - ReceiveThread(HTTPEngineReceiver& receiver) : _receiver(receiver) {} - virtual void _run(); - private: - HTTPEngineReceiver& _receiver; - }; - - friend class ReceiveThread; - - static void message_callback(SoupServer* server, SoupMessage* msg, const char* path, - GHashTable *query, SoupClientContext* client, void* data); - - ReceiveThread* _receive_thread; - SoupServer* _server; -}; - - -} // namespace Ingen - -#endif // HTTPENGINERECEIVER_H diff --git a/src/libs/engine/InputPort.cpp b/src/libs/engine/InputPort.cpp deleted file mode 100644 index cf5501ca..00000000 --- a/src/libs/engine/InputPort.cpp +++ /dev/null @@ -1,297 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard <http://drobilla.net> - * - * 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 "InputPort.hpp" -#include <iostream> -#include <cstdlib> -#include <cassert> -#include "AudioBuffer.hpp" -#include "EventBuffer.hpp" -#include "ConnectionImpl.hpp" -#include "OutputPort.hpp" -#include "NodeImpl.hpp" -#include "ProcessContext.hpp" -#include "util.hpp" - -using namespace std; - -namespace Ingen { - - -InputPort::InputPort(NodeImpl* parent, - const string& name, - uint32_t index, - uint32_t poly, - DataType type, - const Atom& value, - size_t buffer_size) - : PortImpl(parent, name, index, poly, type, value, buffer_size) -{ -} - - -void -InputPort::set_buffer_size(size_t size) -{ - PortImpl::set_buffer_size(size); - assert(_buffer_size = size); - - for (Connections::iterator c = _connections.begin(); c != _connections.end(); ++c) - ((ConnectionImpl*)c->get())->set_buffer_size(size); - -} - - -bool -InputPort::prepare_poly(uint32_t poly) -{ - PortImpl::prepare_poly(poly); - - for (Connections::iterator c = _connections.begin(); c != _connections.end(); ++c) - ((ConnectionImpl*)c->get())->prepare_poly(poly); - - connect_buffers(); - return true; -} - - -bool -InputPort::apply_poly(Raul::Maid& maid, uint32_t poly) -{ - if (!_polyphonic || !_parent->polyphonic()) - return true; - - for (Connections::iterator c = _connections.begin(); c != _connections.end(); ++c) - ((ConnectionImpl*)c->get())->apply_poly(maid, poly); - - PortImpl::apply_poly(maid, poly); - assert(this->poly() == poly); - - if (_connections.size() == 1) { - ConnectionImpl* c = _connections.begin()->get(); - for (uint32_t i=0; i < _poly; ++i) - _buffers->at(i)->join(c->buffer(i)); - } - - connect_buffers(); - - return true; -} - - -/** Add a connection. Realtime safe. - * - * The buffer of this port will be set directly to the connection's buffer - * if there is only one connection, since no mixing needs to take place. - */ -void -InputPort::add_connection(Connections::Node* const c) -{ - _connections.push_back(c); - - bool modify_buffers = !_fixed_buffers; - - if (modify_buffers) { - if (_connections.size() == 1) { - // Use buffer directly to avoid copying - for (uint32_t i=0; i < _poly; ++i) { - _buffers->at(i)->join(c->elem()->buffer(i)); - } - } else if (_connections.size() == 2) { - // Used to directly use single connection buffer, now there's two - // so have to use local ones again and mix down - for (uint32_t i=0; i < _poly; ++i) { - _buffers->at(i)->unjoin(); - } - } - PortImpl::connect_buffers(); - } - - // Automatically broadcast connected control inputs - if (_type == DataType::CONTROL) - _broadcast = true; -} - - -/** Remove a connection. Realtime safe. - */ -InputPort::Connections::Node* -InputPort::remove_connection(const OutputPort* src_port) -{ - bool modify_buffers = !_fixed_buffers; - - bool found = false; - Connections::Node* connection = NULL; - for (Connections::iterator i = _connections.begin(); i != _connections.end(); ++i) { - if ((*i)->src_port()->path() == src_port->path()) { - connection = _connections.erase(i); - found = true; - } - } - - if ( ! found) { - cerr << "WARNING: [InputPort::remove_connection] Connection not found !" << endl; - exit(EXIT_FAILURE); - } else { - if (_connections.size() == 0) { - for (uint32_t i=0; i < _poly; ++i) { - // Use a local buffer - if (modify_buffers) - _buffers->at(i)->unjoin(); - _buffers->at(i)->clear(); // Write silence - } - } else if (modify_buffers && _connections.size() == 1) { - // Share a buffer - for (uint32_t i=0; i < _poly; ++i) { - _buffers->at(i)->join((*_connections.begin())->buffer(i)); - } - } - } - - if (modify_buffers) - PortImpl::connect_buffers(); - - // Turn off broadcasting if we're not connected any more (FIXME: not quite right..) - if (_type == DataType::CONTROL && _connections.size() == 0) - _broadcast = false; - - return connection; -} - - -/** Returns whether this port is connected to the passed port. - */ -/*bool -InputPort::is_connected_to(const OutputPort* port) const -{ - for (Connections::const_iterator i = _connections.begin(); i != _connections.end(); ++i) - if ((*i)->src_port() == port) - return true; - - return false; -}*/ - - -/** Prepare buffer for access, mixing if necessary. Realtime safe. - * FIXME: nframes parameter not used, - */ -void -InputPort::pre_process(ProcessContext& context) -{ - // If value has been set (e.g. events pushed) by the user, - // don't do anything this cycle to avoid smashing the value - if (_set_by_user) - return; - - bool do_mixdown = true; - - if (_connections.size() == 0) { - for (uint32_t i=0; i < _poly; ++i) - buffer(i)->prepare_read(context.start(), context.nframes()); - return; - } - - for (Connections::iterator c = _connections.begin(); c != _connections.end(); ++c) - (*c)->process(context); - - if ( ! _fixed_buffers) { - // If only one connection, try to use buffer directly (zero copy) - if (_connections.size() == 1) { - for (uint32_t i=0; i < _poly; ++i) { - //cerr << path() << " joining to " << (*_connections.begin())->buffer(i) << endl; - _buffers->at(i)->join((*_connections.begin())->buffer(i)); - } - do_mixdown = false; - } - connect_buffers(); - } else { - do_mixdown = true; - } - - for (uint32_t i=0; i < _poly; ++i) - buffer(i)->prepare_read(context.start(), context.nframes()); - - /*cerr << path() << " poly = " << _poly << ", mixdown: " << do_mixdown - << ", fixed buffers: " << _fixed_buffers << ", joined: " << _buffers->at(0)->is_joined() - << " to " << _buffers->at(0)->joined_buffer() << endl;*/ - - /*if (type() == DataType::EVENT) - for (uint32_t i=0; i < _poly; ++i) - cerr << path() << " (" << buffer(i) << ") # events: " - << ((EventBuffer*)buffer(i))->event_count() - << ", joined: " << _buffers->at(i)->is_joined() << endl;*/ - - if (!do_mixdown) { - /*#ifndef NDEBUG - for (uint32_t i=0; i < _poly; ++i) - assert(buffer(i) == (*_connections.begin())->buffer(i)); - #endif*/ - return; - } - - if (_type == DataType::CONTROL || _type == DataType::AUDIO) { - for (uint32_t voice=0; voice < _poly; ++voice) { - // Copy first connection - buffer(voice)->copy( - (*_connections.begin())->buffer(voice), 0, _buffer_size-1); - - // Accumulate the rest - if (_connections.size() > 1) { - - Connections::iterator c = _connections.begin(); - - for (++c; c != _connections.end(); ++c) - ((AudioBuffer*)buffer(voice))->accumulate( - ((AudioBuffer*)(*c)->buffer(voice)), 0, _buffer_size-1); - } - } - } else { - assert(_poly == 1); - - // FIXME - if (_connections.size() > 1) - cerr << "WARNING: MIDI mixing not implemented, only first connection used." << endl; - - // Copy first connection - _buffers->at(0)->copy( - (*_connections.begin())->buffer(0), 0, _buffer_size-1); - } -} - - -void -InputPort::post_process(ProcessContext& context) -{ - broadcast(context); - - // Prepare for next cycle - for (uint32_t i=0; i < _poly; ++i) - buffer(i)->prepare_write(context.start(), context.nframes()); - - _set_by_user = false; - - /*if (_broadcast && (_type == DataType::CONTROL)) { - const Sample value = ((AudioBuffer*)(*_buffers)[0])->value_at(0); - - cerr << path() << " input post: buffer: " << buffer(0) << " value = " - << value << " (last " << _last_broadcasted_value << ")" <<endl; - }*/ -} - - -} // namespace Ingen - diff --git a/src/libs/engine/InputPort.hpp b/src/libs/engine/InputPort.hpp deleted file mode 100644 index 2617882f..00000000 --- a/src/libs/engine/InputPort.hpp +++ /dev/null @@ -1,88 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard <http://drobilla.net> - * - * 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 INPUTPORT_H -#define INPUTPORT_H - -#include <string> -#include <cstdlib> -#include <cassert> -#include <raul/List.hpp> -#include <raul/SharedPtr.hpp> -#include "PortImpl.hpp" -using std::string; - -namespace Ingen { - -class ConnectionImpl; -class OutputPort; -class NodeImpl; - - -/** An input port on a Node or Patch. - * - * All ports have a Buffer, but the actual contents (data) of that buffer may be - * set directly to the incoming connection's buffer if there's only one inbound - * connection, to eliminate the need to copy/mix. - * - * If a port has multiple connections, they will be mixed down into the local - * buffer and it will be used. - * - * \ingroup engine - */ -class InputPort : virtual public PortImpl -{ -public: - InputPort(NodeImpl* parent, - const string& name, - uint32_t index, - uint32_t poly, - DataType type, - const Atom& value, - size_t buffer_size); - - virtual ~InputPort() {} - - typedef Raul::List< SharedPtr<ConnectionImpl> > Connections; - - void add_connection(Connections::Node* c); - Connections::Node* remove_connection(const OutputPort* src_port); - - const Connections& connections() { return _connections; } - - bool prepare_poly(uint32_t poly); - bool apply_poly(Raul::Maid& maid, uint32_t poly); - - void pre_process(ProcessContext& context); - void post_process(ProcessContext& context); - - bool is_connected() const { return (_connections.size() > 0); } - //bool is_connected_to(const OutputPort* port) const; - - bool is_input() const { return true; } - bool is_output() const { return false; } - - virtual void set_buffer_size(size_t size); - -private: - Connections _connections; -}; - - -} // namespace Ingen - -#endif // INPUTPORT_H diff --git a/src/libs/engine/InternalPlugin.cpp b/src/libs/engine/InternalPlugin.cpp deleted file mode 100644 index 1c6a92a5..00000000 --- a/src/libs/engine/InternalPlugin.cpp +++ /dev/null @@ -1,55 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard <http://drobilla.net> - * - * 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 <cassert> -#include "InternalPlugin.hpp" -#include "MidiNoteNode.hpp" -#include "MidiTriggerNode.hpp" -#include "MidiControlNode.hpp" -#include "TransportNode.hpp" -#include "Engine.hpp" -#include "AudioDriver.hpp" - -namespace Ingen { - - -NodeImpl* -InternalPlugin::instantiate(const string& name, - bool polyphonic, - Ingen::PatchImpl* parent, - Engine& engine) -{ - assert(_type == Internal); - - SampleCount srate = engine.audio_driver()->sample_rate(); - SampleCount buffer_size = engine.audio_driver()->buffer_size(); - - if (_uri == NS_INGEN "note_node") { - return new MidiNoteNode(name, polyphonic, parent, srate, buffer_size); - } else if (_uri == NS_INGEN "trigger_node") { - return new MidiTriggerNode(name, polyphonic, parent, srate, buffer_size); - } else if (_uri == NS_INGEN "control_node") { - return new MidiControlNode(name, polyphonic, parent, srate, buffer_size); - } else if (_uri == NS_INGEN "transport_node") { - return new TransportNode(name, polyphonic, parent, srate, buffer_size); - } else { - return NULL; - } -} - - -} // namespace Ingen diff --git a/src/libs/engine/InternalPlugin.hpp b/src/libs/engine/InternalPlugin.hpp deleted file mode 100644 index c04c9015..00000000 --- a/src/libs/engine/InternalPlugin.hpp +++ /dev/null @@ -1,74 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard <http://drobilla.net> - * - * 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 INTERNALPLUGIN_H -#define INTERNALPLUGIN_H - -#include CONFIG_H_PATH - -#ifndef HAVE_SLV2 -#error "This file requires SLV2, but HAVE_SLV2 is not defined. Please report." -#endif - -#include <cstdlib> -#include <glibmm/module.h> -#include <boost/utility.hpp> -#include <dlfcn.h> -#include <string> -#include <iostream> -#include <slv2/slv2.h> -#include "types.hpp" -#include "PluginImpl.hpp" - -#define NS_INGEN "http://drobilla.net/ns/ingen#" - -namespace Ingen { - -class NodeImpl; - - -/** Implementation of an Internal plugin. - */ -class InternalPlugin : public PluginImpl -{ -public: - InternalPlugin(const std::string& uri, - const std::string& symbol, - const std::string& name) - : PluginImpl(Plugin::Internal, uri) - , _symbol(symbol) - , _name(name) - {} - - NodeImpl* instantiate(const std::string& name, - bool polyphonic, - Ingen::PatchImpl* parent, - Engine& engine); - - const string symbol() const { return _symbol; } - const string name() const { return _name; } - -private: - const string _symbol; - const string _name; -}; - - -} // namespace Ingen - -#endif // INTERNALPLUGIN_H - diff --git a/src/libs/engine/JackAudioDriver.cpp b/src/libs/engine/JackAudioDriver.cpp deleted file mode 100644 index eff04653..00000000 --- a/src/libs/engine/JackAudioDriver.cpp +++ /dev/null @@ -1,384 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard <http://drobilla.net> - * - * 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 "JackAudioDriver.hpp" -#include CONFIG_H_PATH -#include "tuning.hpp" -#include <iostream> -#include <cstdlib> -#include <raul/List.hpp> -#include "Engine.hpp" -#include "util.hpp" -#include "Event.hpp" -#include "ThreadManager.hpp" -#include "QueuedEvent.hpp" -#include "EventSource.hpp" -#include "PostProcessor.hpp" -#include "NodeImpl.hpp" -#include "PatchImpl.hpp" -#include "PortImpl.hpp" -#include "MidiDriver.hpp" -#include "DuplexPort.hpp" -#include "EventSource.hpp" -#include "AudioBuffer.hpp" -#include "ProcessSlave.hpp" - -using namespace std; - -namespace Ingen { - - -//// JackAudioPort //// - -JackAudioPort::JackAudioPort(JackAudioDriver* driver, DuplexPort* patch_port) - : DriverPort(patch_port) - , Raul::List<JackAudioPort*>::Node(this) - , _driver(driver) - , _jack_port(NULL) - , _jack_buffer(NULL) -{ - assert(patch_port->poly() == 1); - - _jack_port = jack_port_register(_driver->jack_client(), - patch_port->path().c_str(), JACK_DEFAULT_AUDIO_TYPE, - (patch_port->is_input()) ? JackPortIsInput : JackPortIsOutput, - 0); - - if (_jack_port == NULL) { - cerr << "[JackAudioPort] ERROR: Failed to register port " << patch_port->path() << endl; - throw JackAudioDriver::PortRegistrationFailedException(); - } - - patch_port->buffer(0)->clear(); - patch_port->fixed_buffers(true); -} - - -JackAudioPort::~JackAudioPort() -{ - jack_port_unregister(_driver->jack_client(), _jack_port); -} - - -void -JackAudioPort::prepare_buffer(jack_nframes_t nframes) -{ - jack_sample_t* jack_buf = (jack_sample_t*)jack_port_get_buffer(_jack_port, nframes); - - AudioBuffer* patch_buf = (AudioBuffer*)_patch_port->buffer(0); - - //cerr << "[JACK] " << _patch_port->path() << " buffer: " << patch_buf << endl; - - if (jack_buf != _jack_buffer) { - patch_buf->set_data(jack_buf); - _jack_buffer = jack_buf; - } - - assert(patch_buf->data() == jack_buf); -} - - -//// JackAudioDriver //// - -JackAudioDriver::JackAudioDriver(Engine& engine, - std::string server_name, - jack_client_t* jack_client) - : _engine(engine) - , _jack_thread(NULL) - , _client(jack_client) - , _buffer_size(jack_client ? jack_get_buffer_size(jack_client) : 0) - , _sample_rate(jack_client ? jack_get_sample_rate(jack_client) : 0) - , _is_activated(false) - , _local_client(true) // FIXME - , _process_context(engine) - , _root_patch(NULL) -{ - if (!_client) { - // 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); - } - - jack_on_shutdown(_client, shutdown_cb, this); - - jack_set_thread_init_callback(_client, thread_init_cb, this); - jack_set_sample_rate_callback(_client, sample_rate_cb, this); - jack_set_buffer_size_callback(_client, buffer_size_cb, this); -} - - -JackAudioDriver::~JackAudioDriver() -{ - deactivate(); - - if (_local_client) - jack_client_close(_client); -} - - -void -JackAudioDriver::activate() -{ - if (_is_activated) { - cerr << "[JackAudioDriver] Jack driver already activated." << endl; - return; - } - - jack_set_process_callback(_client, process_cb, this); - - _is_activated = true; - - if (jack_activate(_client)) { - cerr << "[JackAudioDriver] Could not activate Jack client, aborting." << endl; - exit(EXIT_FAILURE); - } else { - cout << "[JackAudioDriver] Activated Jack client." << endl; -/*#ifdef HAVE_LASH - _engine.lash_driver()->set_jack_client_name(jack_client_get_name(_client)); -#endif*/ - } -} - - -void -JackAudioDriver::deactivate() -{ - if (_is_activated) { - - //for (Raul::List<JackAudioPort*>::iterator i = _ports.begin(); i != _ports.end(); ++i) - // jack_port_unregister(_client, (*i)->jack_port()); - - jack_deactivate(_client); - _is_activated = false; - - _ports.clear(); - - cout << "[JackAudioDriver] Deactivated Jack client." << endl; - - //_engine.post_processor()->stop(); - } -} - - -/** Add a Jack port. - * - * Realtime safe, this is to be called at the beginning of a process cycle to - * insert (and actually begin using) a new port. - * - * See create_port() and remove_port(). - */ -void -JackAudioDriver::add_port(DriverPort* port) -{ - assert(ThreadManager::current_thread_id() == THREAD_PROCESS); - - assert(dynamic_cast<JackAudioPort*>(port)); - _ports.push_back((JackAudioPort*)port); -} - - -/** Remove a Jack port. - * - * Realtime safe. This is to be called at the beginning of a process cycle to - * remove the port from the lists read by the audio thread, so the port - * will no longer be used and can be removed afterwards. - * - * It is the callers responsibility to delete the returned port. - */ -DriverPort* -JackAudioDriver::remove_port(const Path& path) -{ - assert(ThreadManager::current_thread_id() == THREAD_PROCESS); - - for (Raul::List<JackAudioPort*>::iterator i = _ports.begin(); i != _ports.end(); ++i) - if ((*i)->patch_port()->path() == path) - return _ports.erase(i)->elem(); // FIXME: LEAK - - cerr << "[JackAudioDriver::remove_port] WARNING: Unable to find Jack port " << path << endl; - return NULL; -} - - -DriverPort* -JackAudioDriver::port(const Path& path) -{ - for (Raul::List<JackAudioPort*>::iterator i = _ports.begin(); i != _ports.end(); ++i) - if ((*i)->patch_port()->path() == path) - return (*i); - - return NULL; -} - - -DriverPort* -JackAudioDriver::create_port(DuplexPort* patch_port) -{ - try { - if (patch_port->buffer_size() == _buffer_size) - return new JackAudioPort(this, patch_port); - else - return NULL; - } catch (...) { - return NULL; - } -} - - -DriverPort* -JackAudioDriver::driver_port(const Path& path) -{ - assert(ThreadManager::current_thread_id() == THREAD_PROCESS); - - for (Raul::List<JackAudioPort*>::iterator i = _ports.begin(); i != _ports.end(); ++i) - if ((*i)->patch_port()->path() == path) - return (*i); - - return NULL; -} - - -/**** Jack Callbacks ****/ - - - -/** Jack process callback, drives entire audio thread. - * - * \callgraph - */ -int -JackAudioDriver::_process_cb(jack_nframes_t nframes) -{ - if (nframes == 0 || ! _is_activated) - return 0; - - // FIXME: all of this time stuff is screwy - - // FIXME: support nframes != buffer_size, even though that never damn well happens - assert(nframes == _buffer_size); - - // Jack can elect to not call this function for a cycle, if overloaded - // FIXME: this doesn't make sense, and the start time isn't used anyway - const jack_nframes_t start_of_current_cycle = jack_last_frame_time(_client); - - const jack_nframes_t end_of_current_cycle = start_of_current_cycle + nframes; -#ifndef NDEBUG - // FIXME: support changing cycle length - const jack_nframes_t start_of_last_cycle = start_of_current_cycle - nframes; - assert(start_of_current_cycle - start_of_last_cycle == nframes); -#endif - - _transport_state = jack_transport_query(_client, &_position); - - _process_context.set_time_slice(nframes, start_of_current_cycle, end_of_current_cycle); - - for (Engine::ProcessSlaves::iterator i = _engine.process_slaves().begin(); - i != _engine.process_slaves().end(); ++i) { - (*i)->context().set_time_slice(nframes, start_of_current_cycle, end_of_current_cycle); - } - - // Process events that came in during the last cycle - // (Aiming for jitter-free 1 block event latency, ideally) - _engine.process_events(_process_context); - - // Set buffers of patch ports to Jack port buffers (zero-copy processing) - for (Raul::List<JackAudioPort*>::iterator i = _ports.begin(); i != _ports.end(); ++i) { - assert(*i); - (*i)->prepare_buffer(nframes); - } - - assert(_engine.midi_driver()); - _engine.midi_driver()->pre_process(_process_context); - - // Run root patch - if (_root_patch) - _root_patch->process(_process_context); - - _engine.midi_driver()->post_process(_process_context); - - _engine.post_processor()->set_end_time(_process_context.end()); - - return 0; -} - - -void -JackAudioDriver::_thread_init_cb() -{ - // Initialize thread specific data - _jack_thread = Thread::create_for_this_thread("Jack"); - assert(&Thread::get() == _jack_thread); - _jack_thread->set_context(THREAD_PROCESS); - assert(ThreadManager::current_thread_id() == THREAD_PROCESS); -} - -void -JackAudioDriver::_shutdown_cb() -{ - cout << "[JackAudioDriver] Jack shutdown. Exiting." << endl; - _engine.quit(); - _jack_thread = NULL; -} - - -int -JackAudioDriver::_sample_rate_cb(jack_nframes_t nframes) -{ - if (_is_activated) { - cerr << "[JackAudioDriver] On-the-fly sample rate changing not supported (yet). Aborting." << endl; - exit(EXIT_FAILURE); - } else { - _sample_rate = nframes; - } - return 0; -} - - -int -JackAudioDriver::_buffer_size_cb(jack_nframes_t nframes) -{ - if (_root_patch) { - _root_patch->set_buffer_size(nframes); - _buffer_size = nframes; - } - return 0; -} - - -} // namespace Ingen - diff --git a/src/libs/engine/JackAudioDriver.hpp b/src/libs/engine/JackAudioDriver.hpp deleted file mode 100644 index 3beb775a..00000000 --- a/src/libs/engine/JackAudioDriver.hpp +++ /dev/null @@ -1,185 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard <http://drobilla.net> - * - * 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 JACKAUDIODRIVER_H -#define JACKAUDIODRIVER_H - -#include <jack/jack.h> -#include <jack/transport.h> -#include <raul/Thread.hpp> -#include <raul/Path.hpp> -#include <raul/List.hpp> -#include "AudioDriver.hpp" -#include "Buffer.hpp" -#include "ProcessContext.hpp" - -namespace Ingen { - -class Engine; -class PatchImpl; -class PortImpl; -class DuplexPort; -class JackAudioDriver; -typedef jack_default_audio_sample_t jack_sample_t; - - -/** Used internally by JackAudioDriver to represent a Jack port. - * - * A Jack port always has a one-to-one association with a Patch port. - */ -class JackAudioPort : public DriverPort, public Raul::List<JackAudioPort*>::Node -{ -public: - JackAudioPort(JackAudioDriver* driver, DuplexPort* patch_port); - ~JackAudioPort(); - - void set_name(const std::string& name) { jack_port_set_name(_jack_port, name.c_str()); }; - - void prepare_buffer(jack_nframes_t nframes); - - jack_port_t* jack_port() const { return _jack_port; } - -private: - JackAudioDriver* _driver; - jack_port_t* _jack_port; - jack_sample_t* _jack_buffer; ///< Cached for output ports -}; - - - -/** The Jack AudioDriver. - * - * The process callback here drives the entire audio thread by "pulling" - * events from queues, processing them, running the patches, and passing - * events along to the PostProcessor. - * - * \ingroup engine - */ -class JackAudioDriver : public AudioDriver -{ -public: - JackAudioDriver(Engine& engine, - std::string server_name = "", - jack_client_t* jack_client = 0); - - ~JackAudioDriver(); - - void activate(); - void deactivate(); - void enable(); - void disable(); - - DriverPort* port(const Raul::Path& path); - DriverPort* create_port(DuplexPort* patch_port); - - void add_port(DriverPort* port); - DriverPort* remove_port(const Raul::Path& path); - - DriverPort* driver_port(const Raul::Path& path); - - PatchImpl* root_patch() { return _root_patch; } - void set_root_patch(PatchImpl* patch) { _root_patch = patch; } - - ProcessContext& context() { return _process_context; } - - /** Transport state for this frame. - * Intended to only be called from the audio thread. */ - inline const jack_position_t* position() { return &_position; } - inline jack_transport_state_t transport_state() { return _transport_state; } - - bool is_realtime() const { return jack_is_realtime(_client); } - - jack_client_t* jack_client() const { return _client; } - SampleCount buffer_size() const { return _buffer_size; } - SampleCount sample_rate() const { return _sample_rate; } - bool is_activated() const { return _is_activated; } - - inline SampleCount frame_time() const { return jack_frame_time(_client); } - - class PortRegistrationFailedException : public std::exception {}; - -private: - friend class JackAudioPort; - - // These are the static versions of the callbacks, they call - // the non-static ones below - inline static void thread_init_cb(void* const jack_driver); - inline static void shutdown_cb(void* const jack_driver); - inline static int process_cb(jack_nframes_t nframes, void* const jack_driver); - inline static int buffer_size_cb(jack_nframes_t nframes, void* const jack_driver); - inline static int sample_rate_cb(jack_nframes_t nframes, void* const jack_driver); - - // Non static callbacks - void _thread_init_cb(); - void _shutdown_cb(); - int _process_cb(jack_nframes_t nframes); - int _buffer_size_cb(jack_nframes_t nframes); - int _sample_rate_cb(jack_nframes_t nframes); - - Engine& _engine; - Raul::Thread* _jack_thread; - jack_client_t* _client; - jack_nframes_t _buffer_size; - jack_nframes_t _sample_rate; - bool _is_activated; - bool _local_client; ///< Whether _client should be closed on destruction - jack_position_t _position; - jack_transport_state_t _transport_state; - - Raul::List<JackAudioPort*> _ports; - ProcessContext _process_context; - - PatchImpl* _root_patch; -}; - - -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::thread_init_cb(void* jack_driver) -{ - assert(jack_driver); - return ((JackAudioDriver*)jack_driver)->_thread_init_cb(); -} - -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); -} - - -} // namespace Ingen - -#endif // JACKAUDIODRIVER_H diff --git a/src/libs/engine/JackMidiDriver.cpp b/src/libs/engine/JackMidiDriver.cpp deleted file mode 100644 index 9e236541..00000000 --- a/src/libs/engine/JackMidiDriver.cpp +++ /dev/null @@ -1,267 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard <http://drobilla.net> - * - * 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 <iostream> -#include <cstdlib> -#include <pthread.h> -#include <raul/Maid.hpp> -#include <raul/midi_events.h> -#include "types.hpp" -#include "JackMidiDriver.hpp" -#include "JackAudioDriver.hpp" -#include "ThreadManager.hpp" -#include "AudioDriver.hpp" -#include "EventBuffer.hpp" -#include "DuplexPort.hpp" -#include "ProcessContext.hpp" -#include "jack_compat.h" -using namespace std; - -namespace Ingen { - - -//// JackMidiPort //// - -JackMidiPort::JackMidiPort(JackMidiDriver* driver, DuplexPort* patch_port) - : DriverPort(patch_port) - , Raul::List<JackMidiPort*>::Node(this) - , _driver(driver) - , _jack_port(NULL) -{ - assert(patch_port->poly() == 1); - - _jack_port = jack_port_register(_driver->jack_client(), - patch_port->path().c_str(), JACK_DEFAULT_MIDI_TYPE, - (patch_port->is_input()) ? JackPortIsInput : JackPortIsOutput, - 0); - - if (_jack_port == NULL) { - cerr << "[JackMidiPort] ERROR: Failed to register port " << patch_port->path() << endl; - throw JackAudioDriver::PortRegistrationFailedException(); - } - - patch_port->buffer(0)->clear(); -} - - -JackMidiPort::~JackMidiPort() -{ - jack_port_unregister(_driver->jack_client(), _jack_port); -} - - -/** Prepare input for a block before a cycle is run, in the audio thread. - * - * This is simple since Jack MIDI is in-band with audio. - */ -void -JackMidiPort::pre_process(ProcessContext& context) -{ - if ( ! is_input() ) - return; - - assert(_patch_port->poly() == 1); - - EventBuffer* patch_buf = dynamic_cast<EventBuffer*>(_patch_port->buffer(0)); - assert(patch_buf); - - void* jack_buffer = jack_port_get_buffer(_jack_port, context.nframes()); - const jack_nframes_t event_count = jack_midi_get_event_count(jack_buffer); - - patch_buf->prepare_write(context.start(), context.nframes()); - - // Copy events from Jack port buffer into patch port buffer - for (jack_nframes_t i=0; i < event_count; ++i) { - jack_midi_event_t ev; - jack_midi_event_get(&ev, jack_buffer, i); - - // FIXME: type is hardcoded for now, we should get it from - // the type map instead - const bool success = patch_buf->append(ev.time, 0, 1, ev.size, ev.buffer); - if (!success) - cerr << "WARNING: Failed to write MIDI to port buffer, event(s) lost!" << endl; - } - - //if (event_count) - // cerr << "Jack MIDI got " << event_count << " events." << endl; -} - - -/** Prepare output for a block after a cycle is run, in the audio thread. - * - * This is simple since Jack MIDI is in-band with audio. - */ -void -JackMidiPort::post_process(ProcessContext& context) -{ - if (is_input()) - return; - - EventBuffer* patch_buf = dynamic_cast<EventBuffer*>(_patch_port->buffer(0)); - void* jack_buf = jack_port_get_buffer(_jack_port, context.nframes()); - - assert(_patch_port->poly() == 1); - assert(patch_buf); - - patch_buf->prepare_read(context.start(), context.nframes()); - jack_midi_clear_buffer(jack_buf); - - uint32_t frames = 0; - uint32_t subframes = 0; - uint16_t type = 0; - uint16_t size = 0; - uint8_t* data = NULL; - - // Copy events from Jack port buffer into patch port buffer - for (patch_buf->rewind(); patch_buf->is_valid(); patch_buf->increment()) { - patch_buf->get_event(&frames, &subframes, &type, &size, &data); - jack_midi_event_write(jack_buf, frames, data, size); - } - - //if (event_count) - // cerr << "Jack MIDI wrote " << event_count << " events." << endl; -} - - - -//// JackMidiDriver //// - - -bool JackMidiDriver::_midi_thread_exit_flag = true; - - -JackMidiDriver::JackMidiDriver(jack_client_t* client) - : _client(client) - , _is_activated(false) - , _is_enabled(false) -{ -} - - -JackMidiDriver::~JackMidiDriver() -{ - deactivate(); -} - - -/** Launch and start the MIDI thread. - */ -void -JackMidiDriver::activate() -{ - _is_activated = true; -} - - -/** Terminate the MIDI thread. - */ -void -JackMidiDriver::deactivate() -{ - _is_activated = false; -} - - -/** Build flat arrays of events to be used as input for the given cycle. - */ -void -JackMidiDriver::pre_process(ProcessContext& context) -{ - for (Raul::List<JackMidiPort*>::iterator i = _in_ports.begin(); i != _in_ports.end(); ++i) - (*i)->pre_process(context); -} - - -/** Write the output from any (top-level, exported) MIDI output ports to Jack ports. - */ -void -JackMidiDriver::post_process(ProcessContext& context) -{ - for (Raul::List<JackMidiPort*>::iterator i = _out_ports.begin(); i != _out_ports.end(); ++i) - (*i)->post_process(context); -} - - -/** Add an Jack MIDI port. - * - * Realtime safe, this is to be called at the beginning of a process cycle to - * insert (and actually begin using) a new port. - * - * See new_port() and remove_port(). - */ -void -JackMidiDriver::add_port(DriverPort* port) -{ - assert(ThreadManager::current_thread_id() == THREAD_PROCESS); - assert(dynamic_cast<JackMidiPort*>(port)); - - if (port->is_input()) - _in_ports.push_back((JackMidiPort*)port); - else - _out_ports.push_back((JackMidiPort*)port); -} - - -/** Remove an Jack MIDI port. - * - * Realtime safe. This is to be called at the beginning of a process cycle to - * remove the port from the lists read by the audio thread, so the port - * will no longer be used and can be removed afterwards. - * - * It is the callers responsibility to delete the returned port. - */ -DriverPort* -JackMidiDriver::remove_port(const Path& path) -{ - assert(ThreadManager::current_thread_id() == THREAD_PROCESS); - - // FIXME: duplex? - - for (Raul::List<JackMidiPort*>::iterator i = _in_ports.begin(); i != _in_ports.end(); ++i) - if ((*i)->patch_port()->path() == path) - return _in_ports.erase(i)->elem(); // FIXME: LEAK - - for (Raul::List<JackMidiPort*>::iterator i = _out_ports.begin(); i != _out_ports.end(); ++i) - if ((*i)->patch_port()->path() == path) - return _out_ports.erase(i)->elem(); // FIXME: LEAK - - cerr << "[JackMidiDriver::remove_input] WARNING: Unable to find Jack port " << path << endl; - return NULL; -} - - -DriverPort* -JackMidiDriver::driver_port(const Path& path) -{ - assert(ThreadManager::current_thread_id() == THREAD_PROCESS); - - // FIXME: duplex? - - for (Raul::List<JackMidiPort*>::iterator i = _in_ports.begin(); i != _in_ports.end(); ++i) - if ((*i)->patch_port()->path() == path) - return (*i); - - for (Raul::List<JackMidiPort*>::iterator i = _out_ports.begin(); i != _out_ports.end(); ++i) - if ((*i)->patch_port()->path() == path) - return (*i); - - return NULL; -} - - -} // namespace Ingen - diff --git a/src/libs/engine/JackMidiDriver.hpp b/src/libs/engine/JackMidiDriver.hpp deleted file mode 100644 index 7889c4fa..00000000 --- a/src/libs/engine/JackMidiDriver.hpp +++ /dev/null @@ -1,113 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard <http://drobilla.net> - * - * 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 JACKMIDIDRIVER_H -#define JACKMIDIDRIVER_H - -#include <jack/jack.h> -#include <jack/midiport.h> -#include <raul/List.hpp> -#include CONFIG_H_PATH -#include "MidiDriver.hpp" - -namespace Ingen { - -class NodeImpl; -class SetPortValueEvent; -class JackMidiDriver; -class DuplexPort; - - -/** Representation of an JACK MIDI port. - * - * \ingroup engine - */ -class JackMidiPort : public DriverPort, public Raul::List<JackMidiPort*>::Node -{ -public: - JackMidiPort(JackMidiDriver* driver, DuplexPort* port); - virtual ~JackMidiPort(); - - void pre_process(ProcessContext& context); - void post_process(ProcessContext& context); - - void set_name(const std::string& name) { jack_port_set_name(_jack_port, name.c_str()); }; - -private: - JackMidiDriver* _driver; - jack_port_t* _jack_port; -}; - - -/** Jack MIDI driver. - * - * This driver reads Jack MIDI events and dispatches them to the appropriate - * JackMidiPort for processing. - * - * \ingroup engine - */ -class JackMidiDriver : public MidiDriver -{ -public: - JackMidiDriver(jack_client_t* client); - ~JackMidiDriver(); - - void activate(); - void deactivate(); - void enable() { _is_enabled = true; } - void disable() { _is_enabled = false; } - - bool is_activated() const { return _is_activated; } - bool is_enabled() const { return _is_enabled; } - - void pre_process(ProcessContext& context); - void post_process(ProcessContext& context); - - JackMidiPort* create_port(DuplexPort* patch_port) - { return new JackMidiPort(this, patch_port); } - - void add_port(DriverPort* port); - DriverPort* remove_port(const Raul::Path& path); - - DriverPort* driver_port(const Raul::Path& path); - - jack_client_t* jack_client() { return _client; } - -private: - Raul::List<JackMidiPort*> _in_ports; - Raul::List<JackMidiPort*> _out_ports; - - friend class JackMidiPort; - - void add_output(Raul::List<JackMidiPort*>::Node* port); - Raul::List<JackMidiPort*>::Node* remove_output(JackMidiPort* port); - - // MIDI thread - static void* process_midi_in(void* me); - - jack_client_t* _client; - pthread_t _process_thread; - bool _is_activated; - bool _is_enabled; - static bool _midi_thread_exit_flag; -}; - - -} // namespace Ingen - - -#endif // JACKMIDIDRIVER_H diff --git a/src/libs/engine/LADSPANode.cpp b/src/libs/engine/LADSPANode.cpp deleted file mode 100644 index 22f5bbf3..00000000 --- a/src/libs/engine/LADSPANode.cpp +++ /dev/null @@ -1,373 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard <http://drobilla.net> - * - * 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 <iostream> -#include <cassert> -#include <cmath> -#include <stdint.h> -#include <raul/Maid.hpp> -#include <boost/optional.hpp> -#include "LADSPANode.hpp" -#include "AudioBuffer.hpp" -#include "InputPort.hpp" -#include "OutputPort.hpp" -#include "PluginImpl.hpp" -#include "ProcessContext.hpp" - -using namespace std; - -namespace Ingen { - - -/** Partially construct a LADSPANode. - * - * Object is not usable until instantiate() is called with success. - * (It _will_ crash!) - */ -LADSPANode::LADSPANode(PluginImpl* plugin, const string& path, bool polyphonic, PatchImpl* parent, const LADSPA_Descriptor* descriptor, SampleRate srate, size_t buffer_size) - : NodeBase(plugin, path, polyphonic, parent, srate, buffer_size) - , _descriptor(descriptor) - , _instances(NULL) - , _prepared_instances(NULL) -{ - assert(_descriptor != NULL); -} - - -LADSPANode::~LADSPANode() -{ - for (uint32_t i=0; i < _polyphony; ++i) - _descriptor->cleanup((*_instances)[i]); - - delete _instances; -} - - -bool -LADSPANode::prepare_poly(uint32_t poly) -{ - NodeBase::prepare_poly(poly); - - if ( (!_polyphonic) - || (_prepared_instances && poly <= _prepared_instances->size()) ) { - return true; - } - - _prepared_instances = new Raul::Array<LADSPA_Handle>(poly, *_instances); - for (uint32_t i = _polyphony; i < _prepared_instances->size(); ++i) { - _prepared_instances->at(i) = _descriptor->instantiate(_descriptor, _srate); - if (_prepared_instances->at(i) == NULL) { - cerr << "Failed to instantiate plugin!" << endl; - return false; - } - - if (_activated && _descriptor->activate) - _descriptor->activate(_prepared_instances->at(i)); - } - - return true; -} - - -bool -LADSPANode::apply_poly(Raul::Maid& maid, uint32_t poly) -{ - if (!_polyphonic) - return true; - - if (_prepared_instances) { - assert(poly <= _prepared_instances->size()); - maid.push(_instances); - _instances = _prepared_instances; - _prepared_instances = NULL; - } - - assert(poly <= _instances->size()); - _polyphony = poly; - - return NodeBase::apply_poly(maid, poly); -} - - -static string -nameify_if_invalid(const string& name) -{ - if (Path::is_valid_name(name)) { - return name; - } else { - const string new_name = Path::nameify(name); - assert(Path::is_valid_name(new_name)); - if (new_name != name) - cerr << "Symbol '" << new_name << "' generated from LADSPA name '" << name << endl; - return new_name; - } -} - - -/** Instantiate self from LADSPA plugin descriptor. - * - * Implemented as a seperate function (rather than in the constructor) to - * allow graceful error-catching of broken plugins. - * - * Returns whether or not plugin was successfully instantiated. If return - * value is false, this object may not be used. - */ -bool -LADSPANode::instantiate() -{ - if (!_ports) - _ports = new Raul::Array<PortImpl*>(_descriptor->PortCount); - - _instances = new Raul::Array<LADSPA_Handle>(_polyphony, NULL); - - size_t port_buffer_size = 0; - - for (uint32_t i=0; i < _polyphony; ++i) { - (*_instances)[i] = _descriptor->instantiate(_descriptor, _srate); - if ((*_instances)[i] == NULL) { - cerr << "Failed to instantiate plugin!" << endl; - return false; - } - } - - string port_name; - string port_path; - - PortImpl* port = NULL; - - for (size_t j=0; j < _descriptor->PortCount; ++j) { - port_name = nameify_if_invalid(_descriptor->PortNames[j]); - - string::size_type slash_index; - - // Name mangling, to guarantee port names are unique - for (size_t k=0; k < _descriptor->PortCount; ++k) { - assert(_descriptor->PortNames[k] != NULL); - if (k != j && port_name == _descriptor->PortNames[k]) { // clash - if (LADSPA_IS_PORT_CONTROL(_descriptor->PortDescriptors[j])) - port_name += "(CR)"; - else - port_name += "(AR)"; - } - // Replace all slashes with "-" (so they don't screw up paths) - while ((slash_index = port_name.find("/")) != string::npos) - port_name[slash_index] = '-'; - } - - /*if (_descriptor->PortNames[j] != port_name) - cerr << "NOTICE: Translated LADSPA port name: " << - _descriptor->PortNames[j] << " -> " << port_name << endl;*/ - - port_path = path() + "/" + port_name; - - DataType type = DataType::AUDIO; - port_buffer_size = _buffer_size; - - if (LADSPA_IS_PORT_CONTROL(_descriptor->PortDescriptors[j])) { - type = DataType::CONTROL; - port_buffer_size = 1; - } else { - assert(LADSPA_IS_PORT_AUDIO(_descriptor->PortDescriptors[j])); - } - assert (LADSPA_IS_PORT_INPUT(_descriptor->PortDescriptors[j]) - || LADSPA_IS_PORT_OUTPUT(_descriptor->PortDescriptors[j])); - - boost::optional<Sample> default_val, min, max; - get_port_limits(j, default_val, min, max); - - const float value = default_val ? default_val.get() : 0.0f; - - if (LADSPA_IS_PORT_INPUT(_descriptor->PortDescriptors[j])) { - port = new InputPort(this, port_name, j, _polyphony, type, value, port_buffer_size); - _ports->at(j) = port; - } else if (LADSPA_IS_PORT_OUTPUT(_descriptor->PortDescriptors[j])) { - port = new OutputPort(this, port_name, j, _polyphony, type, value, port_buffer_size); - _ports->at(j) = port; - } - - assert(port); - assert(_ports->at(j) == port); - - // Work around broke-ass crackhead plugins - if (default_val && default_val.get() < min.get()) { - cerr << "WARNING: Broken LADSPA " << _descriptor->UniqueID - << ": Port default < minimum. Minimum adjusted." << endl; - min = default_val; - } - - if (default_val && default_val.get() > max.get()) { - cerr << "WARNING: Broken LADSPA " << _descriptor->UniqueID - << ": Maximum adjusted." << endl; - max = default_val; - } - - // Set initial/default value - if (port->buffer_size() == 1) { - for (uint32_t i=0; i < _polyphony; ++i) - ((AudioBuffer*)port->buffer(i))->set_value(value, 0, 0); - } - - if (port->is_input() && port->buffer_size() == 1) { - if (min) - port->set_variable("ingen:minimum", min.get()); - if (max) - port->set_variable("ingen:maximum", max.get()); - if (default_val) - port->set_variable("ingen:default", default_val.get()); - } - } - - return true; -} - - -void -LADSPANode::activate() -{ - NodeBase::activate(); - - for (uint32_t i=0; i < _polyphony; ++i) { - for (unsigned long j=0; j < _descriptor->PortCount; ++j) { - set_port_buffer(i, j, _ports->at(j)->buffer(i)); - /* if (port->type() == DataType::FLOAT && port->buffer_size() == 1) - port->set_value(0.0f, 0); // FIXME - else if (port->type() == DataType::FLOAT && port->buffer_size() > 1) - port->set_value(0.0f, 0);*/ - } - if (_descriptor->activate != NULL) - _descriptor->activate((*_instances)[i]); - } -} - - -void -LADSPANode::deactivate() -{ - NodeBase::deactivate(); - - for (uint32_t i=0; i < _polyphony; ++i) - if (_descriptor->deactivate != NULL) - _descriptor->deactivate((*_instances)[i]); -} - - -void -LADSPANode::process(ProcessContext& context) -{ - NodeBase::pre_process(context); - - for (uint32_t i=0; i < _polyphony; ++i) - _descriptor->run((*_instances)[i], context.nframes()); - - NodeBase::post_process(context); -} - - -void -LADSPANode::set_port_buffer(uint32_t voice, uint32_t port_num, Buffer* buf) -{ - assert(voice < _polyphony); - - AudioBuffer* audio_buffer = dynamic_cast<AudioBuffer*>(buf); - assert(audio_buffer); - - if (port_num < _descriptor->PortCount) - _descriptor->connect_port((*_instances)[voice], port_num, - audio_buffer->data()); -} - - -void -LADSPANode::get_port_limits(unsigned long port_index, - boost::optional<Sample>& normal, - boost::optional<Sample>& lower, - boost::optional<Sample>& upper) -{ - LADSPA_PortRangeHintDescriptor hint_descriptor = _descriptor->PortRangeHints[port_index].HintDescriptor; - - /* set upper and lower, possibly adjusted to the sample rate */ - if (LADSPA_IS_HINT_SAMPLE_RATE(hint_descriptor)) { - upper = _descriptor->PortRangeHints[port_index].UpperBound * _srate; - lower = _descriptor->PortRangeHints[port_index].LowerBound * _srate; - } else { - upper = _descriptor->PortRangeHints[port_index].UpperBound; - lower = _descriptor->PortRangeHints[port_index].LowerBound; - } - - if (LADSPA_IS_HINT_LOGARITHMIC(hint_descriptor)) { - /* FLT_EPSILON is defined as the different between 1.0 and the minimum - * float greater than 1.0. So, if lower is < FLT_EPSILON, it will be 1.0 - * and the logarithmic control will have a base of 1 and thus not change - */ - if (lower.get() < FLT_EPSILON) lower = FLT_EPSILON; - } - - - if (LADSPA_IS_HINT_HAS_DEFAULT(hint_descriptor)) { - - if (LADSPA_IS_HINT_DEFAULT_MINIMUM(hint_descriptor)) { - normal = lower; - } else if (LADSPA_IS_HINT_DEFAULT_LOW(hint_descriptor)) { - assert(lower); - assert(upper); - if (LADSPA_IS_HINT_LOGARITHMIC(hint_descriptor)) { - normal = exp(log(lower.get()) * 0.75 + log(upper.get()) * 0.25); - } else { - normal = lower.get() * 0.75 + upper.get() * 0.25; - } - } else if (LADSPA_IS_HINT_DEFAULT_MIDDLE(hint_descriptor)) { - assert(lower); - assert(upper); - if (LADSPA_IS_HINT_LOGARITHMIC(hint_descriptor)) { - normal = exp(log(lower.get()) * 0.5 + log(upper.get()) * 0.5); - } else { - normal = lower.get() * 0.5 + upper.get() * 0.5; - } - } else if (LADSPA_IS_HINT_DEFAULT_HIGH(hint_descriptor)) { - assert(lower); - assert(upper); - if (LADSPA_IS_HINT_LOGARITHMIC(hint_descriptor)) { - normal = exp(log(lower.get()) * 0.25 + log(upper.get()) * 0.75); - } else { - normal = lower.get() * 0.25 + upper.get() * 0.75; - } - } else if (LADSPA_IS_HINT_DEFAULT_MAXIMUM(hint_descriptor)) { - assert(upper); - normal = upper.get(); - } else if (LADSPA_IS_HINT_DEFAULT_0(hint_descriptor)) { - normal = 0.0; - } else if (LADSPA_IS_HINT_DEFAULT_1(hint_descriptor)) { - normal = 1.0; - } else if (LADSPA_IS_HINT_DEFAULT_100(hint_descriptor)) { - normal = 100.0; - } else if (LADSPA_IS_HINT_DEFAULT_440(hint_descriptor)) { - normal = 440.0; - } - } else { // No default hint - if (LADSPA_IS_HINT_BOUNDED_BELOW(hint_descriptor)) { - assert(lower); - normal = lower.get(); - } else if (LADSPA_IS_HINT_BOUNDED_ABOVE(hint_descriptor)) { - assert(upper); - normal = upper.get(); - } - } -} - - -} // namespace Ingen - diff --git a/src/libs/engine/LADSPANode.hpp b/src/libs/engine/LADSPANode.hpp deleted file mode 100644 index 53d7ad9e..00000000 --- a/src/libs/engine/LADSPANode.hpp +++ /dev/null @@ -1,74 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard <http://drobilla.net> - * - * 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 LADSPANODE_H -#define LADSPANODE_H - -#include <string> -#include <ladspa.h> -#include <boost/optional.hpp> -#include "types.hpp" -#include "NodeBase.hpp" -#include "PluginImpl.hpp" - -namespace Ingen { - - -/** An instance of a LADSPA plugin. - * - * \ingroup engine - */ -class LADSPANode : public NodeBase -{ -public: - LADSPANode(PluginImpl* plugin, - const string& name, - bool polyphonic, - PatchImpl* parent, - const LADSPA_Descriptor* descriptor, - SampleRate srate, - size_t buffer_size); - - ~LADSPANode(); - - bool instantiate(); - - bool prepare_poly(uint32_t poly); - bool apply_poly(Raul::Maid& maid, uint32_t poly); - - void activate(); - void deactivate(); - - void process(ProcessContext& context); - - void set_port_buffer(uint32_t voice, uint32_t port_num, Buffer* buf); - -protected: - void get_port_limits(unsigned long port_index, - boost::optional<Sample>& default_value, - boost::optional<Sample>& lower_bound, - boost::optional<Sample>& upper_bound); - - const LADSPA_Descriptor* _descriptor; - Raul::Array<LADSPA_Handle>* _instances; - Raul::Array<LADSPA_Handle>* _prepared_instances; -}; - - -} // namespace Ingen - -#endif // LADSPANODE_H diff --git a/src/libs/engine/LADSPAPlugin.cpp b/src/libs/engine/LADSPAPlugin.cpp deleted file mode 100644 index 4a0b5c14..00000000 --- a/src/libs/engine/LADSPAPlugin.cpp +++ /dev/null @@ -1,79 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard <http://drobilla.net> - * - * 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 <cassert> -#include <ladspa.h> -#include <iostream> -#include "LADSPAPlugin.hpp" -#include "LADSPANode.hpp" -#include "NodeImpl.hpp" -#include "Engine.hpp" -#include "AudioDriver.hpp" - -using namespace std; - -namespace Ingen { - - -NodeImpl* -LADSPAPlugin::instantiate(const string& name, - bool polyphonic, - Ingen::PatchImpl* parent, - Engine& engine) -{ - assert(_id != 0); - - SampleCount srate = engine.audio_driver()->sample_rate(); - SampleCount buffer_size = engine.audio_driver()->buffer_size(); - - LADSPA_Descriptor_Function df = NULL; - LADSPANode* n = NULL; - - load(); // FIXME: unload at some point - assert(_module); - assert(*_module); - - if (!_module->get_symbol("ladspa_descriptor", (void*&)df)) { - cerr << "Looks like this isn't a LADSPA plugin." << endl; - return NULL; - } - - // Attempt to find the plugin in library - LADSPA_Descriptor* descriptor = NULL; - for (unsigned long i=0; (descriptor = (LADSPA_Descriptor*)df(i)) != NULL; ++i) { - if (descriptor->UniqueID == _id) { - break; - } - } - - if (descriptor != NULL) { - n = new LADSPANode(this, name, polyphonic, parent, descriptor, srate, buffer_size); - - if ( ! n->instantiate() ) { - delete n; - n = NULL; - } - - } else { - cerr << "Could not find plugin \"" << _id << "\" in " << _library_path << endl; - } - - return n; -} - - -} // namespace Ingen diff --git a/src/libs/engine/LADSPAPlugin.hpp b/src/libs/engine/LADSPAPlugin.hpp deleted file mode 100644 index 2414be7c..00000000 --- a/src/libs/engine/LADSPAPlugin.hpp +++ /dev/null @@ -1,78 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard <http://drobilla.net> - * - * 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 LADSPAPLUGIN_H -#define LADSPAPLUGIN_H - -#include CONFIG_H_PATH - -#include <cstdlib> -#include <glibmm/module.h> -#include <boost/utility.hpp> -#include <dlfcn.h> -#include <string> -#include <iostream> -#include <raul/Path.hpp> -#include "types.hpp" -#include "PluginImpl.hpp" - -namespace Ingen { - -class NodeImpl; - - -/** Implementation of a LADSPA plugin (loaded shared library). - */ -class LADSPAPlugin : public PluginImpl -{ -public: - LADSPAPlugin(const std::string& library_path, - const std::string& uri, - unsigned long id, - const string& label, - const string& name) - : PluginImpl(Plugin::LADSPA, uri, library_path) - , _id(id) - , _label(label) - , _name(name) - {} - - NodeImpl* instantiate(const std::string& name, - bool polyphonic, - Ingen::PatchImpl* parent, - Engine& engine); - - const std::string& label() const { return _label; } - unsigned long id() const { return _id; } - const string symbol() const { return Raul::Path::nameify(_label); } - const string name() const { return _name; } - - const string library_name() const { - return _library_path.substr(_library_path.find_last_of("/")+1); - } - -private: - const unsigned long _id; - const std::string _label; - const std::string _name; -}; - - -} // namespace Ingen - -#endif // LADSPAPLUGIN_H - diff --git a/src/libs/engine/LV2Info.cpp b/src/libs/engine/LV2Info.cpp deleted file mode 100644 index 43dd014b..00000000 --- a/src/libs/engine/LV2Info.cpp +++ /dev/null @@ -1,70 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2008 Dave Robillard <http://drobilla.net> - * - * 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 - */ - -#define __STDC_LIMIT_MACROS 1 -#include <cassert> -#include <iostream> -#include <stdint.h> -#include "LV2Info.hpp" -#include <module/World.hpp> - -using namespace std; - -namespace Ingen { - -LV2Info::LV2Info(Ingen::Shared::World* world) - : input_class(slv2_value_new_uri(world->slv2_world, SLV2_PORT_CLASS_INPUT)) - , output_class(slv2_value_new_uri(world->slv2_world, SLV2_PORT_CLASS_OUTPUT)) - , control_class(slv2_value_new_uri(world->slv2_world, SLV2_PORT_CLASS_CONTROL)) - , audio_class(slv2_value_new_uri(world->slv2_world, SLV2_PORT_CLASS_AUDIO)) - , event_class(slv2_value_new_uri(world->slv2_world, SLV2_PORT_CLASS_EVENT)) - , _world(world) -{ - assert(world); - - LV2_Event_Feature* ev_data = (LV2_Event_Feature*)malloc(sizeof(LV2_Event_Feature)); - ev_data->lv2_event_ref = &LV2Info::event_ref; - ev_data->lv2_event_unref = &LV2Info::event_ref; - ev_data->callback_data = this; - LV2_Feature* ev_feature = (LV2_Feature*)malloc(sizeof(LV2_Event_Feature)); - ev_feature->URI = LV2_EVENT_URI; - ev_feature->data = ev_data; - - world->lv2_features->add_feature(LV2_EVENT_URI, ev_feature, ev_data); -} - - -LV2Info::~LV2Info() -{ - slv2_value_free(input_class); - slv2_value_free(output_class); - slv2_value_free(control_class); - slv2_value_free(audio_class); - slv2_value_free(event_class); -} - - -uint32_t -LV2Info::event_ref(LV2_Event_Callback_Data callback_data, - LV2_Event* event) -{ - return 0; -} - - - -} // namespace Ingen diff --git a/src/libs/engine/LV2Info.hpp b/src/libs/engine/LV2Info.hpp deleted file mode 100644 index f4859ac7..00000000 --- a/src/libs/engine/LV2Info.hpp +++ /dev/null @@ -1,66 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2008 Dave Robillard <http://drobilla.net> - * - * 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 LV2INFO_H -#define LV2INFO_H - -#include CONFIG_H_PATH -#ifndef HAVE_SLV2 -#error "This file requires SLV2, but HAVE_SLV2 is not defined. Please report." -#endif - -#include <map> -#include <string> -#include <slv2/slv2.h> -#include "module/global.hpp" -#include "module/World.hpp" -#include "shared/LV2URIMap.hpp" -#include "lv2ext/lv2_uri_map.h" -#include "lv2ext/lv2_event.h" - -namespace Ingen { - - -/** Stuff that may need to be passed to an LV2 plugin (i.e. LV2 features). - */ -class LV2Info : public Shared::LV2URIMap { -public: - LV2Info(Ingen::Shared::World* world); - ~LV2Info(); - - SLV2Value input_class; - SLV2Value output_class; - SLV2Value control_class; - SLV2Value audio_class; - SLV2Value event_class; - - Ingen::Shared::World& world() { return *_world; } - SLV2World lv2_world() { return _world->slv2_world; } - - static uint32_t event_ref(LV2_Event_Callback_Data callback_data, - LV2_Event* event); - - LV2_Feature** lv2_features() const { return _world->lv2_features->lv2_features(); } - -private: - Ingen::Shared::World* _world; -}; - - -} // namespace Ingen - -#endif // LV2INFO_H diff --git a/src/libs/engine/LV2Node.cpp b/src/libs/engine/LV2Node.cpp deleted file mode 100644 index a06cc55a..00000000 --- a/src/libs/engine/LV2Node.cpp +++ /dev/null @@ -1,305 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard <http://drobilla.net> - * - * 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 <iostream> -#include <cassert> -#include <float.h> -#include <stdint.h> -#include <cmath> -#include <raul/Maid.hpp> -#include "AudioBuffer.hpp" -#include "InputPort.hpp" -#include "LV2Node.hpp" -#include "LV2Plugin.hpp" -#include "EventBuffer.hpp" -#include "OutputPort.hpp" -#include "ProcessContext.hpp" -#include "lv2_contexts.h" - -using namespace std; - -namespace Ingen { - - -/** Partially construct a LV2Node. - * - * Object is not usable until instantiate() is called with success. - * (It _will_ crash!) - */ -LV2Node::LV2Node(LV2Plugin* plugin, - const string& name, - bool polyphonic, - PatchImpl* parent, - SampleRate srate, - size_t buffer_size) - : NodeBase(plugin, name, polyphonic, parent, srate, buffer_size) - , _lv2_plugin(plugin) - , _instances(NULL) - , _prepared_instances(NULL) - , _message_run(NULL) -{ - assert(_lv2_plugin); -} - - -LV2Node::~LV2Node() -{ - for (uint32_t i=0; i < _polyphony; ++i) - slv2_instance_free((*_instances)[i]); - - delete _instances; -} - - -bool -LV2Node::prepare_poly(uint32_t poly) -{ - NodeBase::prepare_poly(poly); - - if ( (!_polyphonic) - || (_prepared_instances && poly <= _prepared_instances->size()) ) { - return true; - } - - _prepared_instances = new Raul::Array<SLV2Instance>(poly, *_instances); - for (uint32_t i = _polyphony; i < _prepared_instances->size(); ++i) { - // FIXME: features array (in NodeFactory) must be passed! - _prepared_instances->at(i) = slv2_plugin_instantiate( - _lv2_plugin->slv2_plugin(), _srate, NULL); - - if (_prepared_instances->at(i) == NULL) { - cerr << "Failed to instantiate plugin!" << endl; - return false; - } - - if (_activated) - slv2_instance_activate(_prepared_instances->at(i)); - } - - return true; -} - - -bool -LV2Node::apply_poly(Raul::Maid& maid, uint32_t poly) -{ - if (!_polyphonic) - return true; - - if (_prepared_instances) { - assert(poly <= _prepared_instances->size()); - maid.push(_instances); - _instances = _prepared_instances; - _prepared_instances = NULL; - } - - assert(poly <= _instances->size()); - _polyphony = poly; - - return NodeBase::apply_poly(maid, poly); -} - - -/** Instantiate self from LV2 plugin descriptor. - * - * Implemented as a seperate function (rather than in the constructor) to - * allow graceful error-catching of broken plugins. - * - * Returns whether or not plugin was successfully instantiated. If return - * value is false, this object may not be used. - */ -bool -LV2Node::instantiate() -{ - SharedPtr<LV2Info> info = _lv2_plugin->lv2_info(); - SLV2Plugin plug = _lv2_plugin->slv2_plugin(); - - uint32_t num_ports = slv2_plugin_get_num_ports(plug); - assert(num_ports > 0); - - _ports = new Raul::Array<PortImpl*>(num_ports, NULL); - _instances = new Raul::Array<SLV2Instance>(_polyphony, NULL); - - uint32_t port_buffer_size = 0; - - for (uint32_t i=0; i < _polyphony; ++i) { - (*_instances)[i] = slv2_plugin_instantiate(plug, _srate, info->lv2_features()); - if ((*_instances)[i] == NULL) { - cerr << "Failed to instantiate plugin!" << endl; - return false; - } - - const void* ctx_ext = slv2_instance_get_extension_data( - (*_instances)[i], LV2_CONTEXT_MESSAGE); - - if (ctx_ext) { - cerr << "HAS CONTEXT EXTENSION" << endl; - if (_message_run == NULL) - _message_run = new MessageRunFuncs(_polyphony, NULL); - LV2MessageContext* mc = (LV2MessageContext*)ctx_ext; - (*_message_run)[i] = mc->message_run; - } - } - - string port_name; - string port_path; - - PortImpl* port = NULL; - - float* def_values = new float[num_ports]; - slv2_plugin_get_port_ranges_float(plug, 0, 0, def_values); - - for (uint32_t j=0; j < num_ports; ++j) { - SLV2Port id = slv2_plugin_get_port_by_index(plug, j); - - // LV2 shortnames are guaranteed to be unique, valid C identifiers - port_name = slv2_value_as_string(slv2_port_get_symbol(plug, id)); - - assert(port_name.find("/") == string::npos); - - port_path = path() + "/" + port_name; - - DataType data_type = DataType::UNKNOWN; - if (slv2_port_is_a(plug, id, info->control_class)) { - data_type = DataType::CONTROL; - port_buffer_size = 1; - } else if (slv2_port_is_a(plug, id, info->audio_class)) { - data_type = DataType::AUDIO; - port_buffer_size = _buffer_size; - } else if (slv2_port_is_a(plug, id, info->event_class)) { - data_type = DataType::EVENT; - port_buffer_size = _buffer_size; - } - - enum { UNKNOWN, INPUT, OUTPUT } direction = UNKNOWN; - if (slv2_port_is_a(plug, id, info->input_class)) { - direction = INPUT; - } else if (slv2_port_is_a(plug, id, info->output_class)) { - direction = OUTPUT; - } - - if (data_type == DataType::UNKNOWN || direction == UNKNOWN) { - delete _ports; - _ports = NULL; - delete _instances; - _instances = NULL; - return false; - } - - // FIXME: need nice type preserving SLV2Value -> Raul::Atom conversion - float def = isnan(def_values[j]) ? 0.0f : def_values[j]; - Atom defatm = def; - - if (direction == INPUT) - port = new InputPort(this, port_name, j, _polyphony, data_type, defatm, port_buffer_size); - else - port = new OutputPort(this, port_name, j, _polyphony, data_type, defatm, port_buffer_size); - - if (direction == INPUT && data_type == DataType::CONTROL) - ((AudioBuffer*)port->buffer(0))->set_value(def, 0, 0); - - SLV2Value pred = slv2_value_new_uri(info->lv2_world(), - "http://lv2plug.in/ns/dev/contexts#context"); - SLV2Values contexts = slv2_port_get_value(plug, id, pred); - for (uint32_t i = 0; i < slv2_values_size(contexts); ++i) { - SLV2Value c = slv2_values_get_at(contexts, i); - const char* context = slv2_value_as_string(c); - if (!strcmp("http://lv2plug.in/ns/dev/contexts#MessageContext", context)) { - cout << "MESSAGE CONTEXT!" << endl; - port->set_context(Context::MESSAGE); - } else { - cout << "UNKNOWN CONTEXT: " - << slv2_value_as_string(slv2_values_get_at(contexts, i)) - << endl; - } - } - - _ports->at(j) = port; - } - - delete [] def_values; - - return true; -} - - -void -LV2Node::activate() -{ - NodeBase::activate(); - - for (uint32_t i=0; i < _polyphony; ++i) { - for (unsigned long j=0; j < num_ports(); ++j) { - PortImpl* const port = _ports->at(j); - - set_port_buffer(i, j, port->buffer(i)); - - if (port->type() == DataType::CONTROL) { - ((AudioBuffer*)port->buffer(i))->set_value(port->value().get_float(), 0, 0); - } else if (port->type() == DataType::AUDIO) { - ((AudioBuffer*)port->buffer(i))->set_value(0.0f, 0, 0); - } - } - slv2_instance_activate((*_instances)[i]); - } -} - - -void -LV2Node::deactivate() -{ - NodeBase::deactivate(); - - for (uint32_t i=0; i < _polyphony; ++i) - slv2_instance_deactivate((*_instances)[i]); -} - - -void -LV2Node::message_process(MessageContext& context, uint32_t* output) -{ - // FIXME: voice - if (_message_run) - (*_message_run)[0]((*_instances)[0], output); - - /* MESSAGE PROCESS */ -} - - -void -LV2Node::process(ProcessContext& context) -{ - NodeBase::pre_process(context); - - for (uint32_t i=0; i < _polyphony; ++i) - slv2_instance_run((*_instances)[i], context.nframes()); - - NodeBase::post_process(context); -} - - -void -LV2Node::set_port_buffer(uint32_t voice, uint32_t port_num, Buffer* buf) -{ - assert(voice < _polyphony); - - slv2_instance_connect_port((*_instances)[voice], port_num, buf->raw_data()); -} - - -} // namespace Ingen - diff --git a/src/libs/engine/LV2Node.hpp b/src/libs/engine/LV2Node.hpp deleted file mode 100644 index 3187005c..00000000 --- a/src/libs/engine/LV2Node.hpp +++ /dev/null @@ -1,75 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard <http://drobilla.net> - * - * 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 LV2NODE_H -#define LV2NODE_H - -#include <string> -#include <slv2/slv2.h> -#include "types.hpp" -#include "NodeBase.hpp" - -namespace Ingen { - -class LV2Plugin; - - -/** An instance of a LV2 plugin. - * - * \ingroup engine - */ -class LV2Node : public NodeBase -{ -public: - LV2Node(LV2Plugin* plugin, - const string& name, - bool polyphonic, - PatchImpl* parent, - SampleRate srate, - size_t buffer_size); - - ~LV2Node(); - - bool instantiate(); - - bool prepare_poly(uint32_t poly); - bool apply_poly(Raul::Maid& maid, uint32_t poly); - - void activate(); - void deactivate(); - - void message_process(MessageContext& context, uint32_t* output); - - void process(ProcessContext& context); - - void set_port_buffer(uint32_t voice, uint32_t port_num, Buffer* buf); - -protected: - LV2Plugin* _lv2_plugin; - Raul::Array<SLV2Instance>* _instances; - Raul::Array<SLV2Instance>* _prepared_instances; - - typedef bool (*MessageRunFunc)(LV2_Handle, uint32_t*); - typedef Raul::Array<MessageRunFunc> MessageRunFuncs; - MessageRunFuncs* _message_run; -}; - - -} // namespace Ingen - -#endif // LV2NODE_H - diff --git a/src/libs/engine/LV2Plugin.cpp b/src/libs/engine/LV2Plugin.cpp deleted file mode 100644 index 90a3a6b8..00000000 --- a/src/libs/engine/LV2Plugin.cpp +++ /dev/null @@ -1,94 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard <http://drobilla.net> - * - * 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 <cassert> -#include <glibmm.h> -#include <redlandmm/World.hpp> -#include "LV2Plugin.hpp" -#include "LV2Node.hpp" -#include "NodeImpl.hpp" -#include "Engine.hpp" -#include "AudioDriver.hpp" - -namespace Ingen { - - -const string -LV2Plugin::symbol() const -{ - string working = _uri; - if (working[working.length()-1] == '/') - working = working.substr(0, working.length()-1); - - while (working.length() > 0) { - size_t last_slash = working.find_last_of("/"); - const string symbol = working.substr(last_slash+1); - if ( (symbol[0] >= 'a' && symbol[0] <= 'z') - || (symbol[0] >= 'A' && symbol[0] <= 'Z') ) - return Path::nameify(symbol); - else - working = working.substr(0, last_slash); - } - - return "lv2_symbol"; -} - - -const string -LV2Plugin::name() const -{ - if (_name) - return slv2_value_as_string(_name); - else - return "(no name)"; -} - - -NodeImpl* -LV2Plugin::instantiate(const string& name, - bool polyphonic, - Ingen::PatchImpl* parent, - Engine& engine) -{ - SampleCount srate = engine.audio_driver()->sample_rate(); - SampleCount buffer_size = engine.audio_driver()->buffer_size(); - - load(); // FIXME: unload at some point - - Glib::Mutex::Lock lock(engine.world()->rdf_world->mutex()); - LV2Node* n = new LV2Node(this, name, polyphonic, parent, srate, buffer_size); - - if ( ! n->instantiate() ) { - delete n; - n = NULL; - } - - return n; -} - - -void -LV2Plugin::slv2_plugin(SLV2Plugin p) -{ - _slv2_plugin = p; - if (_name) - slv2_value_free(_name); - _name = slv2_plugin_get_name(_slv2_plugin); -} - - -} // namespace Ingen diff --git a/src/libs/engine/LV2Plugin.hpp b/src/libs/engine/LV2Plugin.hpp deleted file mode 100644 index c9bc4ff9..00000000 --- a/src/libs/engine/LV2Plugin.hpp +++ /dev/null @@ -1,84 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard <http://drobilla.net> - * - * 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 LV2PLUGIN_H -#define LV2PLUGIN_H - -#include CONFIG_H_PATH - -#ifndef HAVE_SLV2 -#error "This file requires SLV2, but HAVE_SLV2 is not defined. Please report." -#endif - -#include <cstdlib> -#include <glibmm/module.h> -#include <boost/utility.hpp> -#include <dlfcn.h> -#include <string> -#include <iostream> -#include <slv2/slv2.h> -#include <raul/SharedPtr.hpp> -#include "types.hpp" -#include "PluginImpl.hpp" -#include "LV2Info.hpp" - -using std::string; -using Ingen::Shared::Plugin; - - -namespace Ingen { - -class PatchImpl; -class NodeImpl; - - -/** Implementation of an LV2 plugin (loaded shared library). - */ -class LV2Plugin : public PluginImpl -{ -public: - LV2Plugin(SharedPtr<LV2Info> lv2_info, const string& uri) - : PluginImpl(Plugin::LV2, uri) - , _name(NULL) - , _slv2_plugin(NULL) - , _lv2_info(lv2_info) - {} - - NodeImpl* instantiate(const string& name, - bool polyphonic, - Ingen::PatchImpl* parent, - Engine& engine); - - const string symbol() const; - const string name() const; - - SharedPtr<LV2Info> lv2_info() const { return _lv2_info; } - - SLV2Plugin slv2_plugin() const { return _slv2_plugin; } - void slv2_plugin(SLV2Plugin p); - -private: - SLV2Value _name; - SLV2Plugin _slv2_plugin; - SharedPtr<LV2Info> _lv2_info; -}; - - -} // namespace Ingen - -#endif // LV2PLUGIN_H - diff --git a/src/libs/engine/Makefile.am b/src/libs/engine/Makefile.am deleted file mode 100644 index 3c464de3..00000000 --- a/src/libs/engine/Makefile.am +++ /dev/null @@ -1,205 +0,0 @@ -SUBDIRS = events - -MAINTAINERCLEANFILES = Makefile.in - -moduledir = $(libdir)/ingen - -module_LTLIBRARIES = libingen_engine.la -libingen_engine_la_CXXFLAGS = \ - @GLIBMM_CFLAGS@ \ - @INGEN_CFLAGS@ \ - @JACK_CFLAGS@ \ - @LIBLO_CFLAGS@ \ - @RAUL_CFLAGS@ \ - @REDLANDMM_CFLAGS@ \ - @SLV2_CFLAGS@ \ - @SOUP_CFLAGS@ - -libingen_engine_la_LDFLAGS = -no-undefined -module -avoid-version -libingen_engine_la_LIBADD = \ - ../shared/libingen_shared.la \ - ../module/libingen_module.la \ - @GLIBMM_LIBS@ \ - @JACK_LIBS@ \ - @LIBLO_LIBS@ \ - @RAUL_LIBS@ \ - @REDLANDMM_LIBS@ \ - @SLV2_LIBS@ \ - @SOUP_LIBS@ - -AM_CFLAGS=-std=c99 - -libingen_engine_la_SOURCES = \ - AudioBuffer.cpp \ - AudioBuffer.hpp \ - AudioDriver.hpp \ - Buffer.cpp \ - Buffer.hpp \ - ClientBroadcaster.cpp \ - ClientBroadcaster.hpp \ - CompiledPatch.hpp \ - ConnectionImpl.cpp \ - ConnectionImpl.hpp \ - Driver.hpp \ - DuplexPort.cpp \ - DuplexPort.hpp \ - Engine.cpp \ - Engine.hpp \ - EngineStore.cpp \ - EngineStore.hpp \ - Event.cpp \ - Event.hpp \ - EventBuffer.cpp \ - EventBuffer.hpp \ - EventSink.cpp \ - EventSink.hpp \ - EventSource.hpp \ - GraphObjectImpl.cpp \ - GraphObjectImpl.hpp \ - InputPort.cpp \ - InputPort.hpp \ - InternalPlugin.cpp \ - InternalPlugin.hpp \ - JackAudioDriver.cpp \ - JackAudioDriver.hpp \ - JackMidiDriver.cpp \ - JackMidiDriver.hpp \ - LADSPAPlugin.cpp \ - LADSPAPlugin.hpp \ - LV2Info.cpp \ - LV2Info.hpp \ - LV2Plugin.cpp \ - LV2Plugin.hpp \ - MessageContext.cpp \ - MessageContext.hpp \ - MidiControlNode.cpp \ - MidiControlNode.hpp \ - MidiDriver.hpp \ - MidiNoteNode.cpp \ - MidiNoteNode.hpp \ - MidiTriggerNode.cpp \ - MidiTriggerNode.hpp \ - NodeBase.cpp \ - NodeBase.hpp \ - NodeFactory.cpp \ - NodeFactory.hpp \ - NodeImpl.hpp \ - OSCClientSender.cpp \ - OSCClientSender.hpp \ - OSCDriver.hpp \ - OSCEngineReceiver.cpp \ - OSCEngineReceiver.hpp \ - ObjectSender.cpp \ - ObjectSender.hpp \ - OutputPort.cpp \ - OutputPort.hpp \ - PatchImpl.cpp \ - PatchImpl.hpp \ - PatchPlugin.hpp \ - PluginImpl.cpp \ - PluginImpl.hpp \ - PortImpl.cpp \ - PortImpl.hpp \ - PostProcessor.cpp \ - PostProcessor.hpp \ - ProcessContext.hpp \ - ProcessSlave.cpp \ - ProcessSlave.hpp \ - QueuedEngineInterface.cpp \ - QueuedEngineInterface.hpp \ - QueuedEvent.cpp \ - QueuedEvent.hpp \ - QueuedEventSource.cpp \ - QueuedEventSource.hpp \ - Responder.hpp \ - ThreadManager.hpp \ - TransportNode.cpp \ - TransportNode.hpp \ - engine.cpp \ - engine.hpp \ - events.hpp \ - events/AllNotesOffEvent.cpp \ - events/AllNotesOffEvent.hpp \ - events/ClearPatchEvent.cpp \ - events/ClearPatchEvent.hpp \ - events/ConnectionEvent.cpp \ - events/ConnectionEvent.hpp \ - events/CreateNodeEvent.cpp \ - events/CreateNodeEvent.hpp \ - events/CreatePatchEvent.cpp \ - events/CreatePatchEvent.hpp \ - events/CreatePortEvent.cpp \ - events/CreatePortEvent.hpp \ - events/DeactivateEvent.cpp \ - events/DeactivateEvent.hpp \ - events/DestroyEvent.cpp \ - events/DestroyEvent.hpp \ - events/DisconnectAllEvent.cpp \ - events/DisconnectAllEvent.hpp \ - events/DisconnectionEvent.cpp \ - events/DisconnectionEvent.hpp \ - events/EnablePatchEvent.cpp \ - events/EnablePatchEvent.hpp \ - events/LoadPluginsEvent.cpp \ - events/LoadPluginsEvent.hpp \ - events/MidiLearnEvent.cpp \ - events/MidiLearnEvent.hpp \ - events/NoteEvent.cpp \ - events/NoteEvent.hpp \ - events/PingQueuedEvent.hpp \ - events/RegisterClientEvent.cpp \ - events/RegisterClientEvent.hpp \ - events/RenameEvent.cpp \ - events/RenameEvent.hpp \ - events/RequestAllObjectsEvent.cpp \ - events/RequestAllObjectsEvent.hpp \ - events/RequestMetadataEvent.cpp \ - events/RequestMetadataEvent.hpp \ - events/RequestObjectEvent.cpp \ - events/RequestObjectEvent.hpp \ - events/RequestPluginEvent.cpp \ - events/RequestPluginEvent.hpp \ - events/RequestPluginsEvent.cpp \ - events/RequestPluginsEvent.hpp \ - events/RequestPortValueEvent.cpp \ - events/RequestPortValueEvent.hpp \ - events/SendPortActivityEvent.cpp \ - events/SendPortActivityEvent.hpp \ - events/SendPortValueEvent.cpp \ - events/SendPortValueEvent.hpp \ - events/SetMetadataEvent.cpp \ - events/SetMetadataEvent.hpp \ - events/SetPolyphonicEvent.cpp \ - events/SetPolyphonicEvent.hpp \ - events/SetPolyphonyEvent.cpp \ - events/SetPolyphonyEvent.hpp \ - events/SetPortValueEvent.cpp \ - events/SetPortValueEvent.hpp \ - events/UnregisterClientEvent.cpp \ - events/UnregisterClientEvent.hpp \ - jack_compat.h \ - lv2_contexts.h \ - tuning.hpp \ - types.hpp \ - util.hpp - -if WITH_LADSPA -libingen_engine_la_SOURCES += \ - LADSPANode.hpp \ - LADSPANode.cpp -endif - -if WITH_LV2 -libingen_engine_la_SOURCES += \ - LV2Node.hpp \ - LV2Node.cpp -endif - -if WITH_SOUP -libingen_engine_la_SOURCES += \ - HTTPEngineReceiver.cpp \ - HTTPEngineReceiver.hpp -endif - - - diff --git a/src/libs/engine/MessageContext.cpp b/src/libs/engine/MessageContext.cpp deleted file mode 100644 index 30f04b05..00000000 --- a/src/libs/engine/MessageContext.cpp +++ /dev/null @@ -1,32 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2008 Dave Robillard <http://drobilla.net> - * - * 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 "MessageContext.hpp" -#include "NodeImpl.hpp" - -namespace Ingen { - -void -MessageContext::run(NodeImpl* node) -{ - uint32_t outputs; - node->message_process(*this, &outputs); - - // Don't care what the plugin output, yet... -} - -} // namespace Ingen diff --git a/src/libs/engine/MessageContext.hpp b/src/libs/engine/MessageContext.hpp deleted file mode 100644 index 31531521..00000000 --- a/src/libs/engine/MessageContext.hpp +++ /dev/null @@ -1,51 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007-2008 Dave Robillard <http://drobilla.net> - * - * 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 MESSAGECONTEXT_H -#define MESSAGECONTEXT_H - -#include "EventSink.hpp" -#include "Context.hpp" - -namespace Ingen { - -class NodeImpl; - -/** Context of a message_process() call. - * - * The message context is a non-hard-realtime thread used to execute things - * that can take too long to execute in an audio thread, and do sloppy timed - * event propagation and scheduling. Interface to plugins via the - * LV2 contexts extension. - * - * \ingroup engine - */ -class MessageContext : public Context -{ -public: - MessageContext(Engine& engine) - : Context(engine, MESSAGE) - {} - - void run(NodeImpl* node); -}; - - -} // namespace Ingen - -#endif // MESSAGECONTEXT_H - diff --git a/src/libs/engine/MidiControlNode.cpp b/src/libs/engine/MidiControlNode.cpp deleted file mode 100644 index bfe0e57e..00000000 --- a/src/libs/engine/MidiControlNode.cpp +++ /dev/null @@ -1,141 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard <http://drobilla.net> - * - * 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 <math.h> -#include <raul/midi_events.h> -#include "MidiControlNode.hpp" -#include "PostProcessor.hpp" -#include "MidiLearnEvent.hpp" -#include "InputPort.hpp" -#include "OutputPort.hpp" -#include "InternalPlugin.hpp" -#include "AudioBuffer.hpp" -#include "ProcessContext.hpp" -#include "EventBuffer.hpp" -#include "util.hpp" - -namespace Ingen { - - -MidiControlNode::MidiControlNode(const string& path, - bool polyphonic, - PatchImpl* parent, - SampleRate srate, - size_t buffer_size) - : NodeBase(new InternalPlugin(NS_INGEN "control_node", "controller", "MIDI Controller") - , path, false, parent, srate, buffer_size) - , _learning(false) -{ - _ports = new Raul::Array<PortImpl*>(6); - - _midi_in_port = new InputPort(this, "input", 0, 1, DataType::EVENT, Atom(), _buffer_size); - _ports->at(0) = _midi_in_port; - - _param_port = new InputPort(this, "controller", 1, 1, DataType::CONTROL, 0.0f, 1); - _param_port->set_variable("ingen:minimum", 0.0f); - _param_port->set_variable("ingen:maximum", 127.0f); - _param_port->set_variable("ingen:integer", true); - _ports->at(1) = _param_port; - - _log_port = new InputPort(this, "logarithmic", 2, 1, DataType::CONTROL, 0.0f, 1); - _log_port->set_variable("ingen:toggled", true); - _ports->at(2) = _log_port; - - _min_port = new InputPort(this, "minimum", 3, 1, DataType::CONTROL, 0.0f, 1); - _ports->at(3) = _min_port; - - _max_port = new InputPort(this, "maximum", 4, 1, DataType::CONTROL, 1.0f, 1); - _ports->at(4) = _max_port; - - _audio_port = new OutputPort(this, "ar_output", 5, 1, DataType::AUDIO, 0.0f, _buffer_size); - _ports->at(5) = _audio_port; -} - - -void -MidiControlNode::process(ProcessContext& context) -{ - NodeBase::pre_process(context); - - uint32_t frames = 0; - uint32_t subframes = 0; - uint16_t type = 0; - uint16_t size = 0; - uint8_t* buf = NULL; - - EventBuffer* const midi_in = (EventBuffer*)_midi_in_port->buffer(0); - assert(midi_in->this_nframes() == context.nframes()); - - while (midi_in->get_event(&frames, &subframes, &type, &size, &buf)) { - // FIXME: type - if (size >= 3 && (buf[0] & 0xF0) == MIDI_CMD_CONTROL) - control(context, buf[1], buf[2], frames + context.start()); - - midi_in->increment(); - } - - NodeBase::post_process(context); -} - - -void -MidiControlNode::control(ProcessContext& context, uchar control_num, uchar val, FrameTime time) -{ - assert(time - context.start() < _buffer_size); - - Sample scaled_value; - - const Sample nval = (val / 127.0f); // normalized [0, 1] - - if (_learning) { - assert(false); // FIXME FIXME FIXME -#if 0 - assert(_learn_event != NULL); - _param_port->set_value(control_num, offset); - assert(_param_port->buffer(0)->value_at(0) == control_num); - _learn_event->set_value(control_num); - _learn_event->execute(offset); - //Engine::instance().post_processor()->push(_learn_event); - //Engine::instance().post_processor()->whip(); - _learning = false; - _learn_event = NULL; -#endif - } - - const Sample min_port_val = ((AudioBuffer*)_min_port->buffer(0))->value_at(0); - const Sample max_port_val = ((AudioBuffer*)_max_port->buffer(0))->value_at(0); - const Sample log_port_val = ((AudioBuffer*)_log_port->buffer(0))->value_at(0); - - if (log_port_val > 0.0f) { - // haaaaack, stupid negatives and logarithms - Sample log_offset = 0; - if (min_port_val < 0) - log_offset = fabs(min_port_val); - const Sample min = log(min_port_val + 1 + log_offset); - const Sample max = log(max_port_val + 1 + log_offset); - scaled_value = expf(nval * (max - min) + min) - 1 - log_offset; - } else { - scaled_value = ((nval) * (max_port_val - min_port_val)) + min_port_val; - } - - if (control_num == ((AudioBuffer*)_param_port->buffer(0))->value_at(0)) - ((AudioBuffer*)_audio_port->buffer(0))->set_value(scaled_value, context.start(), time); -} - - -} // namespace Ingen - diff --git a/src/libs/engine/MidiControlNode.hpp b/src/libs/engine/MidiControlNode.hpp deleted file mode 100644 index 2f0496a3..00000000 --- a/src/libs/engine/MidiControlNode.hpp +++ /dev/null @@ -1,65 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard <http://drobilla.net> - * - * 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 MIDICONTROLNODE_H -#define MIDICONTROLNODE_H - -#include <string> -#include "NodeBase.hpp" - -namespace Ingen { - -class MidiLearnResponseEvent; -class InputPort; -class OutputPort; - - -/** MIDI control input node. - * - * Creating one of these nodes is how a user makes "MIDI Bindings". Note that - * this node will always be monophonic, the poly parameter is ignored. - * - * \ingroup engine - */ -class MidiControlNode : public NodeBase -{ -public: - MidiControlNode(const std::string& path, bool polyphonic, PatchImpl* parent, SampleRate srate, size_t buffer_size); - - void process(ProcessContext& context); - - void control(ProcessContext& context, uchar control_num, uchar val, FrameTime time); - - void learn(MidiLearnResponseEvent* ev) { _learning = true; _learn_event = ev; } - -private: - bool _learning; - - InputPort* _midi_in_port; - InputPort* _param_port; - InputPort* _log_port; - InputPort* _min_port; - InputPort* _max_port; - OutputPort* _audio_port; - - MidiLearnResponseEvent* _learn_event; -}; - - -} // namespace Ingen - -#endif // MIDICONTROLNODE_H diff --git a/src/libs/engine/MidiDriver.hpp b/src/libs/engine/MidiDriver.hpp deleted file mode 100644 index e268124b..00000000 --- a/src/libs/engine/MidiDriver.hpp +++ /dev/null @@ -1,100 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard <http://drobilla.net> - * - * 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 MIDIDRIVER_H -#define MIDIDRIVER_H - -#include <iostream> -#include "types.hpp" -#include "Driver.hpp" -#include "EventBuffer.hpp" -#include "ProcessContext.hpp" - -namespace Ingen { - -class ProcessContext; - - -/** Midi driver abstract base class. - * - * \ingroup engine - */ -class MidiDriver : public Driver -{ -public: - MidiDriver() : Driver(DataType::EVENT) {} - - /** Prepare input for the specified (upcoming) cycle. - * - * Realtime safe, run in audio thread before executing the graph for a cycle. - */ - virtual void pre_process(ProcessContext& context) = 0; - - /** Prepare output for the specified (just completed) cycle. - * - * Realtime safe, run in audio thread after executing the graph for a cycle. - */ - virtual void post_process(ProcessContext& context) = 0; -}; - - - -/** Dummy MIDIDriver. - * - * Not abstract, all functions are dummies. One of these will be allocated and - * "used" if no working MIDI driver is loaded. (Doing it this way as opposed to - * just making MidiDriver have dummy functions makes sure any existing MidiDriver - * derived class actually implements the required functions). - * - * \ingroup engine - */ -class DummyMidiDriver : public MidiDriver -{ -public: - DummyMidiDriver() { - std::cout << "[DummyMidiDriver] Started Dummy MIDI driver." << std::endl; - } - - ~DummyMidiDriver() {} - - void activate() {} - void deactivate() {} - - bool is_activated() const { return false; } - bool is_enabled() const { return false; } - - void enable() {} - void disable() {} - - DriverPort* create_port(DuplexPort* patch_port) { return NULL; } - - DriverPort* driver_port(const Raul::Path& path) { return NULL; } - - DriverPort* new_port(DuplexPort* patch_port) { return NULL; } - - void add_port(DriverPort* port) {} - DriverPort* remove_port(const Raul::Path& path) { return NULL; } - - void pre_process(ProcessContext& context) {} - void post_process(ProcessContext& context) {} -}; - - - -} // namespace Ingen - -#endif // MIDIDRIVER_H diff --git a/src/libs/engine/MidiNoteNode.cpp b/src/libs/engine/MidiNoteNode.cpp deleted file mode 100644 index ae7a7f0e..00000000 --- a/src/libs/engine/MidiNoteNode.cpp +++ /dev/null @@ -1,390 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard <http://drobilla.net> - * - * 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 <raul/Array.hpp> -#include <raul/Maid.hpp> -#include <raul/midi_events.h> -#include <cmath> -#include <iostream> -#include "AudioBuffer.hpp" -#include "AudioDriver.hpp" -#include "InputPort.hpp" -#include "InternalPlugin.hpp" -#include "EventBuffer.hpp" -#include "MidiNoteNode.hpp" -#include "OutputPort.hpp" -#include "PatchImpl.hpp" -#include "ProcessContext.hpp" -#include "util.hpp" - -using namespace std; - -namespace Ingen { - - -MidiNoteNode::MidiNoteNode(const string& path, bool polyphonic, PatchImpl* parent, SampleRate srate, size_t buffer_size) - : NodeBase(new InternalPlugin(NS_INGEN "note_node", "note", "MIDI Note"), - path, polyphonic, parent, srate, buffer_size) - , _voices(new Raul::Array<Voice>(_polyphony)) - , _prepared_voices(NULL) - , _sustain(false) -{ - _ports = new Raul::Array<PortImpl*>(5); - - _midi_in_port = new InputPort(this, "input", 0, 1, DataType::EVENT, Atom(), _buffer_size); - _ports->at(0) = _midi_in_port; - - _freq_port = new OutputPort(this, "frequency", 1, _polyphony, DataType::AUDIO, 440.0f, _buffer_size); - _ports->at(1) = _freq_port; - - _vel_port = new OutputPort(this, "velocity", 2, _polyphony, DataType::AUDIO, 0.0f, _buffer_size); - _vel_port->set_variable("ingen:minimum", 0.0f); - _vel_port->set_variable("ingen:maximum", 1.0f); - _ports->at(2) = _vel_port; - - _gate_port = new OutputPort(this, "gate", 3, _polyphony, DataType::AUDIO, 0.0f, _buffer_size); - _gate_port->set_variable("ingen:toggled", true); - _ports->at(3) = _gate_port; - - _trig_port = new OutputPort(this, "trigger", 4, _polyphony, DataType::AUDIO, 0.0f, _buffer_size); - _trig_port->set_variable("ingen:toggled", true); - _ports->at(4) = _trig_port; -} - - -MidiNoteNode::~MidiNoteNode() -{ - delete _voices; -} - - -bool -MidiNoteNode::prepare_poly(uint32_t poly) -{ - if (!_polyphonic) - return true; - - NodeBase::prepare_poly(poly); - - if (_prepared_voices && poly <= _prepared_voices->size()) - return true; - - _prepared_voices = new Raul::Array<Voice>(poly, *_voices); - - return true; -} - - -bool -MidiNoteNode::apply_poly(Raul::Maid& maid, uint32_t poly) -{ - if (!_polyphonic) - return true; - - NodeBase::apply_poly(maid, poly); - - if (_prepared_voices) { - assert(poly <= _prepared_voices->size()); - maid.push(_voices); - _voices = _prepared_voices; - _prepared_voices = NULL; - } - - _polyphony = poly; - assert(_voices->size() >= _polyphony); - - return true; -} - - -void -MidiNoteNode::process(ProcessContext& context) -{ - NodeBase::pre_process(context); - - uint32_t frames = 0; - uint32_t subframes = 0; - uint16_t type = 0; - uint16_t size = 0; - unsigned char* buf = NULL; - - EventBuffer* const midi_in = (EventBuffer*)_midi_in_port->buffer(0); - assert(midi_in->this_nframes() == context.nframes()); - - //cerr << path() << " # input events: " << midi_in->event_count() << endl; - - if (midi_in->event_count() > 0) - while (midi_in->get_event(&frames, &subframes, &type, &size, &buf)) { - - /*cout << "EVENT TYPE " << type << " @ " << frames << "." << subframes << ": "; - for (uint16_t i = 0; i < size; ++i) - cout << (int)((char)buf[i]) << " "; - cout << endl;*/ - - const FrameTime time = context.start() + (FrameTime)frames; - - if (size >= 3) { - switch (buf[0] & 0xF0) { - case MIDI_CMD_NOTE_ON: - if (buf[2] == 0) - note_off(context, buf[1], time); - else - note_on(context, buf[1], buf[2], time); - break; - case MIDI_CMD_NOTE_OFF: - note_off(context, buf[1], time); - break; - case MIDI_CMD_CONTROL: - switch (buf[1]) { - case MIDI_CTL_ALL_NOTES_OFF: - case MIDI_CTL_ALL_SOUNDS_OFF: - all_notes_off(context, time); - break; - case MIDI_CTL_SUSTAIN: - if (buf[2] > 63) - sustain_on(context, time); - else - sustain_off(context, time); - break; - case MIDI_CMD_BENDER: - // ? - break; - default: - //cerr << "Ignored controller " << buf[1] << endl; - break; - } - break; - default: - //fprintf(stderr, "Unknown (size %d) MIDI event %X\n", size, buf[0]); - break; - } - } else { - //fprintf(stderr, "Unknown (size %d) MIDI event %X\n", size, buf[0]); - } - - if (midi_in->increment() == midi_in->this_nframes()) - break; - } - - NodeBase::post_process(context); -} - - -void -MidiNoteNode::note_on(ProcessContext& context, uchar note_num, uchar velocity, FrameTime time) -{ - assert(time >= context.start() && time <= context.end()); - assert(time - context.start() < _buffer_size); - assert(note_num <= 127); - - Key* key = &_keys[note_num]; - Voice* voice = NULL; - uint32_t voice_num = 0; - - if (key->state != Key::OFF) { - //cerr << "[MidiNoteNode] Double midi note received" << endl; - return; - } - - // Look for free voices - for (uint32_t i=0; i < _polyphony; ++i) { - if ((*_voices)[i].state == Voice::Voice::FREE) { - voice = &(*_voices)[i]; - voice_num = i; - break; - } - } - - // If we didn't find a free one, steal the oldest - if (voice == NULL) { - voice_num = 0; - voice = &(*_voices)[0]; - jack_nframes_t oldest_time = (*_voices)[0].time; - for (uint32_t i=1; i < _polyphony; ++i) { - if ((*_voices)[i].time < oldest_time) { - voice = &(*_voices)[i]; - voice_num = i; - oldest_time = voice->time; - } - } - } - assert(voice != NULL); - assert(voice == &(*_voices)[voice_num]); - - /*cerr << "[MidiNoteNode] Note " << (int)note_num << " on @ " << time - << ". Voice " << voice_num << " / " << _polyphony << endl;*/ - - // Update stolen key, if applicable - if (voice->state == Voice::Voice::ACTIVE) { - assert(_keys[voice->note].state == Key::ON_ASSIGNED); - assert(_keys[voice->note].voice == voice_num); - _keys[voice->note].state = Key::Key::ON_UNASSIGNED; - //cerr << "[MidiNoteNode] Stole voice " << voice_num << endl; - } - - // Store key information for later reallocation on note off - key->state = Key::Key::ON_ASSIGNED; - key->voice = voice_num; - key->time = time; - - // Trigger voice - voice->state = Voice::Voice::ACTIVE; - voice->note = note_num; - voice->time = time; - - assert(_keys[voice->note].state == Key::Key::ON_ASSIGNED); - assert(_keys[voice->note].voice == voice_num); - - ((AudioBuffer*)_freq_port->buffer(voice_num))->set_value(note_to_freq(note_num), context.start(), time); - ((AudioBuffer*)_vel_port->buffer(voice_num))->set_value(velocity/127.0, context.start(), time); - ((AudioBuffer*)_gate_port->buffer(voice_num))->set_value(1.0f, context.start(), time); - - // trigger (one sample) - ((AudioBuffer*)_trig_port->buffer(voice_num))->set_value(1.0f, context.start(), time); - ((AudioBuffer*)_trig_port->buffer(voice_num))->set_value(0.0f, context.start(), time + 1); - - assert(key->state == Key::Key::ON_ASSIGNED); - assert(voice->state == Voice::Voice::ACTIVE); - assert(key->voice == voice_num); - assert((*_voices)[key->voice].note == note_num); -} - - -void -MidiNoteNode::note_off(ProcessContext& context, uchar note_num, FrameTime time) -{ - assert(time >= context.start() && time <= context.end()); - assert(time - context.start() < _buffer_size); - - Key* key = &_keys[note_num]; - - //cerr << "[MidiNoteNode] Note " << (int)note_num << " off @ " << time << endl; - - if (key->state == Key::ON_ASSIGNED) { - // Assigned key, turn off voice and key - if ((*_voices)[key->voice].state == Voice::ACTIVE) { - assert((*_voices)[key->voice].note == note_num); - - if ( ! _sustain) { - //cerr << "... free voice " << key->voice << endl; - free_voice(context, key->voice, time); - } else { - //cerr << "... hold voice " << key->voice << endl; - (*_voices)[key->voice].state = Voice::HOLDING; - } - - } else { -#ifndef NDEBUG - cerr << "WARNING: Assigned key, but voice not active" << endl; -#endif - } - } - - key->state = Key::OFF; -} - - -void -MidiNoteNode::free_voice(ProcessContext& context, uint32_t voice, FrameTime time) -{ - assert(time >= context.start() && time <= context.end()); - assert(time - context.start() < _buffer_size); - - // Find a key to reassign to the freed voice (the newest, if there is one) - Key* replace_key = NULL; - uchar replace_key_num = 0; - - for (uchar i = 0; i <= 127; ++i) { - if (_keys[i].state == Key::ON_UNASSIGNED) { - if (replace_key == NULL || _keys[i].time > replace_key->time) { - replace_key = &_keys[i]; - replace_key_num = i; - } - } - } - - if (replace_key != NULL) { // Found a key to assign to freed voice - assert(&_keys[replace_key_num] == replace_key); - assert(replace_key->state == Key::ON_UNASSIGNED); - - // Change the freq but leave the gate high and don't retrigger - ((AudioBuffer*)_freq_port->buffer(voice))->set_value(note_to_freq(replace_key_num), context.start(), time); - - replace_key->state = Key::ON_ASSIGNED; - replace_key->voice = voice; - _keys[(*_voices)[voice].note].state = Key::ON_UNASSIGNED; - (*_voices)[voice].note = replace_key_num; - (*_voices)[voice].state = Voice::ACTIVE; - } else { - // No new note for voice, deactivate (set gate low) - //cerr << "[MidiNoteNode] Note off. Key " << (int)note_num << ", Voice " << voice << " Killed" << endl; - ((AudioBuffer*)_gate_port->buffer(voice))->set_value(0.0f, context.start(), time); - (*_voices)[voice].state = Voice::FREE; - } -} - - -void -MidiNoteNode::all_notes_off(ProcessContext& context, FrameTime time) -{ - assert(time >= context.start() && time <= context.end()); - assert(time - context.start() < _buffer_size); - - //cerr << "All notes off @ " << offset << endl; - - // FIXME: set all keys to Key::OFF? - - for (uint32_t i = 0; i < _polyphony; ++i) { - ((AudioBuffer*)_gate_port->buffer(i))->set_value(0.0f, context.start(), time); - (*_voices)[i].state = Voice::FREE; - } -} - - -float -MidiNoteNode::note_to_freq(int num) -{ - static const float A4 = 440.0f; - if (num >= 0 && num <= 119) - return A4 * powf(2.0f, (float)(num - 57.0f) / 12.0f); - return 1.0f; // Some LADSPA plugins don't like freq=0 -} - - -void -MidiNoteNode::sustain_on(ProcessContext& context, FrameTime time) -{ - _sustain = true; -} - - -void -MidiNoteNode::sustain_off(ProcessContext& context, FrameTime time) -{ - assert(time >= context.start() && time <= context.end()); - assert(time - context.start() < _buffer_size); - - _sustain = false; - - for (uint32_t i=0; i < _polyphony; ++i) - if ((*_voices)[i].state == Voice::HOLDING) - free_voice(context, i, time); -} - - -} // namespace Ingen - diff --git a/src/libs/engine/MidiNoteNode.hpp b/src/libs/engine/MidiNoteNode.hpp deleted file mode 100644 index eebcbda6..00000000 --- a/src/libs/engine/MidiNoteNode.hpp +++ /dev/null @@ -1,88 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard <http://drobilla.net> - * - * 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 MIDINOTENODE_H -#define MIDINOTENODE_H - -#include <string> -#include "types.hpp" -#include "NodeBase.hpp" - -namespace Ingen { - -class InputPort; -class OutputPort; - - -/** MIDI note input node. - * - * For pitched instruments like keyboard, etc. - * - * \ingroup engine - */ -class MidiNoteNode : public NodeBase -{ -public: - MidiNoteNode(const std::string& path, bool polyphonic, PatchImpl* parent, SampleRate srate, size_t buffer_size); - ~MidiNoteNode(); - - bool prepare_poly(uint32_t poly); - bool apply_poly(Raul::Maid& maid, uint32_t poly); - - void process(ProcessContext& context); - - void note_on(ProcessContext& context, uchar note_num, uchar velocity, FrameTime time); - void note_off(ProcessContext& context, uchar note_num, FrameTime time); - void all_notes_off(ProcessContext& context, FrameTime time); - - void sustain_on(ProcessContext& context, FrameTime time); - void sustain_off(ProcessContext& context, FrameTime time); - -private: - /** Key, one for each key on the keyboard */ - struct Key { - enum State { OFF, ON_ASSIGNED, ON_UNASSIGNED }; - Key() : state(OFF), voice(0), time(0) {} - State state; uint32_t voice; SampleCount time; - }; - - /** Voice, one of these always exists for each voice */ - struct Voice { - enum State { FREE, ACTIVE, HOLDING }; - Voice() : state(FREE), note(0) {} - State state; uchar note; SampleCount time; - }; - - float note_to_freq(int num); - void free_voice(ProcessContext& context, uint32_t voice, FrameTime time); - - Raul::Array<Voice>* _voices; - Raul::Array<Voice>* _prepared_voices; - Key _keys[128]; - bool _sustain; ///< Whether or not hold pedal is depressed - - InputPort* _midi_in_port; - OutputPort* _freq_port; - OutputPort* _vel_port; - OutputPort* _gate_port; - OutputPort* _trig_port; -}; - - -} // namespace Ingen - -#endif // MIDINOTENODE_H diff --git a/src/libs/engine/MidiTriggerNode.cpp b/src/libs/engine/MidiTriggerNode.cpp deleted file mode 100644 index aa2c272f..00000000 --- a/src/libs/engine/MidiTriggerNode.cpp +++ /dev/null @@ -1,135 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard <http://drobilla.net> - * - * 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 <cmath> -#include <raul/midi_events.h> -#include "MidiTriggerNode.hpp" -#include "AudioBuffer.hpp" -#include "InputPort.hpp" -#include "OutputPort.hpp" -#include "InternalPlugin.hpp" -#include "ProcessContext.hpp" -#include "EventBuffer.hpp" -#include "util.hpp" - -using namespace std; - -namespace Ingen { - - -MidiTriggerNode::MidiTriggerNode(const string& path, bool polyphonic, PatchImpl* parent, SampleRate srate, size_t buffer_size) - : NodeBase(new InternalPlugin(NS_INGEN "trigger_node", "trigger", "MIDI Trigger"), - path, false, parent, srate, buffer_size) -{ - _ports = new Raul::Array<PortImpl*>(5); - - _midi_in_port = new InputPort(this, "input", 0, 1, DataType::EVENT, Atom(), _buffer_size); - _ports->at(0) = _midi_in_port; - - _note_port = new InputPort(this, "note", 1, 1, DataType::CONTROL, 60.0f, 1); - _note_port->set_variable("ingen:minimum", 0.0f); - _note_port->set_variable("ingen:maximum", 127.0f); - _note_port->set_variable("ingen:integer", true); - _ports->at(1) = _note_port; - - _gate_port = new OutputPort(this, "gate", 2, 1, DataType::AUDIO, 0.0f, _buffer_size); - _ports->at(2) = _gate_port; - - _trig_port = new OutputPort(this, "trigger", 3, 1, DataType::AUDIO, 0.0f, _buffer_size); - _ports->at(3) = _trig_port; - - _vel_port = new OutputPort(this, "velocity", 4, 1, DataType::AUDIO, 0.0f, _buffer_size); - _ports->at(4) = _vel_port; -} - - -void -MidiTriggerNode::process(ProcessContext& context) -{ - NodeBase::pre_process(context); - - uint32_t frames = 0; - uint32_t subframes = 0; - uint16_t type = 0; - uint16_t size = 0; - uint8_t* buf = NULL; - - EventBuffer* const midi_in = (EventBuffer*)_midi_in_port->buffer(0); - assert(midi_in->this_nframes() == context.nframes()); - - while (midi_in->get_event(&frames, &subframes, &type, &size, &buf)) { - const FrameTime time = context.start() + (FrameTime)frames; - - if (size >= 3) { - switch (buf[0] & 0xF0) { - case MIDI_CMD_NOTE_ON: - if (buf[2] == 0) - note_off(context, buf[1], time); - else - note_on(context, buf[1], buf[2], time); - break; - case MIDI_CMD_NOTE_OFF: - note_off(context, buf[1], time); - break; - case MIDI_CMD_CONTROL: - if (buf[1] == MIDI_CTL_ALL_NOTES_OFF - || buf[1] == MIDI_CTL_ALL_SOUNDS_OFF) - ((AudioBuffer*)_gate_port->buffer(0))->set_value(0.0f, context.start(), time); - default: - break; - } - } - - midi_in->increment(); - } - - NodeBase::post_process(context); -} - - -void -MidiTriggerNode::note_on(ProcessContext& context, uchar note_num, uchar velocity, FrameTime time) -{ - assert(time >= context.start() && time <= context.end()); - assert(time - context.start() < _buffer_size); - - /*cerr << "[MidiTriggerNode] " << path() << " Note " << (int)note_num << " on @ " << time << endl;*/ - - Sample filter_note = ((AudioBuffer*)_note_port->buffer(0))->value_at(0); - if (filter_note >= 0.0 && filter_note < 127.0 && (note_num == (uchar)filter_note)) { - ((AudioBuffer*)_gate_port->buffer(0))->set_value(1.0f, context.start(), time); - ((AudioBuffer*)_trig_port->buffer(0))->set_value(1.0f, context.start(), time); - ((AudioBuffer*)_trig_port->buffer(0))->set_value(0.0f, context.start(), time + 1); - ((AudioBuffer*)_vel_port->buffer(0))->set_value(velocity / 127.0f, context.start(), time); - assert(((AudioBuffer*)_trig_port->buffer(0))->data()[time - context.start()] == 1.0f); - } -} - - -void -MidiTriggerNode::note_off(ProcessContext& context, uchar note_num, FrameTime time) -{ - assert(time >= context.start() && time <= context.end()); - assert(time - context.start() < _buffer_size); - - if (note_num == lrintf(((AudioBuffer*)_note_port->buffer(0))->value_at(0))) - ((AudioBuffer*)_gate_port->buffer(0))->set_value(0.0f, context.start(), time); -} - - -} // namespace Ingen - diff --git a/src/libs/engine/MidiTriggerNode.hpp b/src/libs/engine/MidiTriggerNode.hpp deleted file mode 100644 index ba96589b..00000000 --- a/src/libs/engine/MidiTriggerNode.hpp +++ /dev/null @@ -1,61 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard <http://drobilla.net> - * - * 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 MIDITRIGGERNODE_H -#define MIDITRIGGERNODE_H - -#include <string> -#include "NodeBase.hpp" - -namespace Ingen { - -class InputPort; -class OutputPort; - - -/** MIDI trigger input node. - * - * Just has a gate, for drums etc. A control port is used to select - * which note number is responded to. - * - * Note that this node is always monophonic, the poly parameter is ignored. - * (Should that change?) - * - * \ingroup engine - */ -class MidiTriggerNode : public NodeBase -{ -public: - MidiTriggerNode(const std::string& path, bool polyphonic, PatchImpl* parent, SampleRate srate, size_t buffer_size); - - void process(ProcessContext& context); - - void note_on(ProcessContext& context, uchar note_num, uchar velocity, FrameTime time); - void note_off(ProcessContext& context, uchar note_num, FrameTime time); - -private: - InputPort* _midi_in_port; - InputPort* _note_port; - OutputPort* _gate_port; - OutputPort* _trig_port; - OutputPort* _vel_port; -}; - - -} // namespace Ingen - -#endif // MIDITRIGGERNODE_H diff --git a/src/libs/engine/NodeBase.cpp b/src/libs/engine/NodeBase.cpp deleted file mode 100644 index bb4f0e5c..00000000 --- a/src/libs/engine/NodeBase.cpp +++ /dev/null @@ -1,230 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard <http://drobilla.net> - * - * 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 "NodeBase.hpp" -#include <cassert> -#include <iostream> -#include <stdint.h> -#include <raul/List.hpp> -#include <raul/Array.hpp> -#include "util.hpp" -#include "PluginImpl.hpp" -#include "ClientBroadcaster.hpp" -#include "PortImpl.hpp" -#include "PatchImpl.hpp" -#include "EngineStore.hpp" -#include "ThreadManager.hpp" - -using namespace std; - -namespace Ingen { - - -NodeBase::NodeBase(PluginImpl* plugin, const string& name, bool polyphonic, PatchImpl* parent, SampleRate srate, size_t buffer_size) - : NodeImpl(parent, name, polyphonic) - , _plugin(plugin) - , _polyphony((polyphonic && parent) ? parent->internal_polyphony() : 1) - , _srate(srate) - , _buffer_size(buffer_size) - , _activated(false) - , _traversed(false) - , _input_ready(1) - , _process_lock(0) - , _n_inputs_ready(0) - , _ports(NULL) - , _providers(new Raul::List<NodeImpl*>()) - , _dependants(new Raul::List<NodeImpl*>()) -{ - assert(_plugin); - assert(_polyphony > 0); - assert(_parent == NULL || (_polyphony == parent->internal_polyphony() || _polyphony == 1)); -} - - -NodeBase::~NodeBase() -{ - if (_activated) - deactivate(); - - delete _providers; - delete _dependants; -} - - -Port* -NodeBase::port(uint32_t index) const -{ - return (*_ports)[index]; -} - - -const Plugin* -NodeBase::plugin() const -{ - return _plugin; -} - - -void -NodeBase::activate() -{ - assert(ThreadManager::current_thread_id() == THREAD_PRE_PROCESS); - assert(!_activated); - _activated = true; -} - - -void -NodeBase::deactivate() -{ - // FIXME: Not true witn monolithic GUI/engine - //assert(ThreadManager::current_thread_id() == THREAD_POST_PROCESS); - assert(_activated); - _activated = false; -} - - -bool -NodeBase::prepare_poly(uint32_t poly) -{ - assert(ThreadManager::current_thread_id() == THREAD_PRE_PROCESS); - - if (!_polyphonic) - return true; - - if (_ports) - for (size_t i=0; i < _ports->size(); ++i) - _ports->at(i)->prepare_poly(poly); - - return true; -} - - -bool -NodeBase::apply_poly(Raul::Maid& maid, uint32_t poly) -{ - assert(ThreadManager::current_thread_id() == THREAD_PROCESS); - - if (!_polyphonic) - return true; - - for (size_t i=0; i < num_ports(); ++i) { - _ports->at(i)->apply_poly(maid, poly); - assert(_ports->at(i)->poly() == poly); - } - - for (uint32_t i=0; i < num_ports(); ++i) - for (uint32_t j=0; j < _polyphony; ++j) - set_port_buffer(j, i, _ports->at(i)->buffer(j)); - - return true; -} - - -void -NodeBase::set_buffer_size(size_t size) -{ - assert(ThreadManager::current_thread_id() == THREAD_PROCESS); - - _buffer_size = size; - - if (_ports) - for (size_t i=0; i < _ports->size(); ++i) - _ports->at(i)->set_buffer_size(size); -} - - -void -NodeBase::reset_input_ready() -{ - //cout << path() << " RESET" << endl; - _n_inputs_ready = 0; - _process_lock = 0; - _input_ready.reset(0); -} - - -bool -NodeBase::process_lock() -{ - return _process_lock.compare_and_exchange(0, 1); -} - - -void -NodeBase::process_unlock() -{ - _process_lock = 0; -} - - -void -NodeBase::wait_for_input(size_t num_providers) -{ - assert(ThreadManager::current_thread_id() == THREAD_PROCESS); - assert(_process_lock.get() == 1); - - while ((unsigned)_n_inputs_ready.get() < num_providers) { - //cout << path() << " WAITING " << _n_inputs_ready.get() << endl; - _input_ready.wait(); - //cout << path() << " CAUGHT SIGNAL" << endl; - //++_n_inputs_ready; - } - - //cout << path() << " READY" << endl; -} - - -void -NodeBase::signal_input_ready() -{ - assert(ThreadManager::current_thread_id() == THREAD_PROCESS); - //cout << path() << " SIGNAL" << endl; - ++_n_inputs_ready; - _input_ready.post(); -} - - -/** Prepare to run a cycle (in the audio thread) - */ -void -NodeBase::pre_process(ProcessContext& context) -{ - assert(ThreadManager::current_thread_id() == THREAD_PROCESS); - - // Mix down any ports with multiple inputs - for (size_t i=0; i < num_ports(); ++i) - _ports->at(i)->pre_process(context); -} - - -/** Prepare to run a cycle (in the audio thread) - */ -void -NodeBase::post_process(ProcessContext& context) -{ - assert(ThreadManager::current_thread_id() == THREAD_PROCESS); - - /* Write output ports */ - if (_ports) - for (size_t i=0; i < _ports->size(); ++i) - _ports->at(i)->post_process(context); -} - - -} // namespace Ingen - diff --git a/src/libs/engine/NodeBase.hpp b/src/libs/engine/NodeBase.hpp deleted file mode 100644 index e3710aa9..00000000 --- a/src/libs/engine/NodeBase.hpp +++ /dev/null @@ -1,132 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard <http://drobilla.net> - * - * 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 NODEBASE_H -#define NODEBASE_H - -#include "types.hpp" -#include <string> -#include <cstdlib> -#include <raul/Semaphore.hpp> -#include <raul/AtomicInt.hpp> -#include "interface/Port.hpp" -#include "NodeImpl.hpp" - -using std::string; - -namespace Ingen { - -class PluginImpl; -class PatchImpl; -class EngineStore; - -namespace Shared { - class ClientInterface; -} using Shared::ClientInterface; - - -/** Common implementation stuff for Node. - * - * Pretty much just attributes and getters/setters are here. - * - * \ingroup engine - */ -class NodeBase : public NodeImpl -{ -public: - NodeBase(PluginImpl* plugin, - const string& name, - bool poly, - PatchImpl* parent, - SampleRate rate, - size_t buffer_size); - - virtual ~NodeBase(); - - virtual void activate(); - virtual void deactivate(); - bool activated() { return _activated; } - - virtual bool prepare_poly(uint32_t poly); - virtual bool apply_poly(Raul::Maid& maid, uint32_t poly); - - virtual void reset_input_ready(); - virtual bool process_lock(); - virtual void process_unlock(); - virtual void wait_for_input(size_t num_providers); - virtual unsigned n_inputs_ready() const { return _n_inputs_ready.get(); } - - virtual void message_process(MessageContext& context, uint32_t* output) {} - - virtual void pre_process(ProcessContext& context); - virtual void process(ProcessContext& context) = 0; - virtual void post_process(ProcessContext& context); - - virtual void set_port_buffer(uint32_t voice, uint32_t port_num, Buffer* buf) {} - - virtual void set_buffer_size(size_t size); - - SampleRate sample_rate() const { return _srate; } - size_t buffer_size() const { return _buffer_size; } - uint32_t num_ports() const { return _ports ? _ports->size() : 0; } - uint32_t polyphony() const { return _polyphony; } - bool traversed() const { return _traversed; } - void traversed(bool b) { _traversed = b; } - - virtual Port* port(uint32_t index) const; - virtual PortImpl* port_impl(uint32_t index) const { return (*_ports)[index]; } - - /* These are NOT to be used in the audio thread! - * The providers and dependants in CompiledNode are for that - */ - - Raul::List<NodeImpl*>* providers() { return _providers; } - void providers(Raul::List<NodeImpl*>* l) { _providers = l; } - - Raul::List<NodeImpl*>* dependants() { return _dependants; } - void dependants(Raul::List<NodeImpl*>* l) { _dependants = l; } - - virtual const Plugin* plugin() const; - virtual PluginImpl* plugin_impl() const { return _plugin; } - virtual void plugin(PluginImpl* pi) { _plugin = pi; } - - /** A node's parent is always a patch, so static cast should be safe */ - inline PatchImpl* parent_patch() const { return (PatchImpl*)_parent; } - -protected: - virtual void signal_input_ready(); - - PluginImpl* _plugin; - - uint32_t _polyphony; - SampleRate _srate; - size_t _buffer_size; - bool _activated; - - bool _traversed; ///< Flag for process order algorithm - Raul::Semaphore _input_ready; ///< Parallelism: input ready signal - Raul::AtomicInt _process_lock; ///< Parallelism: Waiting on inputs 'lock' - Raul::AtomicInt _n_inputs_ready; ///< Parallelism: # input ready signals this cycle - Raul::Array<PortImpl*>* _ports; ///< Access in audio thread only - Raul::List<NodeImpl*>* _providers; ///< Nodes connected to this one's input ports - Raul::List<NodeImpl*>* _dependants; ///< Nodes this one's output ports are connected to -}; - - -} // namespace Ingen - -#endif // NODEBASE_H diff --git a/src/libs/engine/NodeFactory.cpp b/src/libs/engine/NodeFactory.cpp deleted file mode 100644 index c868d067..00000000 --- a/src/libs/engine/NodeFactory.cpp +++ /dev/null @@ -1,285 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard <http://drobilla.net> - * - * 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 CONFIG_H_PATH -#include <cstdlib> -#include <pthread.h> -#include <dirent.h> -#include <float.h> -#include <cmath> -#include <redlandmm/World.hpp> -#include "module/World.hpp" -#include "NodeFactory.hpp" -#include "ThreadManager.hpp" -#include "MidiNoteNode.hpp" -#include "MidiTriggerNode.hpp" -#include "MidiControlNode.hpp" -#include "TransportNode.hpp" -#include "PatchImpl.hpp" -#include "InternalPlugin.hpp" -#ifdef HAVE_LADSPA -#include "LADSPANode.hpp" -#include "LADSPAPlugin.hpp" -#endif -#ifdef HAVE_SLV2 -#include <slv2/slv2.h> -#include "LV2Plugin.hpp" -#include "LV2Node.hpp" -#endif - -using namespace std; - -namespace Ingen { - - -NodeFactory::NodeFactory(Ingen::Shared::World* world) - : _world(world) - , _has_loaded(false) -#ifdef HAVE_SLV2 - , _lv2_info(new LV2Info(world)) -#endif -{ -} - - -NodeFactory::~NodeFactory() -{ - for (Plugins::iterator i = _plugins.begin(); i != _plugins.end(); ++i) - if (i->second->type() != Plugin::Internal) - delete i->second; - - _plugins.clear(); -} - - -PluginImpl* -NodeFactory::plugin(const string& uri) -{ - const Plugins::const_iterator i = _plugins.find(uri); - return ((i != _plugins.end()) ? i->second : NULL); -} - - -/** DEPRECATED: Find a plugin by type, lib, label. - * - * Slow. Evil. Do not use. - */ -PluginImpl* -NodeFactory::plugin(const string& type, const string& lib, const string& label) -{ - if (type != "LADSPA" || lib == "" || label == "") - return NULL; - -#ifdef HAVE_LADSPA - for (Plugins::const_iterator i = _plugins.begin(); i != _plugins.end(); ++i) { - LADSPAPlugin* lp = dynamic_cast<LADSPAPlugin*>(i->second); - if (lp && lp->type_string() == type - && lp->library_name() == lib - && lp->label() == label) - return lp; - } -#endif - - cerr << "ERROR: Failed to find " << type << " plugin " << lib << " / " << label << endl; - - return NULL; -} - - -void -NodeFactory::load_plugins() -{ - assert(ThreadManager::current_thread_id() == THREAD_PRE_PROCESS); - - _world->rdf_world->mutex().lock(); - - // Only load if we havn't already, so every client connecting doesn't cause - // this (expensive!) stuff to happen. Not the best solution - would be nice - // if clients could refresh plugins list for whatever reason :/ - if (!_has_loaded) { - _plugins.clear(); // FIXME: assert empty? - - load_internal_plugins(); - -#ifdef HAVE_SLV2 - load_lv2_plugins(); -#endif - -#ifdef HAVE_LADSPA - load_ladspa_plugins(); -#endif - - _has_loaded = true; - } - - _world->rdf_world->mutex().unlock(); - - //cerr << "[NodeFactory] # Plugins: " << _plugins.size() << endl; -} - - -void -NodeFactory::load_internal_plugins() -{ - // This is a touch gross... - - PatchImpl* parent = new PatchImpl(*_world->local_engine, "dummy", 1, NULL, 1, 1, 1); - - NodeImpl* n = NULL; - n = new MidiNoteNode("foo", 1, parent, 1, 1); - _plugins.insert(make_pair(n->plugin_impl()->uri(), n->plugin_impl())); - delete n; - n = new MidiTriggerNode("foo", 1, parent, 1, 1); - _plugins.insert(make_pair(n->plugin_impl()->uri(), n->plugin_impl())); - delete n; - n = new MidiControlNode("foo", 1, parent, 1, 1); - _plugins.insert(make_pair(n->plugin_impl()->uri(), n->plugin_impl())); - delete n; - n = new TransportNode("foo", 1, parent, 1, 1); - _plugins.insert(make_pair(n->plugin_impl()->uri(), n->plugin_impl())); - delete n; - - delete parent; -} - - -#ifdef HAVE_SLV2 -/** Loads information about all LV2 plugins into internal plugin database. - */ -void -NodeFactory::load_lv2_plugins() -{ - SLV2Plugins plugins = slv2_world_get_all_plugins(_world->slv2_world); - - //cerr << "[NodeFactory] Found " << slv2_plugins_size(plugins) << " LV2 plugins:" << endl; - - for (unsigned i=0; i < slv2_plugins_size(plugins); ++i) { - - SLV2Plugin lv2_plug = slv2_plugins_get_at(plugins, i); - - const string uri(slv2_value_as_uri(slv2_plugin_get_uri(lv2_plug))); - -#ifndef NDEBUG - assert(_plugins.find(uri) == _plugins.end()); -#endif - - LV2Plugin* const plugin = new LV2Plugin(_lv2_info, uri); - - plugin->slv2_plugin(lv2_plug); - plugin->library_path(slv2_uri_to_path(slv2_value_as_uri( - slv2_plugin_get_library_uri(lv2_plug)))); - _plugins.insert(make_pair(uri, plugin)); - } - - slv2_plugins_free(_world->slv2_world, plugins); -} -#endif // HAVE_SLV2 - - -#ifdef HAVE_LADSPA -/** Loads information about all LADSPA plugins into internal plugin database. - */ -void -NodeFactory::load_ladspa_plugins() -{ - char* env_ladspa_path = getenv("LADSPA_PATH"); - string ladspa_path; - if (!env_ladspa_path) { - cerr << "[NodeFactory] LADSPA_PATH is empty. Assuming /usr/lib/ladspa:/usr/local/lib/ladspa:~/.ladspa" << endl; - ladspa_path = string("/usr/lib/ladspa:/usr/local/lib/ladspa:").append( - getenv("HOME")).append("/.ladspa"); - } else { - ladspa_path = env_ladspa_path; - } - - // Yep, this should use an sstream alright.. - while (ladspa_path != "") { - const string dir = ladspa_path.substr(0, ladspa_path.find(':')); - if (ladspa_path.find(':') != string::npos) - ladspa_path = ladspa_path.substr(ladspa_path.find(':')+1); - else - ladspa_path = ""; - - DIR* pdir = opendir(dir.c_str()); - if (pdir == NULL) { - //cerr << "[NodeFactory] Unreadable directory in LADSPA_PATH: " << dir.c_str() << endl; - continue; - } - - struct dirent* pfile; - while ((pfile = readdir(pdir))) { - - LADSPA_Descriptor_Function df = NULL; - LADSPA_Descriptor* descriptor = NULL; - - if (!strcmp(pfile->d_name, ".") || !strcmp(pfile->d_name, "..")) - continue; - - const string lib_path = dir +"/"+ pfile->d_name; - - // Ignore stupid libtool files. Kludge alert. - if (lib_path.substr(lib_path.length()-3) == ".la") { - //cerr << "WARNING: Skipping stupid libtool file " << pfile->d_name << endl; - continue; - } - - Glib::Module* plugin_library = new Glib::Module(lib_path, Glib::MODULE_BIND_LOCAL); - if (!plugin_library || !(*plugin_library)) { - cerr << "WARNING: Failed to load LADSPA library " << lib_path << endl; - continue; - } - - bool found = plugin_library->get_symbol("ladspa_descriptor", (void*&)df); - if (!found || !df) { - cerr << "WARNING: Non-LADSPA library found in LADSPA path: " << - lib_path << endl; - // Not a LADSPA plugin library - delete plugin_library; - continue; - } - - for (unsigned long i=0; (descriptor = (LADSPA_Descriptor*)df(i)) != NULL; ++i) { - char id_str[11]; - snprintf(id_str, 11, "%lu", descriptor->UniqueID); - const string uri = string("ladspa:").append(id_str); - - const Plugins::const_iterator i = _plugins.find(uri); - - if (i == _plugins.end()) { - LADSPAPlugin* plugin = new LADSPAPlugin(lib_path, uri, - descriptor->UniqueID, - descriptor->Label, - descriptor->Name); - - _plugins.insert(make_pair(uri, plugin)); - - } else { - cerr << "Warning: Duplicate " << uri - << " - Using " << i->second->library_path() - << " over " << lib_path << endl; - } - } - - delete plugin_library; - } - closedir(pdir); - } -} -#endif // HAVE_LADSPA - - -} // namespace Ingen diff --git a/src/libs/engine/NodeFactory.hpp b/src/libs/engine/NodeFactory.hpp deleted file mode 100644 index 95194350..00000000 --- a/src/libs/engine/NodeFactory.hpp +++ /dev/null @@ -1,92 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard <http://drobilla.net> - * - * 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 NODEFACTORY_H -#define NODEFACTORY_H - -#include CONFIG_H_PATH -#include "module/global.hpp" - -#include <list> -#include <map> -#include <string> -#include <pthread.h> -#include <glibmm/module.h> -#ifdef HAVE_SLV2 -#include <slv2/slv2.h> -#include "LV2Info.hpp" -#endif -#include "types.hpp" - -using std::string; - -namespace Ingen { - -class NodeImpl; -class PatchImpl; -class PluginImpl; - - -/** Loads plugins and creates Nodes from them. - * - * NodeFactory's responsibility is to get enough information to allow the - * loading of a plugin possible (ie finding/opening shared libraries etc) - * - * The constructor of various Node types (ie LADSPANode) are responsible - * for actually creating a Node instance of the plugin. - * - * \ingroup engine - */ -class NodeFactory -{ -public: - NodeFactory(Ingen::Shared::World* world); - ~NodeFactory(); - - void load_plugins(); - - typedef std::map<std::string,PluginImpl*> Plugins; - const Plugins& plugins() const { return _plugins; } - - PluginImpl* plugin(const string& uri); - - /** DEPRECATED */ - PluginImpl* plugin(const string& type, const string& lib, const string& label); - -private: -#ifdef HAVE_LADSPA - void load_ladspa_plugins(); -#endif - -#ifdef HAVE_SLV2 - void load_lv2_plugins(); -#endif - - void load_internal_plugins(); - - Plugins _plugins; - Ingen::Shared::World* _world; - bool _has_loaded; -#ifdef HAVE_SLV2 - SharedPtr<LV2Info> _lv2_info; -#endif -}; - - -} // namespace Ingen - -#endif // NODEFACTORY_H diff --git a/src/libs/engine/NodeImpl.hpp b/src/libs/engine/NodeImpl.hpp deleted file mode 100644 index ac125c13..00000000 --- a/src/libs/engine/NodeImpl.hpp +++ /dev/null @@ -1,170 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard <http://drobilla.net> - * - * 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 NODEIMPL_H -#define NODEIMPL_H - -#include <string> -#include <raul/Array.hpp> -#include "interface/Node.hpp" -#include "types.hpp" -#include "GraphObjectImpl.hpp" - -namespace Raul { template <typename T> class List; class Maid; } - -namespace Ingen { - -namespace Shared { class Plugin; class Node; class Port; } - -using namespace Shared; - -class Buffer; -class PluginImpl; -class PatchImpl; -class PortImpl; -class MessageContext; - - -/** A Node (or "module") in a Patch (which is also a Node). - * - * A Node is a unit with input/output ports, a process() method, and some other - * things. - * - * This is a pure abstract base class for any Node, it contains no - * implementation details/data whatsoever. This is the interface you need to - * implement to add a new Node type. - * - * \ingroup engine - */ -class NodeImpl : public GraphObjectImpl, virtual public Ingen::Shared::Node -{ -public: - NodeImpl(GraphObjectImpl* parent, const std::string& name, bool poly) - : GraphObjectImpl(parent, name, poly) - {} - - /** Activate this Node. - * - * This function will be called in a non-realtime thread before it is - * inserted in to a patch. Any non-realtime actions that need to be - * done before the Node is ready for use should be done here. - */ - virtual void activate() = 0; - virtual void deactivate() = 0; - virtual bool activated() = 0; - - /** Prepare for a new (external) polyphony value. - * - * Preprocessor thread, poly is actually applied by apply_poly. - * \return true on success. - */ - virtual bool prepare_poly(uint32_t poly) = 0; - - /** Apply a new (external) polyphony value. - * - * Audio thread. - * - * \param poly Must be < the most recent value passed to prepare_poly. - * \param maid Any objects no longer needed will be pushed to this - */ - virtual bool apply_poly(Raul::Maid& maid, uint32_t poly) = 0; - - /** Parallelism: Reset flags for start of a new cycle. - */ - virtual void reset_input_ready() = 0; - - /** Parallelism: Claim this node (to wait on its input). - * Only one thread will ever take this lock on a particular Node. - * \return true if lock was aquired, false otherwise - */ - virtual bool process_lock() = 0; - - /** Parallelism: Unclaim this node (let someone else wait on its input). - * Only a thread which successfully called process_lock may call this. - */ - virtual void process_unlock() = 0; - - /** Parallelism: Wait for signal that input is ready. - * Only a thread which successfully called process_lock may call this. - */ - virtual void wait_for_input(size_t num_providers) = 0; - - /** Parallelism: Signal that input is ready. Realtime safe. - * Calling this will wake up the thread which blocked on wait_for_input - * if there is one, and otherwise cause it to return true the next call. - * \return true if lock was aquired and input is ready, false otherwise - */ - virtual void signal_input_ready() = 0; - - /** Parallelism: Return the number of providers that have signalled. - */ - virtual unsigned n_inputs_ready() const = 0; - - /** Run the node for one instant in the message thread. - */ - virtual void message_process(MessageContext& context, uint32_t* output) = 0; - - /** Run the node for @a nframes input/output. - * - * @a start and @a end are transport times: end is not redundant in the case - * of varispeed, where end-start != nframes. - */ - virtual void process(ProcessContext& context) = 0; - - virtual void set_port_buffer(uint32_t voice, uint32_t port_num, Buffer* buf) = 0; - - virtual uint32_t num_ports() const = 0; - - virtual Port* port(uint32_t index) const = 0; - virtual PortImpl* port_impl(uint32_t index) const = 0; - - /** Used by the process order finding algorithm (ie during connections) */ - virtual bool traversed() const = 0; - virtual void traversed(bool b) = 0; - - /** Nodes that are connected to this Node's inputs. - * (This Node depends on them) - */ - virtual Raul::List<NodeImpl*>* providers() = 0; - virtual void providers(Raul::List<NodeImpl*>* l) = 0; - - /** Nodes are are connected to this Node's outputs. - * (They depend on this Node) - */ - virtual Raul::List<NodeImpl*>* dependants() = 0; - virtual void dependants(Raul::List<NodeImpl*>* l) = 0; - - /** The Patch this Node belongs to. */ - virtual PatchImpl* parent_patch() const = 0; - - /** Information about the Plugin this Node is an instance of. - * Not the best name - not all nodes come from plugins (ie Patch) - */ - virtual PluginImpl* plugin_impl() const = 0; - - /** Information about the Plugin this Node is an instance of. - * Not the best name - not all nodes come from plugins (ie Patch) - */ - virtual const Shared::Plugin* plugin() const = 0; - - virtual void set_buffer_size(size_t size) = 0; -}; - - -} // namespace Ingen - -#endif // NODEIMPL_H diff --git a/src/libs/engine/OSCClientSender.cpp b/src/libs/engine/OSCClientSender.cpp deleted file mode 100644 index dca2e0ed..00000000 --- a/src/libs/engine/OSCClientSender.cpp +++ /dev/null @@ -1,358 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard <http://drobilla.net> - * - * 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 "OSCClientSender.hpp" -#include <cassert> -#include <iostream> -#include <unistd.h> -#include <raul/AtomLiblo.hpp> -#include "EngineStore.hpp" -#include "NodeFactory.hpp" -#include "util.hpp" -#include "PatchImpl.hpp" -#include "NodeImpl.hpp" -#include "PluginImpl.hpp" -#include "PortImpl.hpp" -#include "ConnectionImpl.hpp" -#include "AudioDriver.hpp" -#include "interface/ClientInterface.hpp" - -using namespace std; - -namespace Ingen { - - -/*! \page client_osc_namespace Client OSC Namespace Documentation - * - * <p>NOTE: this comment doesn't really apply any longer.. sort of. - * but maybe it still should.. maybe. so it remains...</p> - * - * <p>These are all the messages sent from the engine to the client. - * Communication takes place over two distinct bands: control band and - * notification band.</p> - * <p>The control band is where clients send commands, and receive a simple - * response, either OK or an error.</p> - * <p>All notifications of engine state (ie new nodes) are sent over the - * notification band <em>which is seperate from the control band</em>. The - * reasoning behind this is that many clients may be connected at the same - * time - a client may receive notifications that are not a direct consequence - * of some message it sent.</p> - * <p>The notification band can be thought of as a stream of events representing - * the changing engine state. For example, It is possible for a client to send - * commands and receive aknowledgements, and not listen to the notification band - * at all; or (in the near future anyway) for a client to use UDP for the control - * band (for speed), and TCP for the notification band (for reliability and - * order guarantees).</p> - * \n\n - */ - - -/** \page client_osc_namespace - * \n - * <h2>Control Band</h2> - */ - -/** \page client_osc_namespace - * <p> \b /ingen/ok - Respond to a successful user command - * \arg \b response-id (int) - Request ID this is a response to - * </p> \n \n - */ -void -OSCClientSender::response_ok(int32_t id) -{ - if (!_enabled) - return; - - if (lo_send(_address, "/ingen/ok", "i", id) < 0) { - cerr << "Unable to send ok " << id << "! (" - << lo_address_errstr(_address) << ")" << endl; - } -} - - -/** \page client_osc_namespace - * <p> \b /ingen/response - Respond to a user command - * \arg \b response-id (int) - Request ID this is a response to - * \arg \b message (string) - Error message (natural language text) - * </p> \n \n - */ -void -OSCClientSender::response_error(int32_t id, const std::string& msg) -{ - if (!_enabled) - return; - - if (lo_send(_address, "/ingen/error", "is", id, msg.c_str()) < 0) { - cerr << "Unable to send error " << id << "! (" - << lo_address_errstr(_address) << ")" << endl; - } -} - - -/** \page client_osc_namespace - * \n - * <h2>Notification Band</h2> - */ - - -/** \page client_osc_namespace - * <p> \b /ingen/error - Notification that an error has occurred - * \arg \b message (string) - Error message (natural language text) \n\n - * \li This is for notification of errors that aren't a direct response to a - * user command, ie "unexpected" errors.</p> \n \n - */ -void -OSCClientSender::error(const std::string& msg) -{ - send("/ingen/error", "s", msg.c_str(), LO_ARGS_END); -} - - -/** \page client_osc_namespace - * <p> \b /ingen/new_node - Notification of a new node's creation. - * \arg \b plug-uri (string) - URI of the plugin new node is an instance of - * \arg \b path (string) - Path of the new node - * \arg \b polyphonic (boolean) - Node is polyphonic\n\n - * \li New nodes are sent as a bundle. The first message in the bundle will be - * this one (/ingen/new_node), followed by a series of /ingen/new_port commands, - * followed by /ingen/new_node_end. </p> \n \n - */ -void OSCClientSender::new_node(const std::string& node_path, - const std::string& plugin_uri) -{ - send("/ingen/new_node", "ss", node_path.c_str(), plugin_uri.c_str(), LO_ARGS_END); -} - - - -/** \page client_osc_namespace - * <p> \b /ingen/new_port - Notification of a new port's creation. - * \arg \b path (string) - Path of new port - * \arg \b index (integer) - Index (or sort key) of port on parent - * \arg \b data-type (string) - Type of port (ingen:AudioPort, ingen:ControlPort, ingen:MIDIPort, or ingen:OSCPort) - * \arg \b direction ("is-output") (integer) - Direction of data flow (Input = 0, Output = 1) - * - * \li Note that in the event of loading a patch, this message could be - * followed immediately by a control change, meaning the default-value is - * not actually the current value of the port. - * \li The minimum and maximum values are suggestions only, they are not - * enforced in any way, and going outside them is perfectly fine. Also note - * that the port ranges in om_gtk are not these ones! Those ranges are set - * as variable.</p> \n \n - */ -void -OSCClientSender::new_port(const std::string& path, - uint32_t index, - const std::string& data_type, - bool is_output) -{ - send("/ingen/new_port", "sisi", path.c_str(), index, data_type.c_str(), is_output, LO_ARGS_END); -} - - -/** \page client_osc_namespace - * <p> \b /ingen/destroyed - Notification an object has been destroyed - * \arg \b path (string) - Path of object (which no longer exists) </p> \n \n - */ -void -OSCClientSender::destroy(const std::string& path) -{ - assert(path != "/"); - - send("/ingen/destroyed", "s", path.c_str(), LO_ARGS_END); -} - - -/** \page client_osc_namespace - * <p> \b /ingen/patch_cleared - Notification a patch has been cleared (all children destroyed) - * \arg \b path (string) - Path of patch (which is now empty)</p> \n \n - */ -void -OSCClientSender::patch_cleared(const std::string& patch_path) -{ - send("/ingen/patch_cleared", "s", patch_path.c_str(), LO_ARGS_END); -} - - -/** \page client_osc_namespace - * <p> \b /ingen/new_connection - Notification a new connection has been made. - * \arg \b src-path (string) - Path of the source port - * \arg \b dst-path (string) - Path of the destination port</p> \n \n - */ -void -OSCClientSender::connect(const std::string& src_port_path, const std::string& dst_port_path) -{ - send("/ingen/new_connection", "ss", src_port_path.c_str(), dst_port_path.c_str(), LO_ARGS_END); -} - - -/** \page client_osc_namespace - * <p> \b /ingen/disconnection - Notification a connection has been unmade. - * \arg \b src-path (string) - Path of the source port - * \arg \b dst-path (string) - Path of the destination port</p> \n \n - */ -void -OSCClientSender::disconnect(const std::string& src_port_path, const std::string& dst_port_path) -{ - send("/ingen/disconnection", "ss", src_port_path.c_str(), dst_port_path.c_str(), LO_ARGS_END); -} - - -/** \page client_osc_namespace - * <p> \b /ingen/set_variable - Notification of a variable. - * \arg \b path (string) - Path of the object associated with variable (node, patch, or port) - * \arg \b key (string) - * \arg \b value (string)</p> \n \n - */ -void -OSCClientSender::set_variable(const std::string& path, const std::string& key, const Atom& value) -{ - lo_message m = lo_message_new(); - lo_message_add_string(m, path.c_str()); - lo_message_add_string(m, key.c_str()); - Raul::AtomLiblo::lo_message_add_atom(m, value); - send_message("/ingen/set_variable", m); -} - - -/** \page client_osc_namespace - * <p> \b /ingen/set_property - Notification of a property. - * \arg \b path (string) - Path of the object associated with property (node, patch, or port) - * \arg \b key (string) - * \arg \b value (string)</p> \n \n - */ -void -OSCClientSender::set_property(const std::string& path, const std::string& key, const Atom& value) -{ - lo_message m = lo_message_new(); - lo_message_add_string(m, path.c_str()); - lo_message_add_string(m, key.c_str()); - Raul::AtomLiblo::lo_message_add_atom(m, value); - send_message("/ingen/set_property", m); -} - - -/** \page client_osc_namespace - * <p> \b /ingen/set_port_value - Notification the value of a port has changed - * \arg \b path (string) - Path of port - * \arg \b value (any) - New value of port </p> \n \n - */ -void -OSCClientSender::set_port_value(const std::string& port_path, const Raul::Atom& value) -{ - lo_message m = lo_message_new(); - lo_message_add_string(m, port_path.c_str()); - Raul::AtomLiblo::lo_message_add_atom(m, value); - send_message("/ingen/set_port_value", m); -} - - -/** \page client_osc_namespace - * <p> \b /ingen/set_port_value - Notification the value of a port has changed - * \arg \b path (string) - Path of port - * \arg \b voice (int) - Voice which is set to this value - * \arg \b value (any) - New value of port </p> \n \n - */ -void -OSCClientSender::set_voice_value(const std::string& port_path, uint32_t voice, const Raul::Atom& value) -{ - lo_message m = lo_message_new(); - lo_message_add_string(m, port_path.c_str()); - Raul::AtomLiblo::lo_message_add_atom(m, value); - send_message("/ingen/set_port_value", m); -} - - -/** \page client_osc_namespace - * <p> \b /ingen/port_activity - Notification of activity for a port (e.g. MIDI messages) - * \arg \b path (string) - Path of port </p> \n \n - */ -void -OSCClientSender::port_activity(const std::string& port_path) -{ - if (!_enabled) - return; - - lo_send(_address, "/ingen/port_activity", "s", port_path.c_str(), LO_ARGS_END); -} - - -/** \page client_osc_namespace - * <p> \b /ingen/plugin - Notification of the existance of a plugin - * \arg \b uri (string) - URI of plugin (e.g. http://example.org/filtermatic) - * \arg \b type (string) - Type of plugin (e.g. "ingen:LV2Plugin") - * \arg \b symbol (string) - Valid symbol for plugin (default symbol for nodes) (e.g. "adsr") - * \arg \b name (string) - Descriptive human-readable name of plugin (e.g. "ADSR Envelope") - */ -void -OSCClientSender::new_plugin(const std::string& uri, - const std::string& type_uri, - const std::string& symbol, - const std::string& name) -{ - lo_message m = lo_message_new(); - lo_message_add_string(m, uri.c_str()); - lo_message_add_string(m, type_uri.c_str()); - lo_message_add_string(m, symbol.c_str()); - lo_message_add_string(m, name.c_str()); - send_message("/ingen/plugin", m); -} - - -/** \page client_osc_namespace - * <p> \b /ingen/new_patch - Notification of a new patch - * \arg \b path (string) - Path of new patch - * \arg \b poly (int) - Polyphony of new patch (\em not a boolean like new_node) </p> \n \n - */ -void -OSCClientSender::new_patch(const std::string& path, uint32_t poly) -{ - send("/ingen/new_patch", "si", path.c_str(), poly, LO_ARGS_END); -} - - -/** \page client_osc_namespace - * <p> \b /ingen/object_renamed - Notification of an object's renaming - * \arg \b old-path (string) - Old path of object - * \arg \b new-path (string) - New path of object </p> \n \n - */ -void -OSCClientSender::object_renamed(const std::string& old_path, const std::string& new_path) -{ - send("/ingen/object_renamed", "ss", old_path.c_str(), new_path.c_str(), LO_ARGS_END); -} - - -/** Sends information about a program associated with a node. - */ -void -OSCClientSender::program_add(const std::string& node_path, uint32_t bank, uint32_t program, const std::string& name) -{ - send("/ingen/program_add", "siis", - node_path.c_str(), bank, program, name.c_str(), LO_ARGS_END); -} - - -void -OSCClientSender::program_remove(const std::string& node_path, uint32_t bank, uint32_t program) -{ - send("/ingen/program_remove", "sii", - node_path.c_str(), bank, program, LO_ARGS_END); -} - - -} // namespace Ingen diff --git a/src/libs/engine/OSCClientSender.hpp b/src/libs/engine/OSCClientSender.hpp deleted file mode 100644 index c8c8418f..00000000 --- a/src/libs/engine/OSCClientSender.hpp +++ /dev/null @@ -1,136 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard <http://drobilla.net> - * - * 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 OSCCLIENTSENDER_H -#define OSCCLIENTSENDER_H - -#include <cassert> -#include <string> -#include <iostream> -#include <lo/lo.h> -#include <pthread.h> -#include "types.hpp" -#include "interface/ClientInterface.hpp" -#include "shared/OSCSender.hpp" - -namespace Ingen { - -namespace Shared { class EngineInterface; } - - -/** Implements ClientInterface for OSC clients (sends OSC messages). - * - * \ingroup engine - */ -class OSCClientSender : public Shared::ClientInterface, public Shared::OSCSender -{ -public: - OSCClientSender(const std::string& url) - : _url(url) - { - _address = lo_address_new_from_url(url.c_str()); - } - - virtual ~OSCClientSender() - { lo_address_free(_address); } - - bool enabled() const { return _enabled; } - - void enable() { _enabled = true; } - void disable() { _enabled = false; } - - void bundle_begin() { OSCSender::bundle_begin(); } - void bundle_end() { OSCSender::bundle_end(); } - void transfer_begin() { OSCSender::transfer_begin(); } - void transfer_end() { OSCSender::transfer_end(); } - - std::string uri() const { return lo_address_get_url(_address); } - - void subscribe(Shared::EngineInterface* engine) { } - - /* *** ClientInterface Implementation Below *** */ - - //void client_registration(const std::string& url, int client_id); - - void response_ok(int32_t id); - void response_error(int32_t id, const std::string& msg); - - void error(const std::string& msg); - - virtual void new_plugin(const std::string& uri, - const std::string& type_uri, - const std::string& symbol, - const std::string& name); - - virtual void new_patch(const std::string& path, uint32_t poly); - - virtual void new_node(const std::string& path, - const std::string& plugin_uri); - - virtual void new_port(const std::string& path, - uint32_t index, - const std::string& data_type, - bool is_output); - - virtual void patch_cleared(const std::string& path); - - virtual void destroy(const std::string& path); - - virtual void object_renamed(const std::string& old_path, - const std::string& new_path); - - virtual void connect(const std::string& src_port_path, - const std::string& dst_port_path); - - virtual void disconnect(const std::string& src_port_path, - const std::string& dst_port_path); - - virtual void set_variable(const std::string& subject_path, - const std::string& predicate, - const Raul::Atom& value); - - virtual void set_property(const std::string& subject_path, - const std::string& predicate, - const Raul::Atom& value); - - virtual void set_port_value(const std::string& port_path, - const Raul::Atom& value); - - virtual void set_voice_value(const std::string& port_path, - uint32_t voice, - const Raul::Atom& value); - - virtual void port_activity(const std::string& port_path); - - virtual void program_add(const std::string& node_path, - uint32_t bank, - uint32_t program, - const std::string& program_name); - - virtual void program_remove(const std::string& node_path, - uint32_t bank, - uint32_t program); - -private: - std::string _url; -}; - - -} // namespace Ingen - -#endif // OSCCLIENTSENDER_H - diff --git a/src/libs/engine/OSCDriver.hpp b/src/libs/engine/OSCDriver.hpp deleted file mode 100644 index 06125217..00000000 --- a/src/libs/engine/OSCDriver.hpp +++ /dev/null @@ -1,82 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard <http://drobilla.net> - * - * 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 OSCDRIVER_H -#define OSCDRIVER_H - -#include "types.hpp" -#include "Driver.hpp" -#include <iostream> - -namespace Ingen { - - -/** OSC driver abstract base class. - * - * \ingroup engine - */ -class OSCDriver : public Driver -{ -public: - OSCDriver() : Driver(DataType::EVENT) {} - - /** Prepare events (however neccessary) for the specified block (realtime safe) */ - virtual void prepare_block(const SampleCount block_start, const SampleCount block_end) = 0; -}; - - - -/** Dummy OSCDriver. - * - * Not abstract, all functions are dummies. One of these will be allocated and - * "used" if no working OSC driver is loaded. (Doing it this way as opposed to - * just making OSCDriver have dummy functions makes sure any existing OSCDriver - * derived class actually implements the required functions). - * - * \ingroup engine - */ -class DummyOSCDriver : public OSCDriver -{ -public: - DummyOSCDriver() { - std::cout << "[DummyOSCDriver] Started Dummy OSC driver." << std::endl; - } - - ~DummyOSCDriver() {} - - void activate() {} - void deactivate() {} - - bool is_activated() const { return false; } - bool is_enabled() const { return false; } - - void enable() {} - void disable() {} - - DriverPort* create_port(DuplexPort* patch_port) { return NULL; } - - void add_port(DriverPort* port) {} - DriverPort* remove_port(const Raul::Path& path) { return NULL; } - - void prepare_block(const SampleCount block_start, const SampleCount block_end) {} -}; - - - -} // namespace Ingen - -#endif // OSCDRIVER_H diff --git a/src/libs/engine/OSCEngineReceiver.cpp b/src/libs/engine/OSCEngineReceiver.cpp deleted file mode 100644 index e4e2fec1..00000000 --- a/src/libs/engine/OSCEngineReceiver.cpp +++ /dev/null @@ -1,884 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard <http://drobilla.net> - * - * 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 <iostream> -#include <cstdlib> -#include <string> -//#define ENABLE_AVAHI 1 -#include <lo/lo.h> -#include "types.hpp" -#include <raul/SharedPtr.hpp> -#include <raul/AtomLiblo.hpp> -#include "interface/ClientInterface.hpp" -#include "engine/ThreadManager.hpp" -#include "OSCEngineReceiver.hpp" -#include "QueuedEventSource.hpp" -#include "OSCClientSender.hpp" -#include "ClientBroadcaster.hpp" - -using namespace std; - -namespace Ingen { - - -/*! \page engine_osc_namespace Engine OSC Namespace Documentation - * - * <p>These are the commands the engine recognizes. A client can control every - * aspect of the engine entirely with these commands.</p> - * - * <p>All commands on this page are in the "control band". If a client needs to - * know about the state of the engine, it must listen to the "notification band". - * See the "Client OSC Namespace Documentation" for details.</p>\n\n - */ - - -OSCEngineReceiver::OSCEngineReceiver(Engine& engine, size_t queue_size, uint16_t port) - : QueuedEngineInterface(engine, queue_size, queue_size) // FIXME - , _server(NULL) -{ - _receive_thread = new ReceiveThread(*this); - - char port_str[6]; - snprintf(port_str, 6, "%u", port); - - _server = lo_server_new(port_str, error_cb); -#ifdef ENABLE_AVAHI - lo_server_avahi_init(_server, "ingen"); -#endif - - if (_server == NULL) { - cerr << "[OSC] Could not start OSC server. Aborting." << endl; - exit(EXIT_FAILURE); - } else { - char* lo_url = lo_server_get_url(_server); - cout << "[OSC] Started OSC server at " << lo_url << endl; - free(lo_url); - } - - // For debugging, print all incoming OSC messages - //lo_server_add_method(_server, NULL, NULL, generic_cb, NULL); - - // Set response address for this message. - // It's important this is first and returns nonzero. - lo_server_add_method(_server, NULL, NULL, set_response_address_cb, this); - - // Commands - lo_server_add_method(_server, "/ingen/ping", "i", ping_cb, this); - lo_server_add_method(_server, "/ingen/ping_queued", "i", ping_slow_cb, this); - lo_server_add_method(_server, "/ingen/quit", "i", quit_cb, this); - //lo_server_add_method(_server, "/ingen/register_client", "is", register_client_cb, this); - lo_server_add_method(_server, "/ingen/register_client", "i", register_client_cb, this); - lo_server_add_method(_server, "/ingen/unregister_client", "i", unregister_client_cb, this); - lo_server_add_method(_server, "/ingen/load_plugins", "i", load_plugins_cb, this); - lo_server_add_method(_server, "/ingen/activate", "i", engine_activate_cb, this); - lo_server_add_method(_server, "/ingen/deactivate", "i", engine_deactivate_cb, this); - lo_server_add_method(_server, "/ingen/new_patch", "isi", new_patch_cb, this); - lo_server_add_method(_server, "/ingen/clear_patch", "is", clear_patch_cb, this); - lo_server_add_method(_server, "/ingen/set_polyphony", "isi", set_polyphony_cb, this); - lo_server_add_method(_server, "/ingen/set_polyphonic", "isT", set_polyphonic_cb, this); - lo_server_add_method(_server, "/ingen/set_polyphonic", "isF", set_polyphonic_cb, this); - lo_server_add_method(_server, "/ingen/new_port", "issi", new_port_cb, this); - lo_server_add_method(_server, "/ingen/new_node", "issss", new_node_cb, this); - lo_server_add_method(_server, "/ingen/new_node", "issss", new_node_cb, this); - lo_server_add_method(_server, "/ingen/new_node", "iss", new_node_by_uri_cb, this); - lo_server_add_method(_server, "/ingen/new_node", "iss", new_node_by_uri_cb, this); - lo_server_add_method(_server, "/ingen/destroy", "is", destroy_cb, this); - lo_server_add_method(_server, "/ingen/rename", "iss", rename_cb, this); - lo_server_add_method(_server, "/ingen/connect", "iss", connect_cb, this); - lo_server_add_method(_server, "/ingen/disconnect", "iss", disconnect_cb, this); - lo_server_add_method(_server, "/ingen/disconnect_all", "iss", disconnect_all_cb, this); - lo_server_add_method(_server, "/ingen/set_port_value", NULL, set_port_value_cb, this); - lo_server_add_method(_server, "/ingen/note_on", "isii", note_on_cb, this); - lo_server_add_method(_server, "/ingen/note_off", "isi", note_off_cb, this); - lo_server_add_method(_server, "/ingen/all_notes_off", "isi", all_notes_off_cb, this); - lo_server_add_method(_server, "/ingen/midi_learn", "is", midi_learn_cb, this); - lo_server_add_method(_server, "/ingen/set_variable", NULL, variable_set_cb, this); - lo_server_add_method(_server, "/ingen/set_property", NULL, property_set_cb, this); - - // Queries - lo_server_add_method(_server, "/ingen/request_variable", "iss", variable_get_cb, this); - lo_server_add_method(_server, "/ingen/request_plugin", "is", request_plugin_cb, this); - lo_server_add_method(_server, "/ingen/request_object", "is", request_object_cb, this); - lo_server_add_method(_server, "/ingen/request_port_value", "is", request_port_value_cb, this); - lo_server_add_method(_server, "/ingen/request_plugins", "i", request_plugins_cb, this); - lo_server_add_method(_server, "/ingen/request_all_objects", "i", request_all_objects_cb, this); - - lo_server_add_method(_server, NULL, NULL, unknown_cb, NULL); - - Thread::set_name("OSC Pre-Processor"); -} - - -OSCEngineReceiver::~OSCEngineReceiver() -{ - deactivate(); - stop(); - _receive_thread->stop(); - delete _receive_thread; - - if (_server != NULL) { -#ifdef ENABLE_AVAHI - lo_server_avahi_free(_server); -#endif - lo_server_free(_server); - _server = NULL; - } -} - - -void -OSCEngineReceiver::activate() -{ - QueuedEventSource::activate(); - _receive_thread->set_name("OSC Receiver"); - _receive_thread->start(); - _receive_thread->set_scheduling(SCHED_FIFO, 5); // Jack default appears to be 10 -} - - -void -OSCEngineReceiver::deactivate() -{ - cout << "[OSCEngineReceiver] Stopped OSC listening thread" << endl; - _receive_thread->stop(); - QueuedEventSource::deactivate(); -} - - -/** Override the semaphore driven _run method of QueuedEngineInterface - * to wait on OSC messages and prepare them right away in the same thread. - */ -void -OSCEngineReceiver::ReceiveThread::_run() -{ - Thread::get().set_context(THREAD_PRE_PROCESS); - - /* get a timestamp here and stamp all the events with the same time so - * they all get executed in the same cycle */ - - while (true) { - assert(_receiver._server); - /*if ( ! _server) { - cout << "[OSCEngineReceiver] Server is NULL, exiting" << endl; - break; - }*/ - - // Wait on a message and enqueue it - lo_server_recv(_receiver._server); - - // Enqueue every other message that is here "now" - // (would this provide truly atomic bundles?) - while (lo_server_recv_noblock(_receiver._server, 0) > 0) - if (_receiver.unprepared_events()) - _receiver.whip(); - - // No more unprepared events - } -} - - -/** Create a new responder for this message, if necessary. - * - * This is based on the fact that the current responder is stored in a ref - * counted pointer, and events just take a reference to that. Thus, events - * may delete their responder if we've since switched to a new one, or the - * same one can stay around and serve a series of events. - * Hooray for reference counting. - * - * If this message came from the same source as the last message, no allocation - * of responders or lo_addresses or any of it needs to be done. Unfortunately - * the only way to check is by comparing URLs, because liblo addresses suck. - * Lack of a fast liblo address comparison really sucks here, in any case. - */ -int -OSCEngineReceiver::set_response_address_cb(const char* path, const char* types, lo_arg** argv, int argc, lo_message msg, void* user_data) -{ - OSCEngineReceiver* const me = reinterpret_cast<OSCEngineReceiver*>(user_data); - - if (argc < 1 || types[0] != 'i') // Not a valid Ingen message - return 0; // Save liblo the trouble - - const int32_t id = argv[0]->i; - - const lo_address addr = lo_message_get_source(msg); - char* const url = lo_address_get_url(addr); - - const SharedPtr<Responder> r = me->_responder; - - /* Different address than last time, have to do a lookup */ - if (!r || !r->client() || strcmp(url, r->client()->uri().c_str())) { - ClientInterface* client = me->_engine.broadcaster()->client(url); - if (client) - me->_responder = SharedPtr<Responder>(new Responder(client, id)); - else - me->_responder = SharedPtr<Responder>(new Responder()); - } - - if (id != -1) { - me->set_next_response_id(id); - } else { - me->disable_responses(); - } - - // If this returns 0 no OSC commands will work - return 1; -} - - -void -OSCEngineReceiver::error_cb(int num, const char* msg, const char* path) -{ - cerr << "liblo server error " << num << " in path \"" << "\" - " << msg << endl; -} - - -/** \page engine_osc_namespace - * <p> \b /ingen/ping - Immediately sends a successful response to the given response id. - * \arg \b response-id (integer) </p> \n \n - */ -int -OSCEngineReceiver::_ping_cb(const char* path, const char* types, lo_arg** argv, int argc, lo_message msg) -{ - const lo_address addr = lo_message_get_source(msg); - if (lo_send(addr, "/ingen/ok", "i", argv[0]->i) < 0) - cerr << "WARNING: Unable to send response: " << lo_address_errstr(addr) << endl; - return 0; -} - - -/** \page engine_osc_namespace - * <p> \b /ingen/ping_queued - Sends response after going through the event queue. - * \arg \b response-id (integer) - * - * \li See the documentation for /ingen/set_port_value_queued for an explanation of how - * this differs from /ingen/ping. This is useful to send after sending a large cluster of - * events as a sentinel and wait on it's response, to know when the events are all - * finished processing.</p> \n \n - */ -int -OSCEngineReceiver::_ping_slow_cb(const char* path, const char* types, lo_arg** argv, int argc, lo_message msg) -{ - ping(); - return 0; -} - - -/** \page engine_osc_namespace - * <p> \b /ingen/quit - Terminates the engine. - * \arg \b response-id (integer) - * - * \li Note that there is NO order guarantees with this command at all. You could - * send 10 messages then quit, and the quit reply could come immediately and the - * 10 messages would never get executed. </p> \n \n - */ -int -OSCEngineReceiver::_quit_cb(const char* path, const char* types, lo_arg** argv, int argc, lo_message msg) -{ - quit(); - return 0; -} - -/** \page engine_osc_namespace - * <p> \b /ingen/register_client - Registers a new client with the engine - * \arg \b response-id (integer) \n\n - * \li The incoming address will be used for the new registered client. If you - * want to register a different specific address, use the URL version. </p> \n \n - */ -int -OSCEngineReceiver::_register_client_cb(const char* path, const char* types, lo_arg** argv, int argc, lo_message msg) -{ - lo_address addr = lo_message_get_source(msg); - - char* const url = lo_address_get_url(addr); - ClientInterface* client = new OSCClientSender((const char*)url); - register_client(client); - free(url); - - return 0; -} - - -/** \page engine_osc_namespace - * <p> \b /ingen/unregister_client - Unregisters a client - * \arg \b response-id (integer) </p> \n \n - */ -int -OSCEngineReceiver::_unregister_client_cb(const char* path, const char* types, lo_arg** argv, int argc, lo_message msg) -{ - lo_address addr = lo_message_get_source(msg); - - char* url = lo_address_get_url(addr); - unregister_client(url); - free(url); - - return 0; -} - - -/** \page engine_osc_namespace - * <p> \b /ingen/load_plugins - Locates all available plugins, making them available for use. - * \arg \b response-id (integer) </p> \n \n - */ -int -OSCEngineReceiver::_load_plugins_cb(const char* path, const char* types, lo_arg** argv, int argc, lo_message msg) -{ - load_plugins(); - return 0; -} - - -/** \page engine_osc_namespace - * <p> \b /ingen/activate - Activate the engine (MIDI, audio, everything) - * \arg \b response-id (integer) </p> - * - * \li Note that you <b>must</b> send this message first if you want the engine to do - * anything at all - <em>including respond to your messages!</em> \n \n - */ -int -OSCEngineReceiver::_engine_activate_cb(const char* path, const char* types, lo_arg** argv, int argc, lo_message msg) -{ - QueuedEngineInterface::activate(); - return 0; -} - - -/** \page engine_osc_namespace - * <p> \b /ingen/deactivate - Deactivate the engine completely. - * \arg \b response-id (integer) </p> \n \n - */ -int -OSCEngineReceiver::_engine_deactivate_cb(const char* path, const char* types, lo_arg** argv, int argc, lo_message msg) -{ - QueuedEngineInterface::deactivate(); - return 0; -} - - -/** \page engine_osc_namespace - * <p> \b /ingen/new_patch - Creates a new, empty, toplevel patch. - * \arg \b response-id (integer) - * \arg \b patch-path (string) - Patch path (complete, ie /master/parent/new_patch) - * \arg \b poly (integer) - Patch's (internal) polyphony </p> \n \n - */ -int -OSCEngineReceiver::_new_patch_cb(const char* path, const char* types, lo_arg** argv, int argc, lo_message msg) -{ - const char* patch_path = &argv[1]->s; - const int32_t poly = argv[2]->i; - - new_patch(patch_path, poly); - return 0; -} - - -/** \page engine_osc_namespace - * <p> \b /ingen/rename - Rename an Object (only Nodes, for now) - * \arg \b response-id (integer) - * \arg \b path - Object's path - * \arg \b name - New name for object </p> \n \n - */ -int -OSCEngineReceiver::_rename_cb(const char* path, const char* types, lo_arg** argv, int argc, lo_message msg) -{ - const char* object_path = &argv[1]->s; - const char* name = &argv[2]->s; - - rename(object_path, name); - return 0; -} - - -/** \page engine_osc_namespace - * <p> \b /ingen/clear_patch - Remove all nodes from a patch - * \arg \b response-id (integer) - * \arg \b patch-path - Patch's path </p> \n \n - */ -int -OSCEngineReceiver::_clear_patch_cb(const char* path, const char* types, lo_arg** argv, int argc, lo_message msg) -{ - const char* patch_path = &argv[1]->s; - - clear_patch(patch_path); - return 0; -} - - -/** \page engine_osc_namespace - * <p> \b /ingen/set_polyphony - Set the polyphony of a patch - * \arg \b response-id (integer) - * \arg \b patch-path - Patch's path - * \arg \b poly (integer) </p> \n \n - */ -int -OSCEngineReceiver::_set_polyphony_cb(const char* path, const char* types, lo_arg** argv, int argc, lo_message msg) -{ - const char* patch_path = &argv[1]->s; - const uint32_t poly = argv[2]->i; - - set_polyphony(patch_path, poly); - return 0; -} - - -/** \page engine_osc_namespace - * <p> \b /ingen/set_polyphonic - Toggle a node's or port's polyphonic mode - * \arg \b response-id (integer) - * \arg \b path - Object's path - * \arg \b polyphonic (bool) </p> \n \n - */ -int -OSCEngineReceiver::_set_polyphonic_cb(const char* path, const char* types, lo_arg** argv, int argc, lo_message msg) -{ - const char* object_path = &argv[1]->s; - bool polyphonic = (types[2] == 'T'); - - set_polyphonic(object_path, polyphonic); - return 0; -} - - -// FIXME: add index -/** \page engine_osc_namespace - * <p> \b /ingen/new_port - Add a port into a given patch (load a plugin by URI) - * \arg \b response-id (integer) - * \arg \b path (string) - Full path of the new port (ie. /patch2/subpatch/newport) - * \arg \b data-type (string) - Type of port (ingen:AudioPort, ingen:ControlPort, ingen:MIDIPort, or ingen:OSCPort) - * \arg \b direction ("is-output") (integer) - Direction of data flow (Input = 0, Output = 1) </p> \n \n - */ -int -OSCEngineReceiver::_new_port_cb(const char* path, const char* types, lo_arg** argv, int argc, lo_message msg) -{ - const char* port_path = &argv[1]->s; - const char* data_type = &argv[2]->s; - const int32_t direction = argv[3]->i; - - new_port(port_path, 0, data_type, (direction == 1)); - return 0; -} - -/** \page engine_osc_namespace - * <p> \b /ingen/new_node - Add a node into a given patch (load a plugin by URI) - * \arg \b response-id (integer) - * \arg \b node-path (string) - Full path of the new node (ie. /patch2/subpatch/newnode) - * \arg \b plug-uri (string) - URI of the plugin to load \n \n - */ -int -OSCEngineReceiver::_new_node_by_uri_cb(const char* path, const char* types, lo_arg** argv, int argc, lo_message msg) -{ - const char* node_path = &argv[1]->s; - const char* plug_uri = &argv[2]->s; - - new_node(node_path, plug_uri); - return 0; -} - - -/** \page engine_osc_namespace - * <p> \b /ingen/new_node - Add a node into a given patch (load a plugin by libname, label) \b DEPRECATED - * \arg \b response-id (integer) - * \arg \b node-path (string) - Full path of the new node (ie. /patch2/subpatch/newnode) - * \arg \b type (string) - Plugin type ("LADSPA" or "Internal") - * \arg \b lib-name (string) - Name of library where plugin resides (eg "cmt.so") - * \arg \b plug-label (string) - Label (ID) of plugin (eg "sine_fcaa") \n \n - * - * \li This is only here to provide backwards compatibility for old patches that store LADSPA plugin - * references as libname, label. It is to be removed ASAP, don't use it. - * </p> \n \n - */ -int -OSCEngineReceiver::_new_node_cb(const char* path, const char* types, lo_arg** argv, int argc, lo_message msg) -{ - const char* node_path = &argv[1]->s; - const char* type = &argv[2]->s; - const char* lib_name = &argv[3]->s; - const char* plug_label = &argv[4]->s; - - new_node_deprecated(node_path, type, lib_name, plug_label); - return 0; -} - - -/** \page engine_osc_namespace - * <p> \b /ingen/destroy - Removes (destroys) a Patch or a Node - * \arg \b response-id (integer) - * \arg \b node-path (string) - Full path of the object </p> \n \n - */ -int -OSCEngineReceiver::_destroy_cb(const char* path, const char* types, lo_arg** argv, int argc, lo_message msg) -{ - const char* node_path = &argv[1]->s; - - destroy(node_path); - return 0; -} - - -/** \page engine_osc_namespace - * <p> \b /ingen/connect - Connects two ports (must be in the same patch) - * \arg \b response-id (integer) - * \arg \b src-port-path (string) - Full path of source port - * \arg \b dst-port-path (string) - Full path of destination port </p> \n \n - */ -int -OSCEngineReceiver::_connect_cb(const char* path, const char* types, lo_arg** argv, int argc, lo_message msg) -{ - const char* src_port_path = &argv[1]->s; - const char* dst_port_path = &argv[2]->s; - - connect(src_port_path, dst_port_path); - return 0; -} - - -/** \page engine_osc_namespace - * <p> \b /ingen/disconnect - Disconnects two ports. - * \arg \b response-id (integer) - * \arg \b src-port-path (string) - Full path of source port - * \arg \b dst-port-path (string) - Full path of destination port </p> \n \n - */ -int -OSCEngineReceiver::_disconnect_cb(const char* path, const char* types, lo_arg** argv, int argc, lo_message msg) -{ - const char* src_port_path = &argv[1]->s; - const char* dst_port_path = &argv[2]->s; - - disconnect(src_port_path, dst_port_path); - return 0; -} - - -/** \page engine_osc_namespace - * <p> \b /ingen/disconnect_all - Disconnect all connections to/from a node/port. - * \arg \b response-id (integer) - * \arg \b patch-path (string) - The (parent) patch in which to disconnect object. </p> \n \n - * \arg \b node-path (string) - Full path of object. </p> \n \n - */ -int -OSCEngineReceiver::_disconnect_all_cb(const char* path, const char* types, lo_arg** argv, int argc, lo_message msg) -{ - const char* patch_path = &argv[1]->s; - const char* object_path = &argv[2]->s; - - disconnect_all(patch_path, object_path); - return 0; -} - - -/** \page engine_osc_namespace - * <p> \b /ingen/set_port_value - Sets the value of a port for all voices (as a QueuedEvent) - * \arg \b response-id (integer) - * \arg \b port-path (string) - Name of port - * \arg \b value (float) - Value to set port to.</p> \n \n - */ -int -OSCEngineReceiver::_set_port_value_cb(const char* path, const char* types, lo_arg** argv, int argc, lo_message msg) -{ - if (argc < 3 || argc > 5 || strncmp(types, "is", 2)) - return 1; - - const char* port_path = &argv[1]->s; - - using Raul::Atom; - - if (!strcmp(types, "isf")) { // float, all voices - const float value = argv[2]->f; - set_port_value(port_path, Atom(value)); - } else if (!strcmp(types, "isif")) { // float, specific voice - const float value = argv[3]->f; - set_voice_value(port_path, argv[2]->i, Atom(value)); - } else if (!strcmp(types, "issb")) { // blob (event), all voices - const char* type = &argv[2]->s; - lo_blob b = argv[3]; - size_t data_size = lo_blob_datasize(b); - void* data = lo_blob_dataptr(b); - set_port_value(port_path, Atom(type, data_size, data)); - } else if (!strcmp(types, "isisb")) { // blob (event), specific voice - const char* type = &argv[3]->s; - lo_blob b = argv[4]; - size_t data_size = lo_blob_datasize(b); - void* data = lo_blob_dataptr(b); - set_voice_value(port_path, argv[2]->i, Atom(type, data_size, data)); - } else if (!strcmp(types, "issN")) { // empty event (type only), all voices - const char* type = &argv[2]->s; - set_port_value(port_path, Atom(type, 0, NULL)); - } else if (!strcmp(types, "isisN")) { // empty event (type only), specific voice - const char* type = &argv[3]->s; - set_voice_value(port_path, argv[2]->i, Atom(type, 0, NULL)); - } else { - return 1; - } - - return 0; -} - - -/** \page engine_osc_namespace - * <p> \b /ingen/note_on - Triggers a note-on, just as if it came from MIDI - * \arg \b response-id (integer) - * \arg \b node-path (string) - Patch of Node to trigger (must be a trigger or note node) - * \arg \b note-num (int) - MIDI style note number (0-127) - * \arg \b velocity (int) - MIDI style velocity (0-127)</p> \n \n - */ -int -OSCEngineReceiver::_note_on_cb(const char* path, const char* types, lo_arg** argv, int argc, lo_message msg) -{ - /* - - const char* node_path = &argv[1]->s; - const uchar note_num = argv[2]->i; - const uchar velocity = argv[3]->i; - */ - cerr << "FIXME: OSC note on\n"; - //note_on(node_path, note_num, velocity); - return 0; -} - - -/** \page engine_osc_namespace - * <p> \b /ingen/note_off - Triggers a note-off, just as if it came from MIDI - * \arg \b response-id (integer) - * \arg \b node-path (string) - Patch of Node to trigger (must be a trigger or note node) - * \arg \b note-num (int) - MIDI style note number (0-127)</p> \n \n - */ -int -OSCEngineReceiver::_note_off_cb(const char* path, const char* types, lo_arg** argv, int argc, lo_message msg) -{ - /* - - const char* patch_path = &argv[1]->s; - const uchar note_num = argv[2]->i; - */ - cerr << "FIXME: OSC note off\n"; - //note_off(patch_path, note_num); - return 0; -} - - -/** \page engine_osc_namespace - * <p> \b /ingen/all_notes_off - Triggers a note-off for all voices, just as if it came from MIDI - * \arg \b response-id (integer) - * \arg \b patch-path (string) - Patch of patch to send event to </p> \n \n - */ -int -OSCEngineReceiver::_all_notes_off_cb(const char* path, const char* types, lo_arg** argv, int argc, lo_message msg) -{ - /* - - const char* patch_path = &argv[1]->s; - */ - cerr << "FIXME: OSC all notes off\n"; - //all_notes_off(patch_path); - return 0; -} - - -/** \page engine_osc_namespace - * <p> \b /ingen/midi_learn - Initiate MIDI learn for a given (MIDI Control) Node - * \arg \b response-id (integer) - * \arg \b node-path (string) - Patch of the Node that should learn the next MIDI event. - * - * \li This of course will only do anything for MIDI control nodes. The node will learn the next MIDI - * event that arrives at it's MIDI input port - no behind the scenes voodoo happens here. It is planned - * that a plugin specification supporting arbitrary OSC commands for plugins will exist one day, and this - * method will go away completely. </p> \n \n - */ -int -OSCEngineReceiver::_midi_learn_cb(const char* path, const char* types, lo_arg** argv, int argc, lo_message msg) -{ - const char* patch_path = &argv[1]->s; - - midi_learn(patch_path); - return 0; -} - - -/** \page engine_osc_namespace - * <p> \b /ingen/set_variable - Set a variable, associated with a synth-space object (node, etc) - * \arg \b response-id (integer) - * \arg \b object-path (string) - Full path of object to associate variable with - * \arg \b key (string) - Key (index/predicate/ID) for new variable - * \arg \b value (string) - Value of new variable </p> \n \n - */ -int -OSCEngineReceiver::_variable_set_cb(const char* path, const char* types, lo_arg** argv, int argc, lo_message msg) -{ - if (argc != 4 || types[0] != 'i' || types[1] != 's' || types[2] != 's') - return 1; - - const char* object_path = &argv[1]->s; - const char* key = &argv[2]->s; - - Raul::Atom value = Raul::AtomLiblo::lo_arg_to_atom(types[3], argv[3]); - - set_variable(object_path, key, value); - return 0; -} - - -/** \page engine_osc_namespace - * <p> \b /ingen/set_property - Set an (RDF) property, associated with a synth-space object (node, etc) - * \arg \b response-id (integer) - * \arg \b object-path (string) - Full path of object to associate variable with - * \arg \b key (string) - URI/QName for predicate of this property (e.g. "ingen:enabled") - * \arg \b value (string) - Value of property </p> \n \n - */ -int -OSCEngineReceiver::_property_set_cb(const char* path, const char* types, lo_arg** argv, int argc, lo_message msg) -{ - if (argc != 4 || types[0] != 'i' || types[1] != 's' || types[2] != 's') - return 1; - - const char* object_path = &argv[1]->s; - const char* key = &argv[2]->s; - - Raul::Atom value = Raul::AtomLiblo::lo_arg_to_atom(types[3], argv[3]); - - set_property(object_path, key, value); - return 0; -} - - -/** \page engine_osc_namespace - * <p> \b /ingen/request_variable - Requests the engine send a piece of variable, associated with a synth-space object (node, etc) - * \arg \b response-id (integer) - * \arg \b object-path (string) - Full path of object variable is associated with - * \arg \b key (string) - Key (index) for piece of variable - * - * \li Reply will be sent to client registered with the source address of this message.</p> \n \n - */ -int -OSCEngineReceiver::_variable_get_cb(const char* path, const char* types, lo_arg** argv, int argc, lo_message msg) -{ - const char* object_path = &argv[1]->s; - const char* key = &argv[2]->s; - - request_variable(object_path, key); - return 0; -} - - -/** \page engine_osc_namespace - * <p> \b /ingen/request_plugin - Requests the engine send the value of a port. - * \arg \b response-id (integer) - * \arg \b port-path (string) - Full path of port to send the value of \n\n - * \li Reply will be sent to client registered with the source address of this message.</p>\n\n - */ -int -OSCEngineReceiver::_request_plugin_cb(const char* path, const char* types, lo_arg** argv, int argc, lo_message msg) -{ - const char* uri = &argv[1]->s; - - request_plugin(uri); - return 0; -} - - -/** \page engine_osc_namespace - * <p> \b /ingen/request_object - Requests the engine send the value of a port. - * \arg \b response-id (integer) - * \arg \b port-path (string) - Full path of port to send the value of \n\n - * \li Reply will be sent to client registered with the source address of this message.</p>\n\n - */ -int -OSCEngineReceiver::_request_object_cb(const char* path, const char* types, lo_arg** argv, int argc, lo_message msg) -{ - const char* object_path = &argv[1]->s; - - request_object(object_path); - return 0; -} - - -/** \page engine_osc_namespace - * <p> \b /ingen/request_port_value - Requests the engine send the value of a port. - * \arg \b response-id (integer) - * \arg \b port-path (string) - Full path of port to send the value of \n\n - * \li Reply will be sent to client registered with the source address of this message.</p>\n\n - */ -int -OSCEngineReceiver::_request_port_value_cb(const char* path, const char* types, lo_arg** argv, int argc, lo_message msg) -{ - const char* port_path = &argv[1]->s; - - request_port_value(port_path); - return 0; -} - - -/** \page engine_osc_namespace - * <p> \b /ingen/request_plugins - Requests the engine send a list of all known plugins. - * \arg \b response-id (integer) \n\n - * \li Reply will be sent to client registered with the source address of this message.</p>\n\n - */ -int -OSCEngineReceiver::_request_plugins_cb(const char* path, const char* types, lo_arg** argv, int argc, lo_message msg) -{ - request_plugins(); - return 0; -} - - -/** \page engine_osc_namespace - * <p> \b /ingen/request_all_objects - Requests the engine send information about \em all objects (patches, nodes, etc) - * \arg \b response-id (integer)\n\n - * \li Reply will be sent to client registered with the source address of this message.</p> \n \n - */ -int -OSCEngineReceiver::_request_all_objects_cb(const char* path, const char* types, lo_arg** argv, int argc, lo_message msg) -{ - request_all_objects(); - return 0; -} - - -// Static Callbacks // - - -// Display incoming OSC messages (for debugging purposes) -int -OSCEngineReceiver::generic_cb(const char* path, const char* types, lo_arg** argv, int argc, lo_message msg, void* user_data) -{ - printf("[OSCMsg] %s (%s)\t", path, types); - - for (int i=0; i < argc; ++i) { - lo_arg_pp(lo_type(types[i]), argv[i]); - printf("\t"); - } - printf("\n"); - - return 1; // not handled -} - - -int -OSCEngineReceiver::unknown_cb(const char* path, const char* types, lo_arg** argv, int argc, lo_message msg, void* user_data) -{ - const lo_address addr = lo_message_get_source(msg); - char* const url = lo_address_get_url(addr); - - cerr << "Unknown command " << path << " (" << types << "), sending error.\n"; - - string error_msg = "Unknown command: "; - error_msg.append(path).append(" ").append(types); - - OSCClientSender(url).error(error_msg); - - return 0; -} - - -} // namespace Ingen diff --git a/src/libs/engine/OSCEngineReceiver.hpp b/src/libs/engine/OSCEngineReceiver.hpp deleted file mode 100644 index c6e0bf59..00000000 --- a/src/libs/engine/OSCEngineReceiver.hpp +++ /dev/null @@ -1,129 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard <http://drobilla.net> - * - * 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 OSCENGINERECEIVER_H -#define OSCENGINERECEIVER_H - -#include CONFIG_H_PATH -#include <string> -#include <stdint.h> -#include <lo/lo.h> -#include <raul/SharedPtr.hpp> -#include "QueuedEngineInterface.hpp" -#include "Responder.hpp" -using std::string; - -namespace Ingen { - -class JackDriver; -class NodeFactory; -class PatchImpl; - - -/* Some boilerplate killing macros... */ -#define LO_HANDLER_ARGS const char* path, const char* types, lo_arg** argv, int argc, lo_message msg - -/* Defines a static handler to be passed to lo_add_method, which is a trivial - * wrapper around a non-static method that does the real work. Makes a whoole - * lot of ugly boiler plate go away */ -#define LO_HANDLER(name) \ -int _##name##_cb (LO_HANDLER_ARGS);\ -inline static int name##_cb(LO_HANDLER_ARGS, void* myself)\ -{ return ((OSCEngineReceiver*)myself)->_##name##_cb(path, types, argv, argc, msg); } - - -/* FIXME: Make this receive and preprocess in the same thread? */ - - -/** Receives OSC messages from liblo. - * - * This inherits from QueuedEngineInterface and calls it's own functions - * via OSC. It's not actually a directly callable EngineInterface (it's - * callable via OSC...) so it should be implemented-as-a (privately inherit) - * QueuedEngineInterface, but it needs to be public so it's an EventSource - * the Driver can use. This probably should be fixed somehow.. - * - * \ingroup engine - */ -class OSCEngineReceiver : public QueuedEngineInterface -{ -public: - OSCEngineReceiver(Engine& engine, size_t queue_size, uint16_t port); - ~OSCEngineReceiver(); - - void activate(); - void deactivate(); - -private: - struct ReceiveThread : public Raul::Thread { - ReceiveThread(OSCEngineReceiver& receiver) : _receiver(receiver) {} - virtual void _run(); - private: - OSCEngineReceiver& _receiver; - }; - - friend class ReceiveThread; - - ReceiveThread* _receive_thread; - - static void error_cb(int num, const char* msg, const char* path); - static int set_response_address_cb(LO_HANDLER_ARGS, void* myself); - static int generic_cb(LO_HANDLER_ARGS, void* myself); - static int unknown_cb(LO_HANDLER_ARGS, void* myself); - - LO_HANDLER(quit); - LO_HANDLER(ping); - LO_HANDLER(ping_slow); - LO_HANDLER(register_client); - LO_HANDLER(unregister_client); - LO_HANDLER(load_plugins); - LO_HANDLER(engine_activate); - LO_HANDLER(engine_deactivate); - LO_HANDLER(new_patch); - LO_HANDLER(rename); - LO_HANDLER(new_port); - LO_HANDLER(new_node); - LO_HANDLER(new_node_by_uri); - LO_HANDLER(clear_patch); - LO_HANDLER(set_polyphony); - LO_HANDLER(set_polyphonic); - LO_HANDLER(destroy); - LO_HANDLER(connect); - LO_HANDLER(disconnect); - LO_HANDLER(disconnect_all); - LO_HANDLER(set_port_value); - LO_HANDLER(note_on); - LO_HANDLER(note_off); - LO_HANDLER(all_notes_off); - LO_HANDLER(midi_learn); - LO_HANDLER(variable_get); - LO_HANDLER(variable_set); - LO_HANDLER(property_set); - LO_HANDLER(request_plugin); - LO_HANDLER(request_object); - LO_HANDLER(request_port_value); - LO_HANDLER(request_variable); - LO_HANDLER(request_plugins); - LO_HANDLER(request_all_objects); - - lo_server _server; -}; - - -} // namespace Ingen - -#endif // OSCENGINERECEIVER_H diff --git a/src/libs/engine/ObjectSender.cpp b/src/libs/engine/ObjectSender.cpp deleted file mode 100644 index 688cea8e..00000000 --- a/src/libs/engine/ObjectSender.cpp +++ /dev/null @@ -1,150 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard <http://drobilla.net> - * - * 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 "ObjectSender.hpp" -#include "interface/ClientInterface.hpp" -#include "EngineStore.hpp" -#include "PatchImpl.hpp" -#include "NodeImpl.hpp" -#include "PortImpl.hpp" -#include "PortImpl.hpp" -#include "ConnectionImpl.hpp" -#include "NodeFactory.hpp" -#include "interface/DataType.hpp" -#include "AudioBuffer.hpp" - -namespace Ingen { - - -void -ObjectSender::send_patch(ClientInterface* client, const PatchImpl* patch, bool recursive) -{ - client->bundle_begin(); - - client->new_patch(patch->path(), patch->internal_polyphony()); - client->set_property(patch->path(), "ingen:polyphonic", patch->polyphonic()); - - // Send variable - const GraphObjectImpl::Variables& data = patch->variables(); - for (GraphObjectImpl::Variables::const_iterator j = data.begin(); j != data.end(); ++j) - client->set_variable(patch->path(), (*j).first, (*j).second); - - client->set_property(patch->path(), "ingen:enabled", (bool)patch->enabled()); - - client->bundle_end(); - - if (recursive) { - - // Send nodes - for (List<NodeImpl*>::const_iterator j = patch->nodes().begin(); - j != patch->nodes().end(); ++j) { - const NodeImpl* const node = (*j); - send_node(client, node, true); - } - - // Send ports - for (uint32_t i=0; i < patch->num_ports(); ++i) { - PortImpl* const port = patch->port_impl(i); - send_port(client, port); - } - - // Send connections - client->transfer_begin(); - for (PatchImpl::Connections::const_iterator j = patch->connections().begin(); - j != patch->connections().end(); ++j) - client->connect((*j)->src_port_path(), (*j)->dst_port_path()); - client->transfer_end(); - } -} - - -/** Sends a node or a patch */ -void -ObjectSender::send_node(ClientInterface* client, const NodeImpl* node, bool recursive) -{ - PluginImpl* const plugin = node->plugin_impl(); - - assert(node->path().length() > 0); - - if (plugin->type() == Plugin::Patch) { - send_patch(client, (PatchImpl*)node, recursive); - return; - } - - if (plugin->uri().length() == 0) { - cerr << "Node " << node->path() << " plugin has no URI! Not sending." << endl; - return; - } - - client->bundle_begin(); - - client->new_node(node->path(), node->plugin()->uri()); - client->set_property(node->path(), "ingen:polyphonic", node->polyphonic()); - - // Send variables - const GraphObjectImpl::Variables& data = node->variables(); - for (GraphObjectImpl::Variables::const_iterator j = data.begin(); j != data.end(); ++j) - client->set_variable(node->path(), (*j).first, (*j).second); - - // Send properties - const GraphObjectImpl::Properties& prop = node->properties(); - for (GraphObjectImpl::Properties::const_iterator j = prop.begin(); j != prop.end(); ++j) - client->set_property(node->path(), (*j).first, (*j).second); - - client->bundle_end(); - - if (recursive) { - // Send ports - for (size_t j=0; j < node->num_ports(); ++j) - send_port(client, node->port_impl(j)); - } -} - - -void -ObjectSender::send_port(ClientInterface* client, const PortImpl* port) -{ - assert(port); - - client->bundle_begin(); - - client->new_port(port->path(), port->index(), port->type().uri(), port->is_output()); - client->set_property(port->path(), "ingen:polyphonic", port->polyphonic()); - - // Send variable - const GraphObjectImpl::Variables& data = port->variables(); - for (GraphObjectImpl::Variables::const_iterator j = data.begin(); j != data.end(); ++j) - client->set_variable(port->path(), (*j).first, (*j).second); - - // Send properties - const GraphObjectImpl::Properties& prop = port->properties(); - for (GraphObjectImpl::Properties::const_iterator j = prop.begin(); j != prop.end(); ++j) - client->set_property(port->path(), (*j).first, (*j).second); - - // Send control value - if (port->type() == DataType::CONTROL) { - const Sample value = dynamic_cast<const AudioBuffer*>(port->buffer(0))->value_at(0); - //cerr << port->path() << " sending default value " << default_value << endl; - client->set_port_value(port->path(), value); - } - - client->bundle_end(); -} - - -} // namespace Ingen - diff --git a/src/libs/engine/ObjectSender.hpp b/src/libs/engine/ObjectSender.hpp deleted file mode 100644 index 9b6eb000..00000000 --- a/src/libs/engine/ObjectSender.hpp +++ /dev/null @@ -1,57 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard <http://drobilla.net> - * - * 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 OBJECTSENDER_H -#define OBJECTSENDER_H - -#include <list> - -namespace Ingen { - -namespace Shared { - class ClientInterface; -} using Shared::ClientInterface; - -class PatchImpl; -class NodeImpl; -class PortImpl; -class PluginImpl; - - -/** Utility class for sending GraphObjects to clients through ClientInterface. - * - * While ClientInterface is the direct low level message-based interface - * (protocol), this is used from the engine to easily send proper Objects - * with these messages (which is done in a few different parts of the code). - * - * Basically a serialiser, except to calls on ClientInterface rather than - * eg a byte stream. - */ -class ObjectSender { -public: - - // FIXME: Make all object parameters const - - static void send_patch(ClientInterface* client, const PatchImpl* patch, bool recursive); - static void send_node(ClientInterface* client, const NodeImpl* node, bool recursive); - static void send_port(ClientInterface* client, const PortImpl* port); -}; - -} // namespace Ingen - -#endif // OBJECTSENDER_H - diff --git a/src/libs/engine/OmInProcess.cpp b/src/libs/engine/OmInProcess.cpp deleted file mode 100644 index 6a65cf38..00000000 --- a/src/libs/engine/OmInProcess.cpp +++ /dev/null @@ -1,66 +0,0 @@ -/* This file is part of Ingen. Copyright (C) 2006 Mario Lang. - * - * 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 <pthread.h> -#include <stdlib.h> -#include <stdio.h> -#include <memory.h> -#include <jack/jack.h> -#include "Engine.hpp" -#include "OSCReceiver.hpp" -#include "JackAudioDriver.hpp" - -extern "C" -{ - int jack_initialize(jack_client_t* client, const char* load_init); - void jack_finish(void* arg); -} - - -void* -run_main(void* arg) -{ - Engine::instance().main(); - - // FIXME: cleanup - - return 0; -} - - -pthread_t main_thread; - - -int -jack_initialize(jack_client_t* client, const char* load_init) -{ - if ((Ingen::om = new Engine(load_init, new Ingen::JackAudioDriver(client))) != NULL) { - pthread_create(&main_thread, NULL, run_main, NULL); - return 0; // Success - } else { - return 1; - } -} - - -void -jack_finish(void* arg) -{ - void* ret; - Engine::instance().quit(); - pthread_join(main_thread, &ret); -} - diff --git a/src/libs/engine/OutputPort.cpp b/src/libs/engine/OutputPort.cpp deleted file mode 100644 index 116d9a3e..00000000 --- a/src/libs/engine/OutputPort.cpp +++ /dev/null @@ -1,62 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard <http://drobilla.net> - * - * 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 <iostream> -#include "OutputPort.hpp" -#include "Buffer.hpp" -#include "ProcessContext.hpp" - -using namespace std; - -namespace Ingen { - - -OutputPort::OutputPort(NodeImpl* parent, - const string& name, - uint32_t index, - uint32_t poly, - DataType type, - const Atom& value, - size_t buffer_size) - : PortImpl(parent, name, index, poly, type, value, buffer_size) -{ - if (type == DataType::CONTROL) - _broadcast = true; -} - - -void -OutputPort::pre_process(ProcessContext& context) -{ - for (uint32_t i=0; i < _poly; ++i) - buffer(i)->prepare_write(context.start(), context.nframes()); -} - - -void -OutputPort::post_process(ProcessContext& context) -{ - for (uint32_t i=0; i < _poly; ++i) - buffer(i)->prepare_read(context.start(), context.nframes()); - - //cerr << path() << " output post: buffer: " << buffer(0) << endl; - - broadcast(context); -} - - -} // namespace Ingen diff --git a/src/libs/engine/OutputPort.hpp b/src/libs/engine/OutputPort.hpp deleted file mode 100644 index 8d441b5c..00000000 --- a/src/libs/engine/OutputPort.hpp +++ /dev/null @@ -1,63 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard <http://drobilla.net> - * - * 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 OUTPUTPORT_H -#define OUTPUTPORT_H - -#include <string> -#include <cstdlib> -#include "PortImpl.hpp" -#include "types.hpp" - -namespace Ingen { - - -/** An output port. - * - * Output ports always have a locally allocated buffer, and buffer() will - * always return that buffer. (This is very different from InputPort) - * - * This class actually adds no functionality to Port whatsoever right now, - * it will in the future when more advanced port types exist, and it makes - * things clearer throughout the engine. - * - * \ingroup engine - */ -class OutputPort : virtual public PortImpl -{ -public: - OutputPort(NodeImpl* parent, - const std::string& name, - uint32_t index, - uint32_t poly, - DataType type, - const Atom& value, - size_t buffer_size); - - void pre_process(ProcessContext& context); - void post_process(ProcessContext& context); - - virtual ~OutputPort() {} - - bool is_input() const { return false; } - bool is_output() const { return true; } -}; - - -} // namespace Ingen - -#endif // OUTPUTPORT_H diff --git a/src/libs/engine/PatchImpl.cpp b/src/libs/engine/PatchImpl.cpp deleted file mode 100644 index 9f0ae701..00000000 --- a/src/libs/engine/PatchImpl.cpp +++ /dev/null @@ -1,481 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard <http://drobilla.net> - * - * 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 <cassert> -#include <cmath> -#include <iostream> -#include "ThreadManager.hpp" -#include "NodeImpl.hpp" -#include "PatchImpl.hpp" -#include "PatchPlugin.hpp" -#include "PortImpl.hpp" -#include "ConnectionImpl.hpp" -#include "DuplexPort.hpp" -#include "Engine.hpp" -#include "ProcessSlave.hpp" - -using namespace std; - -namespace Ingen { - - -PatchImpl::PatchImpl(Engine& engine, const string& path, uint32_t poly, PatchImpl* parent, SampleRate srate, size_t buffer_size, uint32_t internal_poly) - : NodeBase(new PatchPlugin("http://example.org/FIXME", "patch", "Ingen Patch"), - path, poly, parent, srate, buffer_size) - , _engine(engine) - , _internal_poly(internal_poly) - , _compiled_patch(NULL) - , _process(false) -{ - assert(internal_poly >= 1); -} - - -PatchImpl::~PatchImpl() -{ - assert(!_activated); - - delete _compiled_patch; -} - - -void -PatchImpl::activate() -{ - NodeBase::activate(); - - for (List<NodeImpl*>::iterator i = _nodes.begin(); i != _nodes.end(); ++i) - (*i)->activate(); - - assert(_activated); -} - - -void -PatchImpl::deactivate() -{ - if (_activated) { - - NodeBase::deactivate(); - - for (List<NodeImpl*>::iterator i = _nodes.begin(); i != _nodes.end(); ++i) { - if ((*i)->activated()) - (*i)->deactivate(); - assert(!(*i)->activated()); - } - } - assert(!_activated); -} - - -void -PatchImpl::disable() -{ - assert(ThreadManager::current_thread_id() == THREAD_PROCESS); - - _process = false; - - for (List<PortImpl*>::iterator i = _output_ports.begin(); i != _output_ports.end(); ++i) - (*i)->clear_buffers(); -} - - -bool -PatchImpl::prepare_internal_poly(uint32_t poly) -{ - assert(ThreadManager::current_thread_id() == THREAD_PRE_PROCESS); - - /* TODO: ports? internal/external poly? */ - - for (List<NodeImpl*>::iterator i = _nodes.begin(); i != _nodes.end(); ++i) - (*i)->prepare_poly(poly); - - for (Connections::iterator i = _connections.begin(); i != _connections.end(); ++i) - ((ConnectionImpl*)i->get())->prepare_poly(poly); - - /* FIXME: Deal with failure */ - - return true; -} - - -bool -PatchImpl::apply_internal_poly(Raul::Maid& maid, uint32_t poly) -{ - assert(ThreadManager::current_thread_id() == THREAD_PROCESS); - - /* TODO: ports? internal/external poly? */ - - for (List<NodeImpl*>::iterator i = _nodes.begin(); i != _nodes.end(); ++i) - (*i)->apply_poly(maid, poly); - - _internal_poly = poly; - - return true; -} - - -/** Run the patch for the specified number of frames. - * - * Calls all Nodes in (roughly, if parallel) the order _compiled_patch specifies. - */ -void -PatchImpl::process(ProcessContext& context) -{ - if (!_process) - return; - - NodeBase::pre_process(context); - - /*if (_ports) - for (size_t i=0; i < _ports->size(); ++i) - if (_ports->at(i)->is_input() && _ports->at(i)->type() == DataType::MIDI) - cerr << _ports->at(i)->path() << " " - << _ports->at(i)->buffer(0) << " # events: " - << ((MidiBuffer*)_ports->at(i)->buffer(0))->event_count() << endl;*/ - - /* Run */ - if (_compiled_patch && _compiled_patch->size() > 0) { - if (_engine.process_slaves().size() > 0) - process_parallel(context); - else - process_single(context); - } - - NodeBase::post_process(context); -} - - -void -PatchImpl::process_parallel(ProcessContext& context) -{ - size_t n_slaves = _engine.process_slaves().size(); - - CompiledPatch* const cp = _compiled_patch; - - /* Start p-1 slaves */ - - if (n_slaves >= cp->size()) - n_slaves = cp->size()-1; - - if (n_slaves > 0) { - for (size_t i=0; i < cp->size(); ++i) - (*cp)[i].node()->reset_input_ready(); - - for (size_t i=0; i < n_slaves; ++i) - _engine.process_slaves()[i]->whip(cp, i+1, context); - } - - - /* Process ourself until everything is done - * This is analogous to ProcessSlave::_whipped(), but this is the master - * (i.e. what the main Jack process thread calls). Where ProcessSlave - * waits on input, this just skips the node and tries the next, to avoid - * waiting in the Jack thread which pisses Jack off. - */ - - size_t index = 0; - size_t num_finished = 0; // Number of consecutive finished nodes hit - - while (num_finished < cp->size()) { - - CompiledNode& n = (*cp)[index]; - - if (n.node()->process_lock()) { - if (n.node()->n_inputs_ready() == n.n_providers()) { - n.node()->process(context); - - /* Signal dependants their input is ready */ - for (size_t i=0; i < n.dependants().size(); ++i) - n.dependants()[i]->signal_input_ready(); - - ++num_finished; - } else { - n.node()->process_unlock(); - num_finished = 0; - } - } else { - if (n.node()->n_inputs_ready() == n.n_providers()) - ++num_finished; - else - num_finished = 0; - } - - index = (index + 1) % cp->size(); - } - - /* Tell slaves we're done in case we beat them, and pray they're - * really done by the start of next cycle. - * FIXME: This probably breaks (race) at extremely small nframes where - * ingen is the majority of the DSP load. - */ - for (size_t i=0; i < n_slaves; ++i) - _engine.process_slaves()[i]->finish(); -} - - -void -PatchImpl::process_single(ProcessContext& context) -{ - CompiledPatch* const cp = _compiled_patch; - - for (size_t i=0; i < cp->size(); ++i) - (*cp)[i].node()->process(context); -} - - -void -PatchImpl::set_buffer_size(size_t size) -{ - NodeBase::set_buffer_size(size); - assert(_buffer_size == size); - - CompiledPatch* const cp = _compiled_patch; - - for (size_t i=0; i < cp->size(); ++i) - (*cp)[i].node()->set_buffer_size(size); -} - - -// Patch specific stuff - - -/** Add a node. - * Preprocessing thread only. - */ -void -PatchImpl::add_node(List<NodeImpl*>::Node* ln) -{ - assert(ThreadManager::current_thread_id() == THREAD_PRE_PROCESS); - assert(ln != NULL); - assert(ln->elem() != NULL); - assert(ln->elem()->parent_patch() == this); - //assert(ln->elem()->polyphony() == _internal_poly); - - _nodes.push_back(ln); -} - - -/** Remove a node. - * Preprocessing thread only. - */ -PatchImpl::Nodes::Node* -PatchImpl::remove_node(const string& symbol) -{ - assert(ThreadManager::current_thread_id() == THREAD_PRE_PROCESS); - for (List<NodeImpl*>::iterator i = _nodes.begin(); i != _nodes.end(); ++i) - if ((*i)->symbol() == symbol) - return _nodes.erase(i); - - return NULL; -} - - -/** Remove a connection. - * Preprocessing thread only. - */ -PatchImpl::Connections::Node* -PatchImpl::remove_connection(const PortImpl* src_port, const PortImpl* dst_port) -{ - assert(ThreadManager::current_thread_id() == THREAD_PRE_PROCESS); - bool found = false; - Connections::Node* connection = NULL; - for (Connections::iterator i = _connections.begin(); i != _connections.end(); ++i) { - ConnectionImpl* const c = (ConnectionImpl*)i->get(); - if (c->src_port() == src_port && c->dst_port() == dst_port) { - connection = _connections.erase(i); - found = true; - break; - } - } - - if ( ! found) - cerr << "WARNING: [PatchImpl::remove_connection] Connection not found !" << endl; - - return connection; -} - - -bool -PatchImpl::has_connection(const PortImpl* src_port, const PortImpl* dst_port) const -{ - // FIXME: Doesn't scale - for (Connections::const_iterator i = _connections.begin(); i != _connections.end(); ++i) { - ConnectionImpl* const c = (ConnectionImpl*)i->get(); - if (c->src_port() == src_port && c->dst_port() == dst_port) - return true; - } - - return false; -} - - -uint32_t -PatchImpl::num_ports() const -{ - ThreadID context = ThreadManager::current_thread_id(); - - if (context == THREAD_PROCESS) - return NodeBase::num_ports(); - else - return _input_ports.size() + _output_ports.size(); -} - - -/** Create a port. Not realtime safe. - */ -PortImpl* -PatchImpl::create_port(const string& name, DataType type, size_t buffer_size, bool is_output) -{ - if (type == DataType::UNKNOWN) { - cerr << "[PatchImpl::create_port] Unknown port type " << type.uri() << endl; - return NULL; - } - - assert( !(type == DataType::UNKNOWN) ); - - return new DuplexPort(this, name, num_ports(), _polyphony, type, Atom(), buffer_size, is_output); -} - - -/** Remove port from ports list used in pre-processing thread. - * - * Port is not removed from ports array for process thread (which could be - * simultaneously running). - * - * Realtime safe. Preprocessing thread only. - */ -List<PortImpl*>::Node* -PatchImpl::remove_port(const string& symbol) -{ - assert(ThreadManager::current_thread_id() == THREAD_PRE_PROCESS); - - bool found = false; - List<PortImpl*>::Node* ret = NULL; - for (List<PortImpl*>::iterator i = _input_ports.begin(); i != _input_ports.end(); ++i) { - if ((*i)->symbol() == symbol) { - ret = _input_ports.erase(i); - found = true; - } - } - - if (!found) - for (List<PortImpl*>::iterator i = _output_ports.begin(); i != _output_ports.end(); ++i) { - if ((*i)->symbol() == symbol) { - ret = _output_ports.erase(i); - found = true; - } - } - - if ( ! found) - cerr << "WARNING: [PatchImpl::remove_port] Port not found !" << endl; - - return ret; -} - - -/** Remove all ports from ports list used in pre-processing thread. - * - * Ports are not removed from ports array for process thread (which could be - * simultaneously running). Returned is a (inputs, outputs) pair. - * - * Realtime safe. Preprocessing thread only. - */ -void -PatchImpl::clear_ports() -{ - assert(ThreadManager::current_thread_id() == THREAD_PROCESS); - - _input_ports.clear(); - _output_ports.clear(); -} - - -Raul::Array<PortImpl*>* -PatchImpl::build_ports_array() const -{ - assert(ThreadManager::current_thread_id() == THREAD_PRE_PROCESS); - - Raul::Array<PortImpl*>* const result = new Raul::Array<PortImpl*>(_input_ports.size() + _output_ports.size()); - - size_t i = 0; - - for (List<PortImpl*>::const_iterator p = _input_ports.begin(); p != _input_ports.end(); ++p,++i) - result->at(i) = *p; - - for (List<PortImpl*>::const_iterator p = _output_ports.begin(); p != _output_ports.end(); ++p,++i) - result->at(i) = *p; - - return result; -} - - -/** Find the process order for this Patch. - * - * The process order is a flat list that the patch will execute in order - * when it's run() method is called. Return value is a newly allocated list - * which the caller is reponsible to delete. Note that this function does - * NOT actually set the process order, it is returned so it can be inserted - * at the beginning of an audio cycle (by various Events). - * - * Not realtime safe. - */ -CompiledPatch* -PatchImpl::compile() const -{ - assert(ThreadManager::current_thread_id() == THREAD_PRE_PROCESS); - - //cerr << "*********** Building process order for " << path() << endl; - - CompiledPatch* const compiled_patch = new CompiledPatch();//_nodes.size()); - - for (Nodes::const_iterator i = _nodes.begin(); i != _nodes.end(); ++i) - (*i)->traversed(false); - - for (Nodes::const_iterator i = _nodes.begin(); i != _nodes.end(); ++i) { - NodeImpl* const node = (*i); - // Either a sink or connected to our output ports: - if ( ( ! node->traversed()) && node->dependants()->size() == 0) - compile_recursive(node, compiled_patch); - } - - // Traverse any nodes we didn't hit yet - for (Nodes::const_iterator i = _nodes.begin(); i != _nodes.end(); ++i) { - NodeImpl* const node = (*i); - if ( ! node->traversed()) - compile_recursive(node, compiled_patch); - } - - /*cerr << "----------------------------------------\n"; - for (size_t i=0; i < process_order->size(); ++i) { - assert(process_order->at(i)); - cerr << process_order->at(i)->path() << endl; - } - cerr << "----------------------------------------\n";*/ - - assert(compiled_patch->size() == _nodes.size()); - -#ifndef NDEBUG - for (size_t i=0; i < compiled_patch->size(); ++i) - assert(compiled_patch->at(i).node()); -#endif - - return compiled_patch; -} - - -} // namespace Ingen diff --git a/src/libs/engine/PatchImpl.hpp b/src/libs/engine/PatchImpl.hpp deleted file mode 100644 index 3629f6e5..00000000 --- a/src/libs/engine/PatchImpl.hpp +++ /dev/null @@ -1,168 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard <http://drobilla.net> - * - * 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 PATCHIMPL_H -#define PATCHIMPL_H - -#include <cstdlib> -#include <string> -#include <raul/List.hpp> -#include <raul/SharedPtr.hpp> -#include "interface/DataType.hpp" -#include "interface/Patch.hpp" -#include "NodeBase.hpp" -#include "PluginImpl.hpp" -#include "CompiledPatch.hpp" - -using std::string; - -template <typename T> class Array; -using Raul::List; - -namespace Ingen { - -namespace Shared { class Connection; } - -class ConnectionImpl; -class Engine; -class CompiledPatch; - - -/** A group of nodes in a graph, possibly polyphonic. - * - * Note that this is also a Node, just one which contains Nodes. - * Therefore infinite subpatching is possible, of polyphonic - * patches of polyphonic nodes etc. etc. - * - * \ingroup engine - */ -class PatchImpl : public NodeBase, public Ingen::Shared::Patch -{ -public: - PatchImpl(Engine& engine, - const string& name, - uint32_t poly, - PatchImpl* parent, - SampleRate srate, - size_t buffer_size, - uint32_t local_poly); - - virtual ~PatchImpl(); - - void activate(); - void deactivate(); - - void process(ProcessContext& context); - - void set_buffer_size(size_t size); - - /** Prepare for a new (internal) polyphony value. - * - * Preprocessor thread, poly is actually applied by apply_internal_poly. - * \return true on success. - */ - bool prepare_internal_poly(uint32_t poly); - - /** Apply a new (internal) polyphony value. - * - * Audio thread. - * - * \param poly Must be < the most recent value passed to prepare_internal_poly. - * \param maid Any objects no longer needed will be pushed to this - */ - bool apply_internal_poly(Raul::Maid& maid, uint32_t poly); - - // Patch specific stuff not inherited from Node - - typedef List<NodeImpl*> Nodes; - - void add_node(Nodes::Node* tn); - Nodes::Node* remove_node(const string& name); - - Nodes& nodes() { return _nodes; } - Connections& connections() { return _connections; } - - const Nodes& nodes() const { return _nodes; } - const Connections& connections() const { return _connections; } - - uint32_t num_ports() const; - - PortImpl* create_port(const string& name, DataType type, size_t buffer_size, bool is_output); - void add_input(List<PortImpl*>::Node* port) { _input_ports.push_back(port); } ///< Preprocesser thread - void add_output(List<PortImpl*>::Node* port) { _output_ports.push_back(port); } ///< Preprocessor thread - List<PortImpl*>::Node* remove_port(const string& name); - void clear_ports(); - - void add_connection(Connections::Node* c) { _connections.push_back(c); } - Connections::Node* remove_connection(const PortImpl* src_port, const PortImpl* dst_port); - - bool has_connection(const PortImpl* src_port, const PortImpl* dst_port) const; - - CompiledPatch* compiled_patch() { return _compiled_patch; } - void compiled_patch(CompiledPatch* cp) { _compiled_patch = cp; } - - Raul::Array<PortImpl*>* external_ports() { return _ports; } - void external_ports(Raul::Array<PortImpl*>* pa) { _ports = pa; } - - CompiledPatch* compile() const; - Raul::Array<PortImpl*>* build_ports_array() const; - - /** Whether to run this patch's DSP bits in the audio thread */ - bool enabled() const { return _process; } - void enable() { _process = true; } - void disable(); - - uint32_t internal_polyphony() const { return _internal_poly; } - -private: - inline void compile_recursive(NodeImpl* n, CompiledPatch* output) const; - void process_parallel(ProcessContext& context); - void process_single(ProcessContext& context); - - Engine& _engine; - uint32_t _internal_poly; - CompiledPatch* _compiled_patch; ///< Accessed in audio thread only - Connections _connections; ///< Accessed in preprocessing thread only - List<PortImpl*> _input_ports; ///< Accessed in preprocessing thread only - List<PortImpl*> _output_ports; ///< Accessed in preprocessing thread only - Nodes _nodes; ///< Accessed in preprocessing thread only - bool _process; -}; - - - -/** Private helper for compile */ -inline void -PatchImpl::compile_recursive(NodeImpl* n, CompiledPatch* output) const -{ - if (n == NULL || n->traversed()) - return; - - n->traversed(true); - assert(output != NULL); - - for (List<NodeImpl*>::iterator i = n->providers()->begin(); i != n->providers()->end(); ++i) - if ( ! (*i)->traversed() ) - compile_recursive((*i), output); - - output->push_back(CompiledNode(n, n->providers()->size(), n->dependants())); -} - - -} // namespace Ingen - -#endif // PATCHIMPL_H diff --git a/src/libs/engine/PatchPlugin.hpp b/src/libs/engine/PatchPlugin.hpp deleted file mode 100644 index a7334392..00000000 --- a/src/libs/engine/PatchPlugin.hpp +++ /dev/null @@ -1,64 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard <http://drobilla.net> - * - * 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 PATCHPLUGIN_H -#define PATCHPLUGIN_H - -#include CONFIG_H_PATH - -#include <string> -#include "PluginImpl.hpp" - -namespace Ingen { - -class NodeImpl; - - -/** Implementation of a Patch plugin. - * - * Patches don't actually work like this yet... - */ -class PatchPlugin : public PluginImpl -{ -public: - PatchPlugin(const std::string& uri, - const std::string& symbol, - const std::string& name) - : PluginImpl(Plugin::Patch, uri) - {} - - NodeImpl* instantiate(const std::string& name, - bool polyphonic, - Ingen::PatchImpl* parent, - Engine& engine) - { - return NULL; - } - - const string symbol() const { return "patch"; } - const string name() const { return "Ingen Patch"; } - -private: - const string _symbol; - const string _name; -}; - - -} // namespace Ingen - -#endif // PATCHPLUGIN_H - diff --git a/src/libs/engine/PluginImpl.cpp b/src/libs/engine/PluginImpl.cpp deleted file mode 100644 index 215cf4ce..00000000 --- a/src/libs/engine/PluginImpl.cpp +++ /dev/null @@ -1,54 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard <http://drobilla.net> - * - * 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 <iostream> -#include "PluginImpl.hpp" -#include "MidiNoteNode.hpp" -#include "MidiTriggerNode.hpp" -#include "MidiControlNode.hpp" -#include "TransportNode.hpp" - -using namespace std; - -namespace Ingen { - - -void -PluginImpl::load() -{ - if (!_module) { - //cerr << "Loading " << _library_path << " library" << endl; - _module = new Glib::Module(_library_path, Glib::MODULE_BIND_LOCAL); - if (!(*_module)) - delete _module; - } -} - - -void -PluginImpl::unload() -{ - if (_module) { - //cerr << "Unloading " << _library_path << endl; - delete _module; - _module = NULL; - } -} - - -} // namespace Ingen - diff --git a/src/libs/engine/PluginImpl.hpp b/src/libs/engine/PluginImpl.hpp deleted file mode 100644 index 0301d942..00000000 --- a/src/libs/engine/PluginImpl.hpp +++ /dev/null @@ -1,106 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard <http://drobilla.net> - * - * 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 PLUGINIMPL_H -#define PLUGINIMPL_H - -#include CONFIG_H_PATH - -#include <cstdlib> -#include <glibmm/module.h> -#include <boost/utility.hpp> -#include <dlfcn.h> -#include <string> -#include <iostream> -#include "types.hpp" -#include "interface/Plugin.hpp" - -using std::string; -using Ingen::Shared::Plugin; - -namespace Ingen { - -class PatchImpl; -class NodeImpl; -class Engine; - - -/** Implementation of a plugin (internal code, or a loaded shared library). - * - * Conceptually, a Node is an instance of this. - */ -class PluginImpl : public Ingen::Shared::Plugin, public boost::noncopyable -{ -public: - PluginImpl(Type type, const string& uri, const string library_path="") - : _type(type) - , _uri(uri) - , _library_path(library_path) - , _module(NULL) - {} - - virtual NodeImpl* instantiate(const std::string& name, - bool polyphonic, - Ingen::PatchImpl* parent, - Engine& engine) = 0; - - virtual const string symbol() const = 0; - virtual const string name() const = 0; - - const std::string& library_path() const { return _library_path; } - void library_path(const std::string& s) { _library_path = s;} - - void load(); - void unload(); - - const char* type_string() const { - if (_type == LADSPA) return "LADSPA"; - else if (_type == LV2) return "LV2"; - else if (_type == Internal) return "Internal"; - else if (_type == Patch) return "Patch"; - else return ""; - } - - const string type_uri() const { - return string("ingen:").append(type_string()); - } - - void set_type(const string& type_string) { - if (type_string == "LADSPA") _type = LADSPA; - else if (type_string == "LV2") _type = LV2; - else if (type_string == "Internal") _type = Internal; - else if (type_string == "Patch") _type = Patch; - } - - Plugin::Type type() const { return _type; } - void type(Plugin::Type t) { _type = t; } - const string& uri() const { return _uri; } - Glib::Module* module() const { return _module; } - void module(Glib::Module* module) { _module = module; } - -protected: - Plugin::Type _type; - const string _uri; - string _library_path; - Glib::Module* _module; -}; - - -} // namespace Ingen - -#endif // PLUGINIMPL_H - diff --git a/src/libs/engine/PortImpl.cpp b/src/libs/engine/PortImpl.cpp deleted file mode 100644 index 3eac65ca..00000000 --- a/src/libs/engine/PortImpl.cpp +++ /dev/null @@ -1,190 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard <http://drobilla.net> - * - * 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 <iostream> -#include <raul/Array.hpp> -#include <raul/Maid.hpp> -#include "PortImpl.hpp" -#include "NodeImpl.hpp" -#include "interface/DataType.hpp" -#include "AudioBuffer.hpp" -#include "EventBuffer.hpp" -#include "ProcessContext.hpp" -#include "SendPortActivityEvent.hpp" - -using namespace std; - -namespace Ingen { - - -PortImpl::PortImpl(NodeImpl* const node, - const string& name, - uint32_t index, - uint32_t poly, - DataType type, - const Atom& value, - size_t buffer_size) - : GraphObjectImpl(node, name, (type == DataType::AUDIO || type == DataType::CONTROL)) - , _index(index) - , _poly(poly) - , _buffer_size(buffer_size) - , _type(type) - , _value(value) - , _fixed_buffers(false) - , _broadcast(false) - , _set_by_user(false) - , _last_broadcasted_value(_value.type() == Atom::FLOAT ? _value.get_float() : 0.0f) // default? - , _context(Context::AUDIO) - , _buffers(new Raul::Array<Buffer*>(poly)) -{ - assert(node != NULL); - assert(_poly > 0); - - allocate_buffers(); - clear_buffers(); - - if (node->parent() == NULL) - _polyphonic = false; - else - _polyphonic = true; - - if (type == DataType::EVENT) - _broadcast = true; // send activity blips - - assert(_buffers->size() > 0); -} - - -PortImpl::~PortImpl() -{ - for (uint32_t i=0; i < _poly; ++i) - delete _buffers->at(i); - - delete _buffers; -} - - -bool -PortImpl::set_polyphonic(Raul::Maid& maid, bool p) -{ - if (_type == DataType::CONTROL || _type == DataType::AUDIO) - return GraphObjectImpl::set_polyphonic(maid, p); - else - return (!p); -} - - -bool -PortImpl::prepare_poly(uint32_t poly) -{ - if (!_polyphonic || !_parent->polyphonic()) - return true; - - /* FIXME: poly never goes down, harsh on memory.. */ - if (poly > _poly) { - _prepared_buffers = new Raul::Array<Buffer*>(poly, *_buffers); - for (uint32_t i = _poly; i < _prepared_buffers->size(); ++i) - _prepared_buffers->at(i) = Buffer::create(_type, _buffer_size); - } - - return true; -} - - -bool -PortImpl::apply_poly(Raul::Maid& maid, uint32_t poly) -{ - if (!_polyphonic || !_parent->polyphonic()) - return true; - - assert(poly <= _prepared_buffers->size()); - - // Apply a new set of buffers from a preceding call to prepare_poly - if (_prepared_buffers && _buffers != _prepared_buffers) { - maid.push(_buffers); - _buffers = _prepared_buffers; - } - - _poly = poly; - assert(_buffers->size() >= poly); - assert(this->poly() == poly); - - return true; -} - - -void -PortImpl::allocate_buffers() -{ - _buffers->alloc(_poly); - - for (uint32_t i=0; i < _poly; ++i) - _buffers->at(i) = Buffer::create(_type, _buffer_size); -} - - -void -PortImpl::set_buffer_size(size_t size) -{ - _buffer_size = size; - - for (uint32_t i=0; i < _poly; ++i) - _buffers->at(i)->resize(size); - - connect_buffers(); -} - - -void -PortImpl::connect_buffers() -{ - for (uint32_t i=0; i < _poly; ++i) - PortImpl::parent_node()->set_port_buffer(i, _index, buffer(i)); -} - - -void -PortImpl::clear_buffers() -{ - for (uint32_t i=0; i < _poly; ++i) - buffer(i)->clear(); -} - - -void -PortImpl::broadcast(ProcessContext& context) -{ - if (_broadcast) { - if (_type == DataType::CONTROL || _type == DataType::AUDIO) { - const Sample value = ((AudioBuffer*)buffer(0))->value_at(0); - if (value != _last_broadcasted_value) { - const SendPortValueEvent ev(context.engine(), context.start(), this, false, 0, value); - context.event_sink().write(sizeof(ev), &ev); - _last_broadcasted_value = value; - } - } else if (_type == DataType::EVENT) { - if (((EventBuffer*)buffer(0))->event_count() > 0) { - const SendPortActivityEvent ev(context.engine(), context.start(), this); - context.event_sink().write(sizeof(ev), &ev); - } - } - } -} - - - -} // namespace Ingen diff --git a/src/libs/engine/PortImpl.hpp b/src/libs/engine/PortImpl.hpp deleted file mode 100644 index be96a910..00000000 --- a/src/libs/engine/PortImpl.hpp +++ /dev/null @@ -1,147 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard <http://drobilla.net> - * - * 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 PORTIMPL_H -#define PORTIMPL_H - -#include <cstdlib> -#include <string> -#include <raul/Array.hpp> -#include "interface/Port.hpp" -#include "types.hpp" -#include "GraphObjectImpl.hpp" -#include "interface/DataType.hpp" -#include "Buffer.hpp" -#include "Context.hpp" - -namespace Raul { class Maid; class Atom; } - -namespace Ingen { - -class NodeImpl; -class Buffer; -class ProcessContext; - - -/** A port on a Node. - * - * This is a non-template abstract base class, which basically exists so - * things can pass around Port pointers and not have to worry about type, - * templates, etc. - * - * \ingroup engine - */ -class PortImpl : public GraphObjectImpl, public Ingen::Shared::Port -{ -public: - virtual ~PortImpl(); - - /** A port's parent is always a node, so static cast should be safe */ - NodeImpl* parent_node() const { return (NodeImpl*)_parent; } - - bool set_polyphonic(Raul::Maid& maid, bool p); - - /** Prepare for a new (external) polyphony value. - * - * Preprocessor thread, poly is actually applied by apply_poly. - */ - virtual bool prepare_poly(uint32_t poly); - - /** Apply a new polyphony value. - * - * Audio thread. - * - * \param poly Must be < the most recent value passed to prepare_poly. - */ - virtual bool apply_poly(Raul::Maid& maid, uint32_t poly); - - const Raul::Atom& value() const { return _value; } - void set_value(const Raul::Atom& v) { _value = v; } - - inline Buffer* buffer(uint32_t voice) const { - Buffer* const buf = _buffers->at(voice); - if (buf->is_joined()) { - assert(buf->joined_buffer()); - return buf->joined_buffer(); - } else { - return buf; - } - } - - /** Called once per process cycle */ - virtual void pre_process(ProcessContext& context) = 0; - virtual void process(ProcessContext& context) {}; - virtual void post_process(ProcessContext& context) = 0; - - /** Empty buffer contents completely (ie silence) */ - virtual void clear_buffers(); - - virtual bool is_input() const = 0; - virtual bool is_output() const = 0; - - uint32_t index() const { return _index; } - uint32_t poly() const { return _poly; } - DataType type() const { return _type; } - size_t buffer_size() const { return _buffer_size; } - - virtual void set_buffer_size(size_t size); - - void fixed_buffers(bool b) { _fixed_buffers = b; } - bool fixed_buffers() { return _fixed_buffers; } - - void broadcast(bool b) { _broadcast = b; } - bool broadcast() { return _broadcast; } - - void raise_set_by_user_flag() { _set_by_user = true; } - - Context::ID context() const { return _context; } - void set_context(Context::ID c) { _context = c; } - -protected: - PortImpl(NodeImpl* node, - const std::string& name, - uint32_t index, - uint32_t poly, - DataType type, - const Raul::Atom& value, - size_t buffer_size); - - virtual void allocate_buffers(); - virtual void connect_buffers(); - virtual void broadcast(ProcessContext& context); - - uint32_t _index; - uint32_t _poly; - uint32_t _buffer_size; - DataType _type; - Raul::Atom _value; - bool _fixed_buffers; - bool _broadcast; - bool _set_by_user; - Sample _last_broadcasted_value; - - Context::ID _context; - Raul::Array<Buffer*>* _buffers; - - // Dynamic polyphony - Raul::Array<Buffer*>* _prepared_buffers; -}; - - -} // namespace Ingen - -#endif // PORTIMPL_H diff --git a/src/libs/engine/PostProcessor.cpp b/src/libs/engine/PostProcessor.cpp deleted file mode 100644 index a50ca275..00000000 --- a/src/libs/engine/PostProcessor.cpp +++ /dev/null @@ -1,73 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard <http://drobilla.net> - * - * 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 <cassert> -#include <iostream> -#include <pthread.h> -#include <raul/SRSWQueue.hpp> -//#include <raul/Maid.hpp> -#include "events/SendPortValueEvent.hpp" -#include "Event.hpp" -#include "PostProcessor.hpp" -#include "Engine.hpp" -#include "AudioDriver.hpp" -#include "ProcessContext.hpp" - -using namespace std; - -namespace Ingen { - - -PostProcessor::PostProcessor(Engine& engine, size_t queue_size) - : _engine(engine) - , _max_time(0) - , _events(queue_size) - , _event_buffer_size(sizeof(SendPortValueEvent)) // FIXME: make generic - , _event_buffer((uint8_t*)malloc(_event_buffer_size)) -{ -} - - -void -PostProcessor::process() -{ - const FrameTime end_time = _max_time.get(); - - /* Process any audio thread generated events */ - /* FIXME: process events from all threads if parallel */ - - while (_engine.audio_driver()->context().event_sink().read( - _event_buffer_size, _event_buffer)) { - if (((Event*)_event_buffer)->time() > end_time) - break; // FIXME: loses event? - ((Event*)_event_buffer)->post_process(); - } - - /* Process normal events */ - while ( ! _events.empty()) { - Event* const ev = _events.front(); - if (ev->time() > end_time) - break; - _events.pop(); - assert(ev); - ev->post_process(); - delete ev; - } -} - - -} // namespace Ingen diff --git a/src/libs/engine/PostProcessor.hpp b/src/libs/engine/PostProcessor.hpp deleted file mode 100644 index 3d51136d..00000000 --- a/src/libs/engine/PostProcessor.hpp +++ /dev/null @@ -1,73 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard <http://drobilla.net> - * - * 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 POSTPROCESSOR_H -#define POSTPROCESSOR_H - -#include <pthread.h> -#include "types.hpp" -#include <raul/SRSWQueue.hpp> -//#include <raul/Slave.hpp> - -//namespace Raul { class Maid; } - -namespace Ingen { - -class Event; -class Engine; - - -/** Processor for Events after leaving the audio thread. - * - * The audio thread pushes events to this when it is done with them (which - * is realtime-safe), which signals the processing thread through a semaphore - * to handle the event and pass it on to the Maid. - * - * Update: This is all run from main_iteration now to solve scripting - * thread issues. Not sure if this is permanent/ideal or not... - * - * \ingroup engine - */ -class PostProcessor //: public Raul::Slave -{ -public: - PostProcessor(Engine& engine, /*Raul::Maid& maid, */size_t queue_size); - - /** Push an event on to the process queue, realtime-safe, not thread-safe. */ - inline void push(Event* const ev) { _events.push(ev); } - - /** Post-process and delete all pending events */ - void process(); - - /** Set the latest event time that should be post-processed */ - void set_end_time(FrameTime time) { _max_time = time; } - -private: - Engine& _engine; - Raul::AtomicInt _max_time; - //Raul::Maid& _maid; - Raul::SRSWQueue<Event*> _events; - uint32_t _event_buffer_size; - uint8_t* _event_buffer; - - //virtual void _whipped(); -}; - - -} // namespace Ingen - -#endif // POSTPROCESSOR_H diff --git a/src/libs/engine/ProcessContext.hpp b/src/libs/engine/ProcessContext.hpp deleted file mode 100644 index 57677126..00000000 --- a/src/libs/engine/ProcessContext.hpp +++ /dev/null @@ -1,71 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard <http://drobilla.net> - * - * 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 PROCESSCONTEXT_H -#define PROCESSCONTEXT_H - -#include "EventSink.hpp" -#include "Context.hpp" - -namespace Ingen { - - -/** Context of a process() call. - * - * This is used to pass whatever information a GraphObject might need to - * process in the audio thread, e.g. the available thread pool, sink for - * events (generated in the audio thread, not user initiated events), etc. - * - * Note the distinction between nframes and start/end. If transport speed - * != 1.0, end-start != nframes (though currently that is never the case, it - * may be in the future with sequencerey things). - * - * \ingroup engine - */ -class ProcessContext : public Context -{ -public: - ProcessContext(Engine& engine) - : Context(engine, AUDIO) - , _event_sink(engine, 1024) // FIXME: size? - {} - - void set_time_slice(SampleCount nframes, FrameTime start, FrameTime end) { - _nframes = nframes; - _start = start; - _end = end; - } - - inline SampleCount nframes() const { return _nframes; } - inline FrameTime start() const { return _start; } - inline FrameTime end() const { return _end; } - inline const EventSink& event_sink() const { return _event_sink; } - inline EventSink& event_sink() { return _event_sink; } - -private: - SampleCount _nframes; ///< Number of actual time (Jack) frames this cycle - FrameTime _start; ///< Start frame of this cycle, timeline relative - FrameTime _end; ///< End frame of this cycle, timeline relative - EventSink _event_sink; ///< Sink for events generated in the audio thread -}; - - - -} // namespace Ingen - -#endif // PROCESSCONTEXT_H - diff --git a/src/libs/engine/ProcessSlave.cpp b/src/libs/engine/ProcessSlave.cpp deleted file mode 100644 index c7c868e8..00000000 --- a/src/libs/engine/ProcessSlave.cpp +++ /dev/null @@ -1,75 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard <http://drobilla.net> - * - * 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 <iostream> -#include "ProcessSlave.hpp" -#include "NodeImpl.hpp" -#include "CompiledPatch.hpp" - -using namespace std; - -namespace Ingen { - - -uint32_t ProcessSlave::_next_id = 0; - - -void -ProcessSlave::_whipped() -{ - assert(_compiled_patch); - CompiledPatch* const cp = _compiled_patch; - - /* Iterate over all nodes attempting to run immediately or block then run, - * until we've been through the entire array without getting a lock, - * and thus are finished this cycle. - */ - - size_t num_finished = 0; // Number of consecutive finished nodes hit - - while (_state == STATE_RUNNING) { - - CompiledNode& n = (*cp)[_index]; - - if (n.node()->process_lock()) { - - n.node()->wait_for_input(n.n_providers()); - - n.node()->process(_process_context); - - /* Signal dependants their input is ready */ - for (size_t i=0; i < n.dependants().size(); ++i) - n.dependants()[i]->signal_input_ready(); - - num_finished = 1; - } else { - ++num_finished; - } - - _index = (_index + 1) % cp->size(); - - if (num_finished >= cp->size()) - break; - } - - _index = 0; - _compiled_patch = NULL; - _state = STATE_FINISHED; -} - - -} // namespace Ingen diff --git a/src/libs/engine/ProcessSlave.hpp b/src/libs/engine/ProcessSlave.hpp deleted file mode 100644 index 40becd48..00000000 --- a/src/libs/engine/ProcessSlave.hpp +++ /dev/null @@ -1,100 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard <http://drobilla.net> - * - * 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 PROCESS_SLAVE_HPP -#define PROCESS_SLAVE_HPP - -#include CONFIG_H_PATH - -#include <sstream> -#include <raul/Slave.hpp> -#include <raul/Array.hpp> -#include <raul/AtomicInt.hpp> -#include "ProcessContext.hpp" -#include "types.hpp" - -namespace Ingen { - -class NodeImpl; -class CompiledPatch; - - -class ProcessSlave : protected Raul::Slave { -public: - ProcessSlave(Engine& engine, bool realtime) - : _id(_next_id++) - , _index(0) - , _state(STATE_FINISHED) - , _compiled_patch(NULL) - , _process_context(engine) - { - std::stringstream ss; - ss << "Process Slave "; - ss << _id; - set_name(ss.str()); - - start(); - - if (realtime) - set_scheduling(SCHED_FIFO, 40); - } - - ~ProcessSlave() { - stop(); - } - - inline void whip(CompiledPatch* compiled_patch, uint32_t start_index, ProcessContext& context) { - assert(_state == STATE_FINISHED); - _index = start_index; - _state = STATE_RUNNING; - _compiled_patch = compiled_patch; - _process_context.set_time_slice(context.nframes(), context.start(), context.end()); - - Raul::Slave::whip(); - } - - inline void finish() { - while (_state.get() != STATE_FINISHED) - _state.compare_and_exchange(STATE_RUNNING, STATE_FINISH_SIGNALLED); - } - - inline uint32_t id() const { return _id; } - inline const ProcessContext& context() const { return _process_context; } - inline ProcessContext& context() { return _process_context; } - -private: - - void _whipped(); - - static uint32_t _next_id; - - static const int STATE_RUNNING = 0; - static const int STATE_FINISH_SIGNALLED = 1; - static const int STATE_FINISHED = 2; - - uint32_t _id; - uint32_t _index; - Raul::AtomicInt _state; - CompiledPatch* _compiled_patch; - ProcessContext _process_context; -}; - - -} // namespace Ingen - -#endif // PROCESS_SLAVE_HPP - diff --git a/src/libs/engine/QueuedEngineInterface.cpp b/src/libs/engine/QueuedEngineInterface.cpp deleted file mode 100644 index 962410b2..00000000 --- a/src/libs/engine/QueuedEngineInterface.cpp +++ /dev/null @@ -1,370 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard <http://drobilla.net> - * - * 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 <iostream> -#include "QueuedEngineInterface.hpp" -#include CONFIG_H_PATH -#include "QueuedEventSource.hpp" -#include "events.hpp" -#include "Engine.hpp" -#include "AudioDriver.hpp" - -namespace Ingen { - -QueuedEngineInterface::QueuedEngineInterface(Engine& engine, size_t queued_size, size_t stamped_size) - : QueuedEventSource(queued_size, stamped_size) - , _responder(new Responder(NULL, 0)) - , _engine(engine) - , _in_bundle(false) -{ -} - - -SampleCount -QueuedEngineInterface::now() const -{ - // Exactly one cycle latency (some could run ASAP if we get lucky, but not always, and a slight - // constant latency is far better than jittery lower (average) latency - assert(_engine.audio_driver()); - return _engine.audio_driver()->frame_time() + _engine.audio_driver()->buffer_size(); -} - - -void -QueuedEngineInterface::set_next_response_id(int32_t id) -{ - if (_responder) - _responder->set_id(id); -} - - -void -QueuedEngineInterface::disable_responses() -{ - _responder->set_client(NULL); - _responder->set_id(0); -} - - -/* *** EngineInterface implementation below here *** */ - - -void -QueuedEngineInterface::register_client(ClientInterface* client) -{ - push_queued(new RegisterClientEvent(_engine, _responder, now(), client->uri(), client)); - if (!_responder) { - _responder = SharedPtr<Responder>(new Responder(client, 1)); - } else { - _responder->set_id(1); - _responder->set_client(client); - } -} - - -void -QueuedEngineInterface::unregister_client(const string& uri) -{ - push_queued(new UnregisterClientEvent(_engine, _responder, now(), uri)); - if (_responder && _responder->client() && _responder->client()->uri() == uri) { - _responder->set_id(0); - _responder->set_client(NULL); - } -} - - - -// Engine commands -void -QueuedEngineInterface::load_plugins() -{ - push_queued(new LoadPluginsEvent(_engine, _responder, now(), this)); -} - - -void -QueuedEngineInterface::activate() -{ - QueuedEventSource::activate(); - push_queued(new PingQueuedEvent(_engine, _responder, now())); -} - - -void -QueuedEngineInterface::deactivate() -{ - push_queued(new DeactivateEvent(_engine, _responder, now())); -} - - -void -QueuedEngineInterface::quit() -{ - _responder->respond_ok(); - _engine.quit(); -} - - -// Bundle commands - -void -QueuedEngineInterface::bundle_begin() -{ - _in_bundle = true; -} - - -void -QueuedEngineInterface::bundle_end() -{ - _in_bundle = false; -} - - -// Object commands - -void -QueuedEngineInterface::new_patch(const string& path, - uint32_t poly) -{ - push_queued(new CreatePatchEvent(_engine, _responder, now(), path, poly)); -} - - -// FIXME: use index -void QueuedEngineInterface::new_port(const string& path, - uint32_t index, - const string& data_type, - bool direction) -{ - push_queued(new CreatePortEvent(_engine, _responder, now(), path, data_type, direction, this)); -} - - -void -QueuedEngineInterface::new_node(const string& path, - const string& plugin_uri) -{ - push_queued(new CreateNodeEvent(_engine, _responder, now(), - path, plugin_uri, true)); // FIXME: polyphonic by default -} - - -void -QueuedEngineInterface::new_node_deprecated(const string& path, - const string& plugin_type, - const string& plugin_lib, - const string& plugin_label) -{ - push_queued(new CreateNodeEvent(_engine, _responder, now(), - path, plugin_type, plugin_lib, plugin_label, true)); // FIXME: polyphonic by default -} - -void -QueuedEngineInterface::rename(const string& old_path, - const string& new_symbol) -{ - push_queued(new RenameEvent(_engine, _responder, now(), old_path, new_symbol)); -} - - -void -QueuedEngineInterface::destroy(const string& path) -{ - push_queued(new DestroyEvent(_engine, _responder, now(), this, path)); -} - - -void -QueuedEngineInterface::clear_patch(const string& patch_path) -{ - push_queued(new ClearPatchEvent(_engine, _responder, now(), this, patch_path)); -} - - -void -QueuedEngineInterface::set_polyphony(const string& patch_path, uint32_t poly) -{ - push_queued(new SetPolyphonyEvent(_engine, _responder, now(), this, patch_path, poly)); -} - - -void -QueuedEngineInterface::set_polyphonic(const string& path, bool poly) -{ - push_queued(new SetPolyphonicEvent(_engine, _responder, now(), this, path, poly)); -} - - -void -QueuedEngineInterface::connect(const string& src_port_path, - const string& dst_port_path) -{ - push_queued(new ConnectionEvent(_engine, _responder, now(), src_port_path, dst_port_path)); - -} - - -void -QueuedEngineInterface::disconnect(const string& src_port_path, - const string& dst_port_path) -{ - push_queued(new DisconnectionEvent(_engine, _responder, now(), src_port_path, dst_port_path)); -} - - -void -QueuedEngineInterface::disconnect_all(const string& patch_path, - const string& node_path) -{ - push_queued(new DisconnectAllEvent(_engine, _responder, now(), patch_path, node_path)); -} - - -void -QueuedEngineInterface::set_port_value(const string& port_path, - const Raul::Atom& value) -{ - push_queued(new SetPortValueEvent(_engine, _responder, true, now(), port_path, value)); -} - - -void -QueuedEngineInterface::set_voice_value(const string& port_path, - uint32_t voice, - const Raul::Atom& value) -{ - push_queued(new SetPortValueEvent(_engine, _responder, true, now(), voice, port_path, value)); -} - - -void -QueuedEngineInterface::set_program(const string& node_path, - uint32_t bank, - uint32_t program) -{ - std::cerr << "FIXME: set program" << std::endl; -} - - -void -QueuedEngineInterface::midi_learn(const string& node_path) -{ - push_queued(new MidiLearnEvent(_engine, _responder, now(), node_path)); -} - - -void -QueuedEngineInterface::set_variable(const string& path, - const string& predicate, - const Atom& value) -{ - push_queued(new SetMetadataEvent(_engine, _responder, now(), false, path, predicate, value)); -} - - -void -QueuedEngineInterface::set_property(const string& path, - const string& predicate, - const Atom& value) -{ - // FIXME: implement generically - if (predicate == "ingen:enabled") { - if (value.type() == Atom::BOOL) { - push_queued(new EnablePatchEvent(_engine, _responder, now(), path, value.get_bool())); - return; - } - } else if (predicate == "ingen:polyphonic") { - if (value.type() == Atom::BOOL) { - push_queued(new SetPolyphonicEvent(_engine, _responder, now(), this, path, value.get_bool())); - return; - } - } else if (predicate == "ingen:polyphony") { - if (value.type() == Atom::INT) { - push_queued(new SetPolyphonyEvent(_engine, _responder, now(), this, path, value.get_int32())); - return; - } - } else { - push_queued(new SetMetadataEvent(_engine, _responder, now(), true, path, predicate, value)); - } -} - -// Requests // - -void -QueuedEngineInterface::ping() -{ - if (_engine.activated()) { - push_queued(new PingQueuedEvent(_engine, _responder, now())); - } else if (_responder) { - _responder->respond_ok(); - } -} - - -void -QueuedEngineInterface::request_plugin(const string& uri) -{ - push_queued(new RequestPluginEvent(_engine, _responder, now(), uri)); -} - - -void -QueuedEngineInterface::request_object(const string& path) -{ - push_queued(new RequestObjectEvent(_engine, _responder, now(), path)); -} - - -void -QueuedEngineInterface::request_port_value(const string& port_path) -{ - push_queued(new RequestPortValueEvent(_engine, _responder, now(), port_path)); -} - - -void -QueuedEngineInterface::request_variable(const string& object_path, const string& key) -{ - push_queued(new RequestMetadataEvent(_engine, _responder, now(), false, object_path, key)); -} - - -void -QueuedEngineInterface::request_property(const string& object_path, const string& key) -{ - push_queued(new RequestMetadataEvent(_engine, _responder, now(), true, object_path, key)); -} - - -void -QueuedEngineInterface::request_plugins() -{ - push_queued(new RequestPluginsEvent(_engine, _responder, now())); -} - - -void -QueuedEngineInterface::request_all_objects() -{ - push_queued(new RequestAllObjectsEvent(_engine, _responder, now())); -} - - -} // namespace Ingen - - diff --git a/src/libs/engine/QueuedEngineInterface.hpp b/src/libs/engine/QueuedEngineInterface.hpp deleted file mode 100644 index 73c790c8..00000000 --- a/src/libs/engine/QueuedEngineInterface.hpp +++ /dev/null @@ -1,170 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard <http://drobilla.net> - * - * 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 QUEUEDENGINEINTERFACE_H -#define QUEUEDENGINEINTERFACE_H - -#include <inttypes.h> -#include <string> -#include <memory> -#include <raul/SharedPtr.hpp> -#include "interface/EngineInterface.hpp" -#include "interface/ClientInterface.hpp" -#include "Responder.hpp" -#include "QueuedEventSource.hpp" -#include "Engine.hpp" -using std::string; - -namespace Ingen { - -using Shared::ClientInterface; -using Shared::EngineInterface; -class Engine; - - -/** A queued (preprocessed) event source / interface. - * - * This is the bridge between the EngineInterface presented to the client, and - * the EventSource that needs to be presented to the AudioDriver. - * - * This is sort of a state machine, \ref set_responder sets the Responder that - * will be used to send the response from all future function calls. Stateless - * protocols like UDP/OSC can use this to set a different response address for - * each event (eg incoming UDP port), but engine/client interfaces that don't - * need to change an 'address' constantly can just set it once on initialisation. - * Blocking control interfaces can be made by setting a Responder which signals - * the caller when the 'response' is 'sent'. - * - * If you do not register a responder, you have no way of knowing if your calls - * are successful. - * - * FIXME: this isn't really "queued" entirely, since some events aren't queued - * events and get pushed directly into the realtime event queue. Should that - * be separated into a different interface/client? - */ -class QueuedEngineInterface : public QueuedEventSource, public EngineInterface -{ -public: - QueuedEngineInterface(Engine& engine, size_t queued_size, size_t stamped_size); - virtual ~QueuedEngineInterface() {} - - std::string uri() const { return "ingen:internal"; } - - void set_next_response_id(int32_t id); - - // Client registration - virtual void register_client(ClientInterface* client); - virtual void unregister_client(const string& uri); - - // Engine commands - virtual void load_plugins(); - virtual void activate(); - virtual void deactivate(); - virtual void quit(); - - // Bundles - virtual void bundle_begin(); - virtual void bundle_end(); - - // Object commands - - virtual void new_patch(const string& path, - uint32_t poly); - - virtual void new_port(const string& path, - uint32_t index, - const string& data_type, - bool direction); - - virtual void new_node(const string& path, - const string& plugin_uri); - - /** FIXME: DEPRECATED, REMOVE */ - virtual void new_node_deprecated(const string& path, - const string& plugin_type, - const string& lib_path, - const string& plug_label); - - virtual void rename(const string& old_path, - const string& new_name); - - virtual void destroy(const string& path); - - virtual void clear_patch(const string& patch_path); - - virtual void set_polyphony(const string& patch_path, uint32_t poly); - - virtual void set_polyphonic(const string& path, bool poly); - - virtual void connect(const string& src_port_path, - const string& dst_port_path); - - virtual void disconnect(const string& src_port_path, - const string& dst_port_path); - - virtual void disconnect_all(const string& patch_path, - const string& node_path); - - virtual void set_port_value(const string& port_path, - const Raul::Atom& value); - - virtual void set_voice_value(const string& port_path, - uint32_t voice, - const Raul::Atom& value); - - virtual void set_program(const string& node_path, - uint32_t bank, - uint32_t program); - - virtual void midi_learn(const string& node_path); - - virtual void set_variable(const string& path, - const string& predicate, - const Raul::Atom& value); - - virtual void set_property(const string& path, - const string& predicate, - const Raul::Atom& value); - - // Requests // - - virtual void ping(); - virtual void request_plugin(const string& uri); - virtual void request_object(const string& path); - virtual void request_port_value(const string& port_path); - virtual void request_variable(const string& object_path, const string& key); - virtual void request_property(const string& object_path, const string& key); - virtual void request_plugins(); - virtual void request_all_objects(); - -protected: - - virtual void disable_responses(); - - SharedPtr<Responder> _responder; ///< NULL if responding disabled - Engine& _engine; - bool _in_bundle; ///< True iff a bundle is currently being received - -private: - SampleCount now() const; -}; - - -} // namespace Ingen - -#endif // QUEUEDENGINEINTERFACE_H - diff --git a/src/libs/engine/QueuedEvent.cpp b/src/libs/engine/QueuedEvent.cpp deleted file mode 100644 index 8ed6fa02..00000000 --- a/src/libs/engine/QueuedEvent.cpp +++ /dev/null @@ -1,50 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard <http://drobilla.net> - * - * 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 "QueuedEvent.hpp" -#include "ThreadManager.hpp" -#include "ProcessContext.hpp" - -namespace Ingen { - - -void -QueuedEvent::pre_process() -{ - assert(ThreadManager::current_thread_id() == THREAD_PRE_PROCESS); - assert(_pre_processed == false); - _pre_processed = true; -} - - -void -QueuedEvent::execute(ProcessContext& context) -{ - assert(_pre_processed); - assert(_time <= context.end()); - - // Didn't prepare in time. QueuedEvents aren't (necessarily) sample accurate - // so just run at the beginning of this cycle - if (_time <= context.start()) - _time = context.start(); - - Event::execute(context); -} - - -} // namespace Ingen - diff --git a/src/libs/engine/QueuedEvent.hpp b/src/libs/engine/QueuedEvent.hpp deleted file mode 100644 index e616d269..00000000 --- a/src/libs/engine/QueuedEvent.hpp +++ /dev/null @@ -1,83 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard <http://drobilla.net> - * - * 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 QUEUEDEVENT_H -#define QUEUEDEVENT_H - -#include "Event.hpp" - -namespace Ingen { - -class QueuedEventSource; - - -/** An Event with a not-time-critical preprocessing stage. - * - * These events are events that aren't able to be executed immediately by the - * Jack thread (because they allocate memory or whatever). They are pushed - * on to the QueuedEventQueue where they are preprocessed then pushed on - * to the realtime Event Queue when they are ready. - * - * Lookups for these events should go in the pre_process() method, since they are - * not time critical and shouldn't waste time in the audio thread doing - * lookups they can do beforehand. (This applies for any expensive operation that - * could be done before the execute() method). - * - * \ingroup engine - */ -class QueuedEvent : public Event -{ -public: - /** Process this event into a realtime-suitable event. - */ - virtual void pre_process(); - - virtual void execute(ProcessContext& context); - - /** If this event blocks the prepare phase of other slow events */ - bool is_blocking() { return _blocking; } - - bool is_prepared() { return _pre_processed; } - -protected: - QueuedEvent(Engine& engine, - SharedPtr<Responder> responder, - FrameTime time, - bool blocking = false, - QueuedEventSource* source = NULL) - : Event(engine, responder, time) - , _pre_processed(false), _blocking(blocking), _source(source) - { - if (blocking) - assert(_source); - } - - // NULL event base (for internal events only!) - QueuedEvent(Engine& engine) - : Event(engine, SharedPtr<Responder>(), 0) - , _pre_processed(false), _blocking(false), _source(NULL) - {} - - bool _pre_processed; - bool _blocking; - QueuedEventSource* _source; -}; - - -} // namespace Ingen - -#endif // QUEUEDEVENT_H diff --git a/src/libs/engine/QueuedEventSource.cpp b/src/libs/engine/QueuedEventSource.cpp deleted file mode 100644 index 69ab805a..00000000 --- a/src/libs/engine/QueuedEventSource.cpp +++ /dev/null @@ -1,183 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard <http://drobilla.net> - * - * 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 <sys/mman.h> -#include <iostream> -#include "QueuedEventSource.hpp" -#include "QueuedEvent.hpp" -#include "PostProcessor.hpp" -#include "ThreadManager.hpp" -#include "ProcessContext.hpp" - -using namespace std; - -namespace Ingen { - - -QueuedEventSource::QueuedEventSource(size_t queued_size, size_t stamped_size) - : _front(0) - , _back(0) - , _prepared_back(0) - , _size(queued_size+1) - , _blocking_semaphore(0) - , _full_semaphore(0) - , _stamped_queue(stamped_size) -{ - _events = (QueuedEvent**)calloc(_size, sizeof(QueuedEvent*)); - - mlock(_events, _size * sizeof(QueuedEvent*)); - - Thread::set_context(THREAD_PRE_PROCESS); - assert(context() == THREAD_PRE_PROCESS); - - set_name("QueuedEventSource"); -} - - -QueuedEventSource::~QueuedEventSource() -{ - Thread::stop(); - - free(_events); -} - - -/** Push an unprepared event onto the queue. - */ -void -QueuedEventSource::push_queued(QueuedEvent* const ev) -{ - assert(!ev->is_prepared()); - - unsigned back = _back.get(); - bool full = (((_front.get() - back + _size) % _size) == 1); - while (full) { - whip(); - cerr << "WARNING: Event queue full. Waiting..." << endl; - _full_semaphore.wait(); - back = _back.get(); - full = (((_front.get() - back + _size) % _size) == 1); - } - - assert(_events[back] == NULL); - _events[back] = ev; - _back = (back + 1) % _size; - whip(); -} - - -/** Process all events for a cycle. - * - * Executed events will be pushed to @a dest. - */ -void -QueuedEventSource::process(PostProcessor& dest, ProcessContext& context) -{ - assert(ThreadManager::current_thread_id() == THREAD_PROCESS); - - Event* ev = NULL; - - /* Limit the maximum number of queued events to process per cycle. This - * makes the process callback (more) realtime-safe by preventing being - * choked by events coming in faster than they can be processed. - * FIXME: test this and figure out a good value */ - const unsigned int MAX_QUEUED_EVENTS = context.nframes() / 100; - - unsigned int num_events_processed = 0; - - /* FIXME: Merge these next two loops into one */ - - while ((ev = pop_earliest_queued_before(context.end()))) { - ev->execute(context); - dest.push(ev); - if (++num_events_processed > MAX_QUEUED_EVENTS) - break; - } - - while ((ev = pop_earliest_stamped_before(context.end()))) { - ev->execute(context); - dest.push(ev); - ++num_events_processed; - } - - if (_full_semaphore.has_waiter() && num_events_processed > 0) - _full_semaphore.post(); - - /*if (num_events_processed > 0) - dest.whip();*/ - //else - // cerr << "NO PROC: queued: " << unprepared_events() << ", stamped: " << !_stamped_queue.empty() << endl; -} - - -/** Pops the prepared event at the front of the prepare queue, if it exists. - * - * This method will only pop events that have been prepared, and are - * stamped before the time passed. In other words, it may return NULL - * even if there are events pending in the queue. The events returned are - * actually QueuedEvents, but after this they are "normal" events and the - * engine deals with them just like a realtime in-band event. The engine will - * not use the timestamps of the returned events in any way, since it is free - * to execute these non-time-stamped events whenever it wants (at whatever rate - * it wants). - */ -Event* -QueuedEventSource::pop_earliest_queued_before(const SampleCount time) -{ - assert(ThreadManager::current_thread_id() == THREAD_PROCESS); - - const unsigned front = _front.get(); - QueuedEvent* const front_event = _events[front]; - - // Pop - if (front_event && front_event->is_prepared() && front_event->time() < time) { - _events[front] = NULL; - _front = (front + 1) % _size; - return front_event; - } else { - return NULL; - } -} - - -// Private // - - -/** Pre-process a single event */ -void -QueuedEventSource::_whipped() -{ - const unsigned prepared_back = _prepared_back.get(); - QueuedEvent* const ev = _events[prepared_back]; - if (!ev) - return; - - assert(!ev->is_prepared()); - ev->pre_process(); - assert(ev->is_prepared()); - - _prepared_back = (prepared_back + 1) % _size; - - // If event was blocking, wait for event to being run through the - // process thread before preparing the next event - if (ev->is_blocking()) - _blocking_semaphore.wait(); -} - - -} // namespace Ingen - diff --git a/src/libs/engine/QueuedEventSource.hpp b/src/libs/engine/QueuedEventSource.hpp deleted file mode 100644 index 6dea092d..00000000 --- a/src/libs/engine/QueuedEventSource.hpp +++ /dev/null @@ -1,128 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard <http://drobilla.net> - * - * 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 QUEUEDEVENTSOURCE_H -#define QUEUEDEVENTSOURCE_H - -#include <cstdlib> -#include <pthread.h> -#include "types.hpp" -#include <raul/Semaphore.hpp> -#include <raul/AtomicInt.hpp> -#include <raul/SRSWQueue.hpp> -#include <raul/Slave.hpp> -#include "Event.hpp" -#include "EventSource.hpp" - -using Raul::AtomicInt; - -namespace Ingen { - -class QueuedEvent; -class PostProcessor; - - -/** Queue of events that need processing before reaching the audio thread. - * - * Implemented as a deque (ringbuffer) in a circular array. Pushing and - * popping are threadsafe, as long as a single thread pushes and a single - * thread pops (ie this data structure is threadsafe, but the push and pop - * methods themselves are not). Creating an instance of this class spawns - * a pre-processing thread to prepare queued events. - * - * This class is it's own slave. :) - */ -class QueuedEventSource : public EventSource, protected Raul::Slave -{ -public: - QueuedEventSource(size_t queued_size, size_t stamped_size); - ~QueuedEventSource(); - - void activate() { Slave::start(); } - void deactivate() { Slave::stop(); } - - void process(PostProcessor& dest, ProcessContext& context); - - void unblock(); - -protected: - void push_queued(QueuedEvent* const ev); - inline void push_stamped(Event* const ev) { _stamped_queue.push(ev); } - Event* pop_earliest_queued_before(const SampleCount time); - inline Event* pop_earliest_stamped_before(const SampleCount time); - - inline bool unprepared_events() { return (_prepared_back.get() != _back.get()); } - - virtual void _whipped(); ///< Prepare 1 event - -private: - // Note that it's crucially important which functions access which of these - // variables, to maintain threadsafeness. - - //(FIXME: make this a separate class?) - // 2-part queue for events that require pre-processing: - AtomicInt _front; ///< Front of queue - AtomicInt _back; ///< Back of entire queue (1 past index of back element) - AtomicInt _prepared_back; ///< Back of prepared section (1 past index of back prepared element) - const size_t _size; - QueuedEvent** _events; - Raul::Semaphore _blocking_semaphore; - - Raul::Semaphore _full_semaphore; - - /** Queue for timestamped events (no pre-processing). */ - Raul::SRSWQueue<Event*> _stamped_queue; -}; - - -/** Pops the realtime (timestamped, not preprocessed) event off the realtime queue. - * - * Engine will use the sample timestamps of returned events directly and execute the - * event with sample accuracy. Timestamps in the past will be bumped forward to - * the beginning of the cycle (offset 0), when eg. skipped cycles occur. - */ -inline Event* -QueuedEventSource::pop_earliest_stamped_before(const SampleCount time) -{ - Event* ret = NULL; - - if (!_stamped_queue.empty()) { - if (_stamped_queue.front()->time() < time) { - ret = _stamped_queue.front(); - _stamped_queue.pop(); - } - } - - return ret; -} - - -/** Signal that the blocking event is finished. - * - * When this is called preparing will resume. This MUST be called by - * blocking events in their post_process() method. - */ -inline void -QueuedEventSource::unblock() -{ - _blocking_semaphore.post(); -} - - -} // namespace Ingen - -#endif // QUEUEDEVENTSOURCE_H diff --git a/src/libs/engine/Responder.hpp b/src/libs/engine/Responder.hpp deleted file mode 100644 index 80d2e24c..00000000 --- a/src/libs/engine/Responder.hpp +++ /dev/null @@ -1,71 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard <http://drobilla.net> - * - * 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 RESPONDER_H -#define RESPONDER_H - -#include <inttypes.h> -#include <string> -#include <raul/SharedPtr.hpp> -#include "interface/ClientInterface.hpp" - -namespace Ingen { - - -/** Class to handle responding to clients. - * - * This is a glorified std::pair<ClientInterface*, int32_t> for replying - * to numbered messages from a client. - * - * For responses that involve more messages, the response will come first - * followed by the messages (eg object notifications, values, errors, etc.) - * in a bundle (or "transfer" if too large). - */ -class Responder -{ -public: - Responder(Shared::ClientInterface* client=0, int32_t id=1) - : _client(client) - , _id(id) - {} - - int32_t id() const { return _id; } - void set_id(int32_t id) { _id = id; } - - Shared::ClientInterface* client() const { return _client; } - void set_client(Shared::ClientInterface* client) { _client = client; } - - void respond_ok() { - if (_client) - _client->response_ok(_id); - } - - void respond_error(const std::string& msg) { - if (_client) - _client->response_error(_id, msg); - } - -private: - Shared::ClientInterface* _client; - int32_t _id; -}; - - -} // namespace Ingen - -#endif // RESPONDER_H - diff --git a/src/libs/engine/ThreadManager.hpp b/src/libs/engine/ThreadManager.hpp deleted file mode 100644 index 12f27000..00000000 --- a/src/libs/engine/ThreadManager.hpp +++ /dev/null @@ -1,43 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard <http://drobilla.net> - * - * 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 THREADMANAGER_H -#define THREADMANAGER_H - -#include <raul/Thread.hpp> - -using Raul::Thread; - -namespace Ingen { - - -enum ThreadID { - THREAD_PRE_PROCESS, - THREAD_PROCESS, - THREAD_POST_PROCESS -}; - - -class ThreadManager { -public: - inline static ThreadID current_thread_id() { return (ThreadID)Thread::get().context(); } -}; - - -} // namespace Ingen - -#endif // THREADMANAGER_H diff --git a/src/libs/engine/TransportNode.cpp b/src/libs/engine/TransportNode.cpp deleted file mode 100644 index 3fc14a43..00000000 --- a/src/libs/engine/TransportNode.cpp +++ /dev/null @@ -1,154 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard <http://drobilla.net> - * - * 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 "TransportNode.hpp" -#include <jack/transport.h> -#include "OutputPort.hpp" -#include "InternalPlugin.hpp" -#include "JackAudioDriver.hpp" -#include "PortImpl.hpp" -#include "util.hpp" -//#include "Engine.hpp" - -namespace Ingen { - - -TransportNode::TransportNode(const string& path, bool polyphonic, PatchImpl* parent, SampleRate srate, size_t buffer_size) -: NodeBase(new InternalPlugin(NS_INGEN "transport_node", "transport", "Transport Follower"), - path, false, parent, srate, buffer_size) -{ -#if 0 - _num_ports = 10; - _ports.alloc(_num_ports); - - OutputPort<Sample>* spb_port = new OutputPort<Sample>(this, "Seconds per Beat", 0, 1, - // new PortInfo("Seconds per Beat", CONTROL, OUTPUT, 0, 0, 1), 1); - _ports.at(0) = spb_port; - - OutputPort<Sample>* bpb_port = new OutputPort<Sample>(this, "Beats per Bar", 1, 1, - // new PortInfo("Beats per Bar", CONTROL, OUTPUT, 0, 0, 1), 1); - _ports.at(1) = bpb_port; - - OutputPort<Sample>* bar_port = new OutputPort<Sample>(this, "Bar", 3, 1, -// new PortInfo("Bar", CONTROL, OUTPUT, 0, 0, 1), buffer_size); - _ports.at(2) = bar_port; - - OutputPort<Sample>* beat_port = new OutputPort<Sample>(this, "Beat", 3, 1, - // new PortInfo("Beat", CONTROL, OUTPUT, 0, 0, 1), buffer_size); - _ports.at(3) = beat_port; - - OutputPort<Sample>* frame_port = new OutputPort<Sample>(this, "Frame", 3, 1, - // new PortInfo("Frame", CONTROL, OUTPUT, 0, 0, 1), buffer_size); - _ports.at(4) = frame_port; - - OutputPort<Sample>* hour_port = new OutputPort<Sample>(this, "Hour", 3, 1, - // new PortInfo("Hour", CONTROL, OUTPUT, 0, 0, 1), buffer_size); - _ports.at(5) = hour_port; - - OutputPort<Sample>* minute_port = new OutputPort<Sample>(this, "Minute", 3, 1, - // new PortInfo("Minute", CONTROL, OUTPUT, 0, 0, 1), buffer_size); - _ports.at(6) = minute_port; - - OutputPort<Sample>* second_port = new OutputPort<Sample>(this, "Second", 3, 1, - // new PortInfo("Second", CONTROL, OUTPUT, 0, 0, 1), buffer_size); - _ports.at(7) = second_port; - - OutputPort<Sample>* trg_port = new OutputPort<Sample>(this, "Beat Tick", 2, 1, - // new PortInfo("Beat Tick", AUDIO, OUTPUT, 0, 0, 1), buffer_size); - _ports.at(8) = trg_port; - - OutputPort<Sample>* bar_trig_port = new OutputPort<Sample>(this, "Bar Tick", 3, 1, - // new PortInfo("Bar Tick", AUDIO, OUTPUT, 0, 0, 1), buffer_size); - _ports.at(9) = bar_trig_port; -#endif -} - - -void -TransportNode::process(ProcessContext& context) -{ - NodeBase::pre_process(context); -#if 0 - - // FIXME: this will die horribly with any driver other than jack (in theory) - const jack_position_t* const position = ((JackAudioDriver*)Engine::instance().audio_driver())->position(); - jack_transport_state_t state = ((JackAudioDriver*)Engine::instance().audio_driver())->transport_state(); - double bpm = position->beats_per_minute; - float bpb = position->beats_per_bar; - float spb = 60.0 / bpm; - - //cerr << "bpm = " << bpm << endl; - //cerr << "spb = " << spb << endl; - - if (position->valid & JackPositionBBT) { - cerr << "bar: " << position->bar << endl; - cerr << "beat: " << position->beat << endl; - cerr << "tick: " << position->tick << endl; - } else { - cerr << "No BBT" << endl; - } - - if (position->valid & JackBBTFrameOffset) { - cerr << "bbt_offset: " << position->bbt_offset << endl; - } else { - cerr << "No BBT offset" << endl; - } - - if (position->valid & JackPositionTimecode) { - double time = position->frame_time; - cerr << "Seconds: " << time << " : " << endl; - /*time /= 60.0; - cerr << "Minutes: " << time << " : "; - time /= 60.0; - cerr << "Hours: " << time << " : ";*/ - } else { - cerr << "No timecode." << endl; - } - - - ((OutputPort<Sample>*)_ports.at(0))->buffer(0)->set(spb, 0, 0); - ((OutputPort<Sample>*)_ports.at(1))->buffer(0)->set(bpb, 0, 0); - - // fill the trigger buffers with zeros - ((OutputPort<Sample>*)_ports.at(2))->buffer(0)->set(0.0f, 0, nframes - 1); - ((OutputPort<Sample>*)_ports.at(3))->buffer(0)->set(0.0f, 0, nframes - 1); - - // if the transport is rolling, add triggers at the right frame positions - if ((position->valid & JackTransportBBT) && (state == JackTransportRolling)) { - double frames_per_beat = position->frame_rate * spb; - double first_beat = (1.0f - position->tick / position->ticks_per_beat) * frames_per_beat; - int first_beat_no = position->beat; - if (first_beat >= frames_per_beat) { - first_beat -= frames_per_beat; - --first_beat_no; - } - for ( ; first_beat < nframes; first_beat += frames_per_beat) { - ((OutputPort<Sample>*)_ports.at(2))->buffer(0)->set(1.0f, size_t(first_beat)); - if (first_beat_no % int(bpb) == 0) { - ((OutputPort<Sample>*)_ports.at(3))->buffer(0)->set(1.0f, size_t(first_beat)); - ++first_beat_no; - } - } - } - #endif - - NodeBase::post_process(context); -} - - -} // namespace Ingen - diff --git a/src/libs/engine/TransportNode.hpp b/src/libs/engine/TransportNode.hpp deleted file mode 100644 index af0ed207..00000000 --- a/src/libs/engine/TransportNode.hpp +++ /dev/null @@ -1,45 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard <http://drobilla.net> - * - * 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 TRANSPORTNODE_H -#define TRANSPORTNODE_H - -#include <string> -#include <jack/transport.h> -#include "NodeBase.hpp" - -namespace Ingen { - - -/** Transport Node, brings timing information into patches. - * - * This node uses the Jack transport API to get information about BPM, time - * signature, etc.. all sample accurate. Using this you can do - * tempo-synced effects or even synthesis, etc. - */ -class TransportNode : public NodeBase -{ -public: - TransportNode(const std::string& path, bool polyphonic, PatchImpl* parent, SampleRate srate, size_t buffer_size); - - virtual void process(ProcessContext& context); -}; - - -} // namespace Ingen - -#endif // TRANSPORTNODE_H diff --git a/src/libs/engine/engine.cpp b/src/libs/engine/engine.cpp deleted file mode 100644 index 45c17354..00000000 --- a/src/libs/engine/engine.cpp +++ /dev/null @@ -1,56 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard <http://drobilla.net> - * - * 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 CONFIG_H_PATH - -#include <raul/Process.hpp> -#include "engine.hpp" -#include "Engine.hpp" -#include "QueuedEngineInterface.hpp" -#include "tuning.hpp" -#include "util.hpp" - -namespace Ingen { - -Engine* -new_engine(Ingen::Shared::World* world) -{ - set_denormal_flags(); - return new Engine(world); -} - - -bool -launch_osc_engine(int port) -{ - char port_str[6]; - snprintf(port_str, 6, "%u", port); - const string cmd = string("ingen -e --engine-port=").append(port_str); - - if (Raul::Process::launch(cmd)) { - return true; - //return SharedPtr<EngineInterface>(new OSCEngineSender( - // string("osc.udp://localhost:").append(port_str))); - } else { - std::cerr << "Failed to launch engine process." << std::endl; - //return SharedPtr<EngineInterface>(); - return false; - } -} - -} // namespace Ingen - diff --git a/src/libs/engine/engine.hpp b/src/libs/engine/engine.hpp deleted file mode 100644 index 93b426ac..00000000 --- a/src/libs/engine/engine.hpp +++ /dev/null @@ -1,42 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard <http://drobilla.net> - * - * 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 INGEN_ENGINE_H -#define INGEN_ENGINE_H - -namespace Ingen { - -namespace Shared { class World; } - -class Engine; - -extern "C" { - - /** Create a new engine in this process */ - Engine* new_engine(Ingen::Shared::World* world); - - /** Launch an OSC engine as a completely separate process - * \return true if successful - */ - bool launch_osc_engine(int port); -} - - -} // namespace Ingen - -#endif // INGEN_ENGINE_H - diff --git a/src/libs/engine/events.hpp b/src/libs/engine/events.hpp deleted file mode 100644 index 14f5230c..00000000 --- a/src/libs/engine/events.hpp +++ /dev/null @@ -1,53 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard <http://drobilla.net> - * - * 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 EVENTS_H -#define EVENTS_H - -#include CONFIG_H_PATH - -#include "AllNotesOffEvent.hpp" -#include "ClearPatchEvent.hpp" -#include "ConnectionEvent.hpp" -#include "CreateNodeEvent.hpp" -#include "CreatePatchEvent.hpp" -#include "CreatePortEvent.hpp" -#include "DeactivateEvent.hpp" -#include "DestroyEvent.hpp" -#include "DisconnectAllEvent.hpp" -#include "DisconnectionEvent.hpp" -#include "EnablePatchEvent.hpp" -#include "LoadPluginsEvent.hpp" -#include "MidiLearnEvent.hpp" -#include "NoteEvent.hpp" -#include "PingQueuedEvent.hpp" -#include "RegisterClientEvent.hpp" -#include "RenameEvent.hpp" -#include "RequestAllObjectsEvent.hpp" -#include "RequestMetadataEvent.hpp" -#include "RequestObjectEvent.hpp" -#include "RequestPluginEvent.hpp" -#include "RequestPluginsEvent.hpp" -#include "RequestPortValueEvent.hpp" -#include "SetMetadataEvent.hpp" -#include "SetPolyphonicEvent.hpp" -#include "SetPolyphonyEvent.hpp" -#include "SetPortValueEvent.hpp" -#include "UnregisterClientEvent.hpp" - -#endif // EVENTS_H - diff --git a/src/libs/engine/events/AllNotesOffEvent.cpp b/src/libs/engine/events/AllNotesOffEvent.cpp deleted file mode 100644 index fcb68b31..00000000 --- a/src/libs/engine/events/AllNotesOffEvent.cpp +++ /dev/null @@ -1,71 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard <http://drobilla.net> - * - * 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 "AllNotesOffEvent.hpp" -#include "Responder.hpp" -#include "Engine.hpp" -#include "EngineStore.hpp" -#include "module/World.hpp" -#include "shared/Store.hpp" - -namespace Ingen { - - -/** Note off with patch explicitly passed - triggered by MIDI. - */ -AllNotesOffEvent::AllNotesOffEvent(Engine& engine, SharedPtr<Responder> responder, SampleCount timestamp, PatchImpl* patch) -: Event(engine, responder, timestamp), - _patch(patch) -{ -} - - -/** Note off event with lookup - triggered by OSC. - */ -AllNotesOffEvent::AllNotesOffEvent(Engine& engine, SharedPtr<Responder> responder, SampleCount timestamp, const string& patch_path) -: Event(engine, responder, timestamp), - _patch_path(patch_path), - _patch(NULL) -{ -} - - -void -AllNotesOffEvent::execute(ProcessContext& context) -{ - Event::execute(context); - - if (_patch == NULL && _patch_path != "") - _patch = _engine.engine_store()->find_patch(_patch_path); - - //if (_patch != NULL) - // for (Raul::List<MidiInNode*>::iterator j = _patch->midi_in_nodes().begin(); j != _patch->midi_in_nodes().end(); ++j) - // (*j)->all_notes_off(offset); -} - - -void -AllNotesOffEvent::post_process() -{ - if (_patch != NULL) - _responder->respond_ok(); -} - - -} // namespace Ingen - - diff --git a/src/libs/engine/events/AllNotesOffEvent.hpp b/src/libs/engine/events/AllNotesOffEvent.hpp deleted file mode 100644 index 3e4d56b3..00000000 --- a/src/libs/engine/events/AllNotesOffEvent.hpp +++ /dev/null @@ -1,51 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard <http://drobilla.net> - * - * 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 ALLNOTESOFFEVENT_H -#define ALLNOTESOFFEVENT_H - -#include "Event.hpp" -#include <string> -using std::string; - -namespace Ingen { - -class PatchImpl; - - -/** A note off event for all active voices. - * - * \ingroup engine - */ -class AllNotesOffEvent : public Event -{ -public: - AllNotesOffEvent(Engine& engine, SharedPtr<Responder> responder, SampleCount timestamp, PatchImpl* patch); - AllNotesOffEvent(Engine& engine, SharedPtr<Responder> responder, SampleCount timestamp, const string& patch_path); - - void execute(ProcessContext& context); - void post_process(); - -private: - const string _patch_path; - PatchImpl* _patch; -}; - - -} // namespace Ingen - -#endif // ALLNOTESOFFEVENT_H diff --git a/src/libs/engine/events/ClearPatchEvent.cpp b/src/libs/engine/events/ClearPatchEvent.cpp deleted file mode 100644 index c1fb0749..00000000 --- a/src/libs/engine/events/ClearPatchEvent.cpp +++ /dev/null @@ -1,133 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard <http://drobilla.net> - * - * 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 <raul/Maid.hpp> -#include "ClearPatchEvent.hpp" -#include "Responder.hpp" -#include "Engine.hpp" -#include "PatchImpl.hpp" -#include "ClientBroadcaster.hpp" -#include "util.hpp" -#include "EngineStore.hpp" -#include "PortImpl.hpp" -#include "NodeImpl.hpp" -#include "ConnectionImpl.hpp" -#include "QueuedEventSource.hpp" -#include "AudioDriver.hpp" -#include "MidiDriver.hpp" - -namespace Ingen { - - -ClearPatchEvent::ClearPatchEvent(Engine& engine, SharedPtr<Responder> responder, FrameTime time, QueuedEventSource* source, const string& patch_path) - : QueuedEvent(engine, responder, time, true, source) - , _patch_path(patch_path) - , _driver_port(NULL) - , _process(false) - , _ports_array(NULL) - , _compiled_patch(NULL) -{ -} - - -void -ClearPatchEvent::pre_process() -{ - EngineStore::Objects::iterator patch_iterator = _engine.engine_store()->find(_patch_path); - - if (patch_iterator != _engine.engine_store()->end()) { - _patch = PtrCast<PatchImpl>(patch_iterator->second); - if (_patch) { - _process = _patch->enabled(); - _removed_table = _engine.engine_store()->remove_children(patch_iterator); - _patch->nodes().clear(); - _patch->connections().clear(); - _ports_array = _patch->build_ports_array(); - if (_patch->enabled()) - _compiled_patch = _patch->compile(); - } - } - - QueuedEvent::pre_process(); -} - - -void -ClearPatchEvent::execute(ProcessContext& context) -{ - QueuedEvent::execute(context); - - if (_patch && _removed_table) { - _patch->disable(); - - if (_patch->compiled_patch() != NULL) { - _engine.maid()->push(_patch->compiled_patch()); - _patch->compiled_patch(NULL); - } - - _patch->clear_ports(); - _patch->connections().clear(); - _patch->compiled_patch(_compiled_patch); - Raul::Array<PortImpl*>* old_ports = _patch->external_ports(); - _patch->external_ports(_ports_array); - _ports_array = old_ports; - - // Remove driver ports, if necessary - if (_patch->parent() == NULL) { - for (EngineStore::Objects::iterator i = _removed_table->begin(); i != _removed_table->end(); ++i) { - SharedPtr<PortImpl> port = PtrCast<PortImpl>(i->second); - if (port && port->type() == DataType::AUDIO) - _driver_port = _engine.audio_driver()->remove_port(port->path()); - else if (port && port->type() == DataType::EVENT) - _driver_port = _engine.midi_driver()->remove_port(port->path()); - } - } - } -} - - -void -ClearPatchEvent::post_process() -{ - if (_patch != NULL) { - delete _ports_array; - delete _driver_port; - - // Restore patch's run state - if (_process) - _patch->enable(); - else - _patch->disable(); - - // Make sure everything's sane - assert(_patch->nodes().size() == 0); - assert(_patch->num_ports() == 0); - assert(_patch->connections().size() == 0); - - // Reply - _responder->respond_ok(); - _engine.broadcaster()->send_patch_cleared(_patch_path); - } else { - _responder->respond_error(string("Patch ") + _patch_path + " not found"); - } - - _source->unblock(); // FIXME: can be done earlier in execute? -} - - -} // namespace Ingen - diff --git a/src/libs/engine/events/ClearPatchEvent.hpp b/src/libs/engine/events/ClearPatchEvent.hpp deleted file mode 100644 index 803721fb..00000000 --- a/src/libs/engine/events/ClearPatchEvent.hpp +++ /dev/null @@ -1,65 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard <http://drobilla.net> - * - * 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 CLEARPATCHEVENT_H -#define CLEARPATCHEVENT_H - -#include <string> -#include <raul/Array.hpp> -#include <raul/Table.hpp> -#include <raul/Path.hpp> -#include "QueuedEvent.hpp" -#include "EngineStore.hpp" -#include "PatchImpl.hpp" - -using std::string; - -namespace Ingen { - -class PatchImpl; -class DriverPort; - - -/** Delete all nodes from a patch. - * - * \ingroup engine - */ -class ClearPatchEvent : public QueuedEvent -{ -public: - ClearPatchEvent(Engine& engine, SharedPtr<Responder> responder, FrameTime time, QueuedEventSource* source, const string& patch_path); - - void pre_process(); - void execute(ProcessContext& context); - void post_process(); - -private: - const string _patch_path; - SharedPtr<PatchImpl> _patch; - DriverPort* _driver_port; - bool _process; - Raul::Array<PortImpl*>* _ports_array; ///< New (external) ports for Patch - CompiledPatch* _compiled_patch; ///< Patch's new process order - - SharedPtr< Table<Path, SharedPtr<Shared::GraphObject> > > _removed_table; -}; - - -} // namespace Ingen - - -#endif // CLEARPATCHEVENT_H diff --git a/src/libs/engine/events/ConnectionEvent.cpp b/src/libs/engine/events/ConnectionEvent.cpp deleted file mode 100644 index 24b80dee..00000000 --- a/src/libs/engine/events/ConnectionEvent.cpp +++ /dev/null @@ -1,202 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard <http://drobilla.net> - * - * 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 <string> -#include <boost/format.hpp> -#include <raul/Maid.hpp> -#include <raul/Path.hpp> -#include "ClientBroadcaster.hpp" -#include "ConnectionEvent.hpp" -#include "ConnectionImpl.hpp" -#include "Engine.hpp" -#include "InputPort.hpp" -#include "EngineStore.hpp" -#include "OutputPort.hpp" -#include "PatchImpl.hpp" -#include "PortImpl.hpp" -#include "Responder.hpp" -#include "types.hpp" - -using std::string; -namespace Ingen { - - -ConnectionEvent::ConnectionEvent(Engine& engine, SharedPtr<Responder> responder, SampleCount timestamp, const string& src_port_path, const string& dst_port_path) -: QueuedEvent(engine, responder, timestamp), - _src_port_path(src_port_path), - _dst_port_path(dst_port_path), - _patch(NULL), - _src_port(NULL), - _dst_port(NULL), - _compiled_patch(NULL), - _patch_listnode(NULL), - _port_listnode(NULL), - _error(NO_ERROR) -{ -} - - -void -ConnectionEvent::pre_process() -{ - if (_src_port_path.parent().parent() != _dst_port_path.parent().parent() - && _src_port_path.parent() != _dst_port_path.parent().parent() - && _src_port_path.parent().parent() != _dst_port_path.parent()) { - _error = PARENT_PATCH_DIFFERENT; - QueuedEvent::pre_process(); - return; - } - - _src_port = _engine.engine_store()->find_port(_src_port_path); - _dst_port = _engine.engine_store()->find_port(_dst_port_path); - - if (_src_port == NULL || _dst_port == NULL) { - _error = PORT_NOT_FOUND; - QueuedEvent::pre_process(); - return; - } - - if ( ! (_src_port->type() == _dst_port->type() - || ( (_src_port->type() == DataType::CONTROL || _src_port->type() == DataType::AUDIO) - && (_dst_port->type() == DataType::CONTROL || _dst_port->type() == DataType::AUDIO) ))) { - _error = TYPE_MISMATCH; - QueuedEvent::pre_process(); - return; - } - - _dst_input_port = dynamic_cast<InputPort*>(_dst_port); - _src_output_port = dynamic_cast<OutputPort*>(_src_port); - - if (!_dst_input_port || !_src_output_port) { - _error = DIRECTION_MISMATCH; - QueuedEvent::pre_process(); - return; - } - - NodeImpl* const src_node = _src_port->parent_node(); - NodeImpl* const dst_node = _dst_port->parent_node(); - - // Connection to a patch port from inside the patch - if (src_node->parent_patch() != dst_node->parent_patch()) { - - assert(src_node->parent() == dst_node || dst_node->parent() == src_node); - if (src_node->parent() == dst_node) - _patch = dynamic_cast<PatchImpl*>(dst_node); - else - _patch = dynamic_cast<PatchImpl*>(src_node); - - // Connection from a patch input to a patch output (pass through) - } else if (src_node == dst_node && dynamic_cast<PatchImpl*>(src_node)) { - _patch = dynamic_cast<PatchImpl*>(src_node); - - // Normal connection between nodes with the same parent - } else { - _patch = src_node->parent_patch(); - } - - assert(_patch); - - //if (_dst_input_port->is_connected_to(_src_output_port)) { - if (_patch->has_connection(_src_output_port, _dst_input_port)) { - _error = ALREADY_CONNECTED; - QueuedEvent::pre_process(); - return; - } - - if (src_node == NULL || dst_node == NULL) { - _error = PARENTS_NOT_FOUND; - QueuedEvent::pre_process(); - return; - } - - if (_patch != src_node && src_node->parent() != _patch && dst_node->parent() != _patch) { - _error = PARENTS_NOT_FOUND; - QueuedEvent::pre_process(); - return; - } - - _connection = SharedPtr<ConnectionImpl>(new ConnectionImpl(_src_port, _dst_port)); - _patch_listnode = new PatchImpl::Connections::Node(_connection); - _port_listnode = new InputPort::Connections::Node(_connection); - - // Need to be careful about patch port connections here and adding a node's - // parent as a dependant/provider, or adding a patch as it's own provider... - if (src_node != dst_node && src_node->parent() == dst_node->parent()) { - dst_node->providers()->push_back(new Raul::List<NodeImpl*>::Node(src_node)); - src_node->dependants()->push_back(new Raul::List<NodeImpl*>::Node(dst_node)); - } - - _patch->add_connection(_patch_listnode); - - if (_patch->enabled()) - _compiled_patch = _patch->compile(); - - QueuedEvent::pre_process(); -} - - -void -ConnectionEvent::execute(ProcessContext& context) -{ - QueuedEvent::execute(context); - - if (_error == NO_ERROR) { - // This must be inserted here, since they're actually used by the audio thread - _dst_input_port->add_connection(_port_listnode); - if (_patch->compiled_patch() != NULL) - _engine.maid()->push(_patch->compiled_patch()); - _patch->compiled_patch(_compiled_patch); - } -} - - -void -ConnectionEvent::post_process() -{ - std::ostringstream ss; - if (_error == NO_ERROR) { - _responder->respond_ok(); - _engine.broadcaster()->send_connection(_connection); - return; - } - - ss << boost::format("Unable to make connection %1% -> %2% (") % _src_port_path % _dst_port_path; - - switch (_error) { - case PARENT_PATCH_DIFFERENT: - ss << "Ports have mismatched parents"; break; - case PORT_NOT_FOUND: - ss << "Port not found"; break; - case TYPE_MISMATCH: - ss << "Type mismatch"; break; - case DIRECTION_MISMATCH: - ss << "Direction mismatch"; break; - case ALREADY_CONNECTED: - ss << "Already connected"; break; - case PARENTS_NOT_FOUND: - ss << "Parents not found"; break; - default: - ss << "Unknown error"; - } - ss << ")"; - _responder->respond_error(ss.str()); -} - - -} // namespace Ingen - diff --git a/src/libs/engine/events/ConnectionEvent.hpp b/src/libs/engine/events/ConnectionEvent.hpp deleted file mode 100644 index 89407957..00000000 --- a/src/libs/engine/events/ConnectionEvent.hpp +++ /dev/null @@ -1,92 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard <http://drobilla.net> - * - * 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 CONNECTIONEVENT_H -#define CONNECTIONEVENT_H - -#include <string> -#include <raul/Path.hpp> -#include "QueuedEvent.hpp" -#include "PatchImpl.hpp" -#include "InputPort.hpp" -#include "types.hpp" -using std::string; - -namespace Raul { - template <typename T> class ListNode; - template <typename T> class Array; -} - -namespace Ingen { - -class PatchImpl; -class NodeImpl; -class ConnectionImpl; -class MidiMessage; -class PortImpl; -class InputPort; -class OutputPort; -class CompiledPatch; - - -/** Make a Connection between two Ports. - * - * \ingroup engine - */ -class ConnectionEvent : public QueuedEvent -{ -public: - ConnectionEvent(Engine& engine, SharedPtr<Responder> responder, SampleCount timestamp, const string& src_port_path, const string& dst_port_path); - - void pre_process(); - void execute(ProcessContext& context); - void post_process(); - -private: - - enum ErrorType { - NO_ERROR, - PARENT_PATCH_DIFFERENT, - PORT_NOT_FOUND, - TYPE_MISMATCH, - DIRECTION_MISMATCH, - ALREADY_CONNECTED, - PARENTS_NOT_FOUND - }; - - Raul::Path _src_port_path; - Raul::Path _dst_port_path; - - PatchImpl* _patch; - PortImpl* _src_port; - PortImpl* _dst_port; - OutputPort* _src_output_port; - InputPort* _dst_input_port; - - CompiledPatch* _compiled_patch; ///< New process order for Patch - - SharedPtr<ConnectionImpl> _connection; - PatchImpl::Connections::Node* _patch_listnode; - InputPort::Connections::Node* _port_listnode; - - ErrorType _error; -}; - - -} // namespace Ingen - -#endif // CONNECTIONEVENT_H diff --git a/src/libs/engine/events/CreateNodeEvent.cpp b/src/libs/engine/events/CreateNodeEvent.cpp deleted file mode 100644 index b58bc2c3..00000000 --- a/src/libs/engine/events/CreateNodeEvent.cpp +++ /dev/null @@ -1,151 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard <http://drobilla.net> - * - * 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 <raul/Maid.hpp> -#include <raul/Path.hpp> -#include <raul/Path.hpp> -#include <redlandmm/World.hpp> -#include "module/World.hpp" -#include "CreateNodeEvent.hpp" -#include "Responder.hpp" -#include "PatchImpl.hpp" -#include "NodeImpl.hpp" -#include "PluginImpl.hpp" -#include "Engine.hpp" -#include "PatchImpl.hpp" -#include "NodeFactory.hpp" -#include "ClientBroadcaster.hpp" -#include "EngineStore.hpp" -#include "PortImpl.hpp" -#include "AudioDriver.hpp" - -namespace Ingen { - - -CreateNodeEvent::CreateNodeEvent(Engine& engine, SharedPtr<Responder> responder, SampleCount timestamp, const string& path, - const string& plugin_uri, bool polyphonic) -: QueuedEvent(engine, responder, timestamp), - _path(path), - _plugin_uri(plugin_uri), - _polyphonic(polyphonic), - _patch(NULL), - _node(NULL), - _compiled_patch(NULL), - _node_already_exists(false) -{ -} - - -/** DEPRECATED: Construct from type, library name, and plugin label. - * - * Do not use. - */ -CreateNodeEvent::CreateNodeEvent(Engine& engine, SharedPtr<Responder> responder, SampleCount timestamp, const string& path, - const string& plugin_type, const string& plugin_lib, const string& plugin_label, bool polyphonic) -: QueuedEvent(engine, responder, timestamp), - _path(path), - _plugin_type(plugin_type), - _plugin_lib(plugin_lib), - _plugin_label(plugin_label), - _polyphonic(polyphonic), - _patch(NULL), - _node(NULL), - _compiled_patch(NULL), - _node_already_exists(false) -{ -} - - -void -CreateNodeEvent::pre_process() -{ - if (_engine.engine_store()->find_object(_path) != NULL) { - _node_already_exists = true; - QueuedEvent::pre_process(); - return; - } - - _patch = _engine.engine_store()->find_patch(_path.parent()); - - PluginImpl* const plugin = (_plugin_uri != "") - ? _engine.node_factory()->plugin(_plugin_uri) - : _engine.node_factory()->plugin(_plugin_type, _plugin_lib, _plugin_label); - - if (_patch && plugin) { - - _node = plugin->instantiate(_path.name(), _polyphonic, _patch, _engine); - - if (_node != NULL) { - _node->activate(); - - // This can be done here because the audio thread doesn't touch the - // node tree - just the process order array - _patch->add_node(new PatchImpl::Nodes::Node(_node)); - //_node->add_to_store(_engine.engine_store()); - _engine.engine_store()->add(_node); - - // FIXME: not really necessary to build process order since it's not connected, - // just append to the list - if (_patch->enabled()) - _compiled_patch = _patch->compile(); - } - } - QueuedEvent::pre_process(); -} - - -void -CreateNodeEvent::execute(ProcessContext& context) -{ - QueuedEvent::execute(context); - - if (_node != NULL) { - if (_patch->compiled_patch() != NULL) - _engine.maid()->push(_patch->compiled_patch()); - _patch->compiled_patch(_compiled_patch); - } -} - - -void -CreateNodeEvent::post_process() -{ - string msg; - if (_node_already_exists) { - msg = string("Could not create node - ").append(_path);// + " already exists."; - _responder->respond_error(msg); - } else if (_patch == NULL) { - msg = "Could not find patch '" + _path.parent() +"' for add_node."; - _responder->respond_error(msg); - } else if (_node == NULL) { - msg = "Unable to load node "; - msg += _path + " (you're missing the plugin "; - if (_plugin_uri != "") - msg += _plugin_uri; - else - msg += _plugin_lib + ":" + _plugin_label + " (" + _plugin_type + ")"; - msg += ")"; - _responder->respond_error(msg); - } else { - _responder->respond_ok(); - _engine.broadcaster()->send_node(_node, true); // yes, send ports - } -} - - -} // namespace Ingen - diff --git a/src/libs/engine/events/CreateNodeEvent.hpp b/src/libs/engine/events/CreateNodeEvent.hpp deleted file mode 100644 index c3ef6313..00000000 --- a/src/libs/engine/events/CreateNodeEvent.hpp +++ /dev/null @@ -1,81 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard <http://drobilla.net> - * - * 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 CREATENODEEVENT_H -#define CREATENODEEVENT_H - -#include "QueuedEvent.hpp" -#include <raul/Path.hpp> -#include <string> -using std::string; - -namespace Raul { template <typename T> class Array; } -template<typename T> class TreeNode; - -namespace Ingen { - -class PatchImpl; -class NodeImpl; -class CompiledPatch; - - -/** An event to load a Node and insert it into a Patch. - * - * \ingroup engine - */ -class CreateNodeEvent : public QueuedEvent -{ -public: - CreateNodeEvent(Engine& engine, - SharedPtr<Responder> responder, - SampleCount timestamp, - const string& node_path, - const string& plugin_uri, - bool poly); - - // DEPRECATED - CreateNodeEvent(Engine& engine, - SharedPtr<Responder> responder, - SampleCount timestamp, - const string& node_path, - const string& plugin_type, - const string& lib_name, - const string& plugin_label, - bool poly); - - void pre_process(); - void execute(ProcessContext& context); - void post_process(); - -private: - string _patch_name; - Raul::Path _path; - string _plugin_uri; ///< If nonempty then type, library, label, are ignored - string _plugin_type; - string _plugin_lib; - string _plugin_label; - bool _polyphonic; - PatchImpl* _patch; - NodeImpl* _node; - CompiledPatch* _compiled_patch; ///< Patch's new process order - bool _node_already_exists; -}; - - -} // namespace Ingen - -#endif // CREATENODEEVENT_H diff --git a/src/libs/engine/events/CreatePatchEvent.cpp b/src/libs/engine/events/CreatePatchEvent.cpp deleted file mode 100644 index 64fe5c63..00000000 --- a/src/libs/engine/events/CreatePatchEvent.cpp +++ /dev/null @@ -1,157 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard <http://drobilla.net> - * - * 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 <raul/Maid.hpp> -#include <raul/Path.hpp> -#include "CreatePatchEvent.hpp" -#include "Responder.hpp" -#include "PatchImpl.hpp" -#include "NodeImpl.hpp" -#include "PluginImpl.hpp" -#include "Engine.hpp" -#include "ClientBroadcaster.hpp" -#include "AudioDriver.hpp" -#include "EngineStore.hpp" - -namespace Ingen { - - -CreatePatchEvent::CreatePatchEvent(Engine& engine, SharedPtr<Responder> responder, SampleCount timestamp, const string& path, int poly) -: QueuedEvent(engine, responder, timestamp), - _path(path), - _patch(NULL), - _parent(NULL), - _compiled_patch(NULL), - _poly(poly), - _error(NO_ERROR) -{ -} - - -void -CreatePatchEvent::pre_process() -{ - if (!Path::is_valid(_path)) { - _error = INVALID_PATH; - QueuedEvent::pre_process(); - return; - } - - if (_path == "/" || _engine.engine_store()->find_object(_path) != NULL) { - _error = OBJECT_EXISTS; - QueuedEvent::pre_process(); - return; - } - - if (_poly < 1) { - _error = INVALID_POLY; - QueuedEvent::pre_process(); - return; - } - - const Path& path = (const Path&)_path; - - _parent = _engine.engine_store()->find_patch(path.parent()); - if (_parent == NULL) { - _error = PARENT_NOT_FOUND; - QueuedEvent::pre_process(); - return; - } - - uint32_t poly = 1; - if (_parent != NULL && _poly > 1 && _poly == static_cast<int>(_parent->internal_polyphony())) - poly = _poly; - - _patch = new PatchImpl(_engine, path.name(), poly, _parent, _engine.audio_driver()->sample_rate(), _engine.audio_driver()->buffer_size(), _poly); - - if (_parent != NULL) { - _parent->add_node(new PatchImpl::Nodes::Node(_patch)); - - if (_parent->enabled()) - _compiled_patch = _parent->compile(); - } - - _patch->activate(); - - // Insert into EngineStore - //_patch->add_to_store(_engine.engine_store()); - _engine.engine_store()->add(_patch); - - QueuedEvent::pre_process(); -} - - -void -CreatePatchEvent::execute(ProcessContext& context) -{ - QueuedEvent::execute(context); - - if (_patch != NULL) { - if (_parent == NULL) { - assert(_path == "/"); - assert(_patch->parent_patch() == NULL); - _engine.audio_driver()->set_root_patch(_patch); - } else { - assert(_parent != NULL); - assert(_path != "/"); - - if (_parent->compiled_patch() != NULL) - _engine.maid()->push(_parent->compiled_patch()); - _parent->compiled_patch(_compiled_patch); - } - } -} - - -void -CreatePatchEvent::post_process() -{ - if (_responder.get()) { - if (_error == NO_ERROR) { - - _responder->respond_ok(); - - // Don't send ports/nodes that have been added since prepare() - // (otherwise they would be sent twice) - _engine.broadcaster()->send_patch(_patch, false); - - } else if (_error == INVALID_PATH) { - string msg = "Attempt to create patch with illegal path "; - msg.append(_path); - _responder->respond_error(msg); - } else if (_error == OBJECT_EXISTS) { - _responder->respond_ok(); - /*string msg = "Unable to create patch: "; - msg.append(_path).append(" already exists."); - _responder->respond_error(msg);*/ - } else if (_error == PARENT_NOT_FOUND) { - string msg = "Unable to create patch: Parent "; - msg.append(Path(_path).parent()).append(" not found."); - _responder->respond_error(msg); - } else if (_error == INVALID_POLY) { - string msg = "Unable to create patch "; - msg.append(_path).append(": ").append("Invalid polyphony respondered."); - _responder->respond_error(msg); - } else { - _responder->respond_error("Unable to load patch."); - } - } -} - - -} // namespace Ingen - diff --git a/src/libs/engine/events/CreatePatchEvent.hpp b/src/libs/engine/events/CreatePatchEvent.hpp deleted file mode 100644 index 733aba17..00000000 --- a/src/libs/engine/events/CreatePatchEvent.hpp +++ /dev/null @@ -1,64 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard <http://drobilla.net> - * - * 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 CREATEPATCHEVENT_H -#define CREATEPATCHEVENT_H - -#include <string> -#include <raul/Path.hpp> -#include "QueuedEvent.hpp" - -using std::string; - -namespace Raul { template<typename T> class Array; } -template<typename T> class TreeNode; - -namespace Ingen { - -class PatchImpl; -class CompiledPatch; - - -/** Creates a new Patch. - * - * \ingroup engine - */ -class CreatePatchEvent : public QueuedEvent -{ -public: - CreatePatchEvent(Engine& engine, SharedPtr<Responder> responder, SampleCount timestamp, const string& path, int poly); - - void pre_process(); - void execute(ProcessContext& context); - void post_process(); - -private: - enum ErrorType { NO_ERROR, OBJECT_EXISTS, PARENT_NOT_FOUND, INVALID_POLY, INVALID_PATH }; - - const std::string _path; - PatchImpl* _patch; - PatchImpl* _parent; - CompiledPatch* _compiled_patch; - int _poly; - ErrorType _error; -}; - - -} // namespace Ingen - - -#endif // CREATEPATCHEVENT_H diff --git a/src/libs/engine/events/CreatePortEvent.cpp b/src/libs/engine/events/CreatePortEvent.cpp deleted file mode 100644 index e767f522..00000000 --- a/src/libs/engine/events/CreatePortEvent.cpp +++ /dev/null @@ -1,173 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard <http://drobilla.net> - * - * 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 <raul/Path.hpp> -#include <raul/Array.hpp> -#include <raul/List.hpp> -#include <raul/Maid.hpp> -#include "Responder.hpp" -#include "CreatePortEvent.hpp" -#include "PatchImpl.hpp" -#include "PluginImpl.hpp" -#include "Engine.hpp" -#include "PatchImpl.hpp" -#include "QueuedEventSource.hpp" -#include "EngineStore.hpp" -#include "ClientBroadcaster.hpp" -#include "PortImpl.hpp" -#include "AudioDriver.hpp" -#include "MidiDriver.hpp" -#include "OSCDriver.hpp" -#include "DuplexPort.hpp" - -namespace Ingen { - - -CreatePortEvent::CreatePortEvent(Engine& engine, - SharedPtr<Responder> responder, - SampleCount timestamp, - const string& path, - const string& type, - bool is_output, - QueuedEventSource* source) -: QueuedEvent(engine, responder, timestamp, true, source), - _error(NO_ERROR), - _path(path), - _type(type), - _is_output(is_output), - _data_type(type), - _patch(NULL), - _patch_port(NULL), - _driver_port(NULL) -{ - /* This is blocking because of the two different sets of Patch ports, the array used in the - * audio thread (inherited from NodeBase), and the arrays used in the pre processor thread. - * If two add port events arrive in the same cycle and the second pre processes before the - * first executes, bad things happen (ports are lost). - * - * FIXME: fix this using RCU - */ - - if (_data_type == DataType::UNKNOWN) { - cerr << "[CreatePortEvent] Unknown port type " << type << endl; - _error = UNKNOWN_TYPE; - } -} - - -void -CreatePortEvent::pre_process() -{ - if (_error == UNKNOWN_TYPE || _engine.engine_store()->find_object(_path)) { - QueuedEvent::pre_process(); - return; - } - - // FIXME: this is just a mess :/ - - _patch = _engine.engine_store()->find_patch(_path.parent()); - - if (_patch != NULL) { - assert(_patch->path() == _path.parent()); - - size_t buffer_size = 1; - if (_type != "ingen:Float") - buffer_size = _engine.audio_driver()->buffer_size(); - - const uint32_t old_num_ports = _patch->num_ports(); - - _patch_port = _patch->create_port(_path.name(), _data_type, buffer_size, _is_output); - - if (_patch_port) { - - if (_is_output) - _patch->add_output(new Raul::List<PortImpl*>::Node(_patch_port)); - else - _patch->add_input(new Raul::List<PortImpl*>::Node(_patch_port)); - - if (_patch->external_ports()) - _ports_array = new Raul::Array<PortImpl*>(old_num_ports + 1, *_patch->external_ports()); - else - _ports_array = new Raul::Array<PortImpl*>(old_num_ports + 1, NULL); - - - _ports_array->at(_patch->num_ports()-1) = _patch_port; - //_patch_port->add_to_store(_engine.engine_store()); - _engine.engine_store()->add(_patch_port); - - if (!_patch->parent()) { - if (_type == "ingen:AudioPort") - _driver_port = _engine.audio_driver()->create_port( - dynamic_cast<DuplexPort*>(_patch_port)); - else if (_type == "ingen:MIDIPort" || _type == "ingen:EventPort") - _driver_port = _engine.midi_driver()->create_port( - dynamic_cast<DuplexPort*>(_patch_port)); - else if (_type == "ingen:OSCPort" && _engine.osc_driver()) - _driver_port = _engine.osc_driver()->create_port( - dynamic_cast<DuplexPort*>(_patch_port)); - } - - assert(_ports_array->size() == _patch->num_ports()); - - } - } - QueuedEvent::pre_process(); -} - - -void -CreatePortEvent::execute(ProcessContext& context) -{ - QueuedEvent::execute(context); - - if (_patch_port) { - - _engine.maid()->push(_patch->external_ports()); - //_patch->add_port(_port); - - _patch->external_ports(_ports_array); - } - - if (_driver_port) { - if (_type == "ingen:AudioPort") - _engine.audio_driver()->add_port(_driver_port); - else if (_type == "ingen:MIDIPort" || _type == "ingen:EventPort") - _engine.midi_driver()->add_port(_driver_port); - else if (_type == "ingen:OSCPort") - cerr << "OSC DRIVER PORT" << endl; - } - - if (_source) - _source->unblock(); -} - - -void -CreatePortEvent::post_process() -{ - if (_error != NO_ERROR || !_patch_port) { - const string msg = string("Could not create port - ").append(_path); - _responder->respond_error(msg); - } else { - _responder->respond_ok(); - _engine.broadcaster()->send_port(_patch_port); - } -} - - -} // namespace Ingen - diff --git a/src/libs/engine/events/CreatePortEvent.hpp b/src/libs/engine/events/CreatePortEvent.hpp deleted file mode 100644 index 5ddd8aa3..00000000 --- a/src/libs/engine/events/CreatePortEvent.hpp +++ /dev/null @@ -1,72 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard <http://drobilla.net> - * - * 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 CREATEPORTEVENT_H -#define CREATEPORTEVENT_H - -#include "QueuedEvent.hpp" -#include <raul/Path.hpp> -#include <raul/Array.hpp> -#include "interface/DataType.hpp" -#include <string> -using std::string; - -template <typename T> class Array; - -namespace Ingen { - -class PatchImpl; -class PortImpl; -class DriverPort; - - -/** An event to add a Port to a Patch. - * - * \ingroup engine - */ -class CreatePortEvent : public QueuedEvent -{ -public: - CreatePortEvent(Engine& engine, SharedPtr<Responder> responder, SampleCount timestamp, const string& path, const string& type, bool is_output, QueuedEventSource* source); - - void pre_process(); - void execute(ProcessContext& context); - void post_process(); - -private: - - enum ErrorType { - NO_ERROR, - UNKNOWN_TYPE - }; - - ErrorType _error; - Raul::Path _path; - string _type; - bool _is_output; - DataType _data_type; - PatchImpl* _patch; - PortImpl* _patch_port; - Raul::Array<PortImpl*>* _ports_array; ///< New (external) ports array for Patch - DriverPort* _driver_port; ///< Driver (eg Jack) port if this is a toplevel port - bool _succeeded; -}; - - -} // namespace Ingen - -#endif // CREATEPORTEVENT_H diff --git a/src/libs/engine/events/DeactivateEvent.cpp b/src/libs/engine/events/DeactivateEvent.cpp deleted file mode 100644 index a68419f0..00000000 --- a/src/libs/engine/events/DeactivateEvent.cpp +++ /dev/null @@ -1,54 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard <http://drobilla.net> - * - * 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 "DeactivateEvent.hpp" -#include "Responder.hpp" -#include "Engine.hpp" - -namespace Ingen { - - -DeactivateEvent::DeactivateEvent(Engine& engine, SharedPtr<Responder> responder, SampleCount timestamp) -: QueuedEvent(engine, responder, timestamp) -{ -} - - -void -DeactivateEvent::pre_process() -{ - QueuedEvent::pre_process(); -} - - -void -DeactivateEvent::execute(ProcessContext& context) -{ - QueuedEvent::execute(context); -} - - -void -DeactivateEvent::post_process() -{ - _responder->respond_ok(); - _engine.deactivate(); -} - - -} // namespace Ingen - diff --git a/src/libs/engine/events/DeactivateEvent.hpp b/src/libs/engine/events/DeactivateEvent.hpp deleted file mode 100644 index 5a6750ba..00000000 --- a/src/libs/engine/events/DeactivateEvent.hpp +++ /dev/null @@ -1,43 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard <http://drobilla.net> - * - * 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 DEACTIVATEEVENT_H -#define DEACTIVATEEVENT_H - -#include "QueuedEvent.hpp" - -namespace Ingen { - - -/** Deactivates the engine. - * - * \ingroup engine - */ -class DeactivateEvent : public QueuedEvent -{ -public: - DeactivateEvent(Engine& engine, SharedPtr<Responder> responder, SampleCount timestamp); - - void pre_process(); - void execute(ProcessContext& context); - void post_process(); -}; - - -} // namespace Ingen - -#endif // DEACTIVATEEVENT_H diff --git a/src/libs/engine/events/DestroyEvent.cpp b/src/libs/engine/events/DestroyEvent.cpp deleted file mode 100644 index 07770c0a..00000000 --- a/src/libs/engine/events/DestroyEvent.cpp +++ /dev/null @@ -1,201 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard <http://drobilla.net> - * - * 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 <raul/Maid.hpp> -#include <raul/Path.hpp> -#include "DestroyEvent.hpp" -#include "Responder.hpp" -#include "Engine.hpp" -#include "PatchImpl.hpp" -#include "NodeBase.hpp" -#include "PluginImpl.hpp" -#include "AudioDriver.hpp" -#include "MidiDriver.hpp" -#include "DisconnectAllEvent.hpp" -#include "ClientBroadcaster.hpp" -#include "EngineStore.hpp" -#include "QueuedEventSource.hpp" -#include "PortImpl.hpp" - -namespace Ingen { - - -DestroyEvent::DestroyEvent(Engine& engine, SharedPtr<Responder> responder, FrameTime time, QueuedEventSource* source, const string& path, bool block) - : QueuedEvent(engine, responder, time, source, source) - , _path(path) - , _store_iterator(engine.engine_store()->end()) - , _driver_port(NULL) - , _patch_node_listnode(NULL) - , _patch_port_listnode(NULL) - , _ports_array(NULL) - , _compiled_patch(NULL) - , _disconnect_event(NULL) -{ - assert(_source); -} - - -DestroyEvent::~DestroyEvent() -{ - delete _disconnect_event; -} - - -void -DestroyEvent::pre_process() -{ - _store_iterator = _engine.engine_store()->find(_path); - - if (_store_iterator != _engine.engine_store()->end()) { - _node = PtrCast<NodeImpl>(_store_iterator->second); - - if (!_node) - _port = PtrCast<PortImpl>(_store_iterator->second); - } - - if (_store_iterator != _engine.engine_store()->end()) { - _removed_table = _engine.engine_store()->remove(_store_iterator); - } - - if (_node != NULL && _path != "/") { - assert(_node->parent_patch()); - _patch_node_listnode = _node->parent_patch()->remove_node(_path.name()); - if (_patch_node_listnode) { - assert(_patch_node_listnode->elem() == _node.get()); - - _disconnect_event = new DisconnectAllEvent(_engine, _node->parent_patch(), _node.get()); - _disconnect_event->pre_process(); - - if (_node->parent_patch()->enabled()) { - // FIXME: is this called multiple times? - _compiled_patch = _node->parent_patch()->compile(); -#ifndef NDEBUG - // Be sure node is removed from process order, so it can be destroyed - for (size_t i=0; i < _compiled_patch->size(); ++i) { - assert(_compiled_patch->at(i).node() != _node.get()); - // FIXME: check providers/dependants too - } -#endif - } - } - } else if (_port) { - assert(_port->parent_patch()); - _patch_port_listnode = _port->parent_patch()->remove_port(_path.name()); - if (_patch_port_listnode) { - assert(_patch_port_listnode->elem() == _port.get()); - - _disconnect_event = new DisconnectAllEvent(_engine, _port->parent_patch(), _port.get()); - _disconnect_event->pre_process(); - - if (_port->parent_patch()->enabled()) { - // FIXME: is this called multiple times? - _compiled_patch = _port->parent_patch()->compile(); - _ports_array = _port->parent_patch()->build_ports_array(); - assert(_ports_array->size() == _port->parent_patch()->num_ports()); - } - } - - } - - QueuedEvent::pre_process(); -} - - -void -DestroyEvent::execute(ProcessContext& context) -{ - QueuedEvent::execute(context); - - if (_patch_node_listnode) { - assert(_node); - - if (_disconnect_event) - _disconnect_event->execute(context); - - if (_node->parent_patch()->compiled_patch()) - _engine.maid()->push(_node->parent_patch()->compiled_patch()); - _node->parent_patch()->compiled_patch(_compiled_patch); - - } else if (_patch_port_listnode) { - assert(_port); - - if (_disconnect_event) - _disconnect_event->execute(context); - - if (_port->parent_patch()->compiled_patch()) - _engine.maid()->push(_port->parent_patch()->compiled_patch()); - - _port->parent_patch()->compiled_patch(_compiled_patch); - - if (_port->parent_patch()->external_ports()) - _engine.maid()->push(_port->parent_patch()->external_ports()); - - _port->parent_patch()->external_ports(_ports_array); - - if ( ! _port->parent_patch()->parent()) { - if (_port->type() == DataType::AUDIO) - _driver_port = _engine.audio_driver()->remove_port(_port->path()); - else if (_port->type() == DataType::EVENT) - _driver_port = _engine.midi_driver()->remove_port(_port->path()); - } - } - - if (_source) - _source->unblock(); -} - - -void -DestroyEvent::post_process() -{ - if (!_node && !_port) { - if (_path == "/") { - _responder->respond_error("You can not destroy the root patch (/)"); - } else { - string msg = string("Could not find object ") + _path + " to destroy"; - _responder->respond_error(msg); - } - } - - if (_patch_node_listnode) { - assert(_node); - _node->deactivate(); - _responder->respond_ok(); - _engine.broadcaster()->bundle_begin(); - if (_disconnect_event) - _disconnect_event->post_process(); - _engine.broadcaster()->send_destroyed(_path); - _engine.broadcaster()->bundle_end(); - _engine.maid()->push(_patch_node_listnode); - } else if (_patch_port_listnode) { - assert(_port); - _responder->respond_ok(); - _engine.broadcaster()->bundle_begin(); - if (_disconnect_event) - _disconnect_event->post_process(); - _engine.broadcaster()->send_destroyed(_path); - _engine.broadcaster()->bundle_end(); - _engine.maid()->push(_patch_port_listnode); - } else { - _responder->respond_error("Unable to destroy object"); - } - - delete _driver_port; -} - - -} // namespace Ingen diff --git a/src/libs/engine/events/DestroyEvent.hpp b/src/libs/engine/events/DestroyEvent.hpp deleted file mode 100644 index b24934f8..00000000 --- a/src/libs/engine/events/DestroyEvent.hpp +++ /dev/null @@ -1,77 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard <http://drobilla.net> - * - * 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 DESTROYEVENT_H -#define DESTROYEVENT_H - -#include <string> -#include <raul/Path.hpp> -#include "QueuedEvent.hpp" -#include "EngineStore.hpp" -#include "PatchImpl.hpp" - -using std::string; - -namespace Raul { - template<typename T> class Array; - template<typename T> class ListNode; -} -template<typename T> class TreeNode; - -namespace Ingen { - -class GraphObjectImpl; -class NodeImpl; -class PortImpl; -class DriverPort; -class DisconnectAllEvent; -class CompiledPatch; - - -/** An event to remove and delete a Node. - * - * \ingroup engine - */ -class DestroyEvent : public QueuedEvent -{ -public: - DestroyEvent(Engine& engine, SharedPtr<Responder> responder, FrameTime timestamp, QueuedEventSource* source, const string& path, bool block = true); - ~DestroyEvent(); - - void pre_process(); - void execute(ProcessContext& context); - void post_process(); - -private: - Path _path; - EngineStore::iterator _store_iterator; - SharedPtr<NodeImpl> _node; ///< Non-NULL iff a node - SharedPtr<PortImpl> _port; ///< Non-NULL iff a port - DriverPort* _driver_port; - PatchImpl::Nodes::Node* _patch_node_listnode; - Raul::List<PortImpl*>::Node* _patch_port_listnode; - Raul::Array<PortImpl*>* _ports_array; ///< New (external) ports for Patch - CompiledPatch* _compiled_patch; ///< Patch's new process order - DisconnectAllEvent* _disconnect_event; - - SharedPtr< Table<Path, SharedPtr<Shared::GraphObject> > > _removed_table; -}; - - -} // namespace Ingen - -#endif // DESTROYEVENT_H diff --git a/src/libs/engine/events/DisablePortMonitoringEvent.cpp b/src/libs/engine/events/DisablePortMonitoringEvent.cpp deleted file mode 100644 index cecc8dfd..00000000 --- a/src/libs/engine/events/DisablePortMonitoringEvent.cpp +++ /dev/null @@ -1,87 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard <http://drobilla.net> - * - * 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 <string> -#include "interface/ClientInterface.hpp" -#include "events/DisablePortMonitoringEvent.hpp" -#include "Responder.hpp" -#include "Engine.hpp" -#include "PortImpl.hpp" -#include "EngineStore.hpp" -#include "ClientBroadcaster.hpp" -#include "AudioBuffer.hpp" - -using std::string; - -namespace Ingen { - - -DisablePortMonitoringEvent::DisablePortMonitoringEvent(Engine& engine, - SharedPtr<Responder> responder, - SampleCount timestamp, - const std::string& port_path) -: QueuedEvent(engine, responder, timestamp), - _port_path(port_path), - _port(NULL) -{ -} - - -void -DisablePortMonitoringEvent::pre_process() -{ - _port = _engine.engine_store()->find_port(_port_path); - - QueuedEvent::pre_process(); -} - - -void -DisablePortMonitoringEvent::execute(ProcessContext& context) -{ - QueuedEvent::execute(context); - -#if 0 - assert(_time >= start && _time <= end); - - if (_port != NULL && _port->type() == DataType::FLOAT) - _value = ((AudioBuffer*)_port->buffer(0))->value_at(0/*_time - start*/); - else - _port = NULL; // triggers error response -#endif -} - - -void -DisablePortMonitoringEvent::post_process() -{ -#if 0 - string msg; - if (!_port) { - _responder->respond_error("Unable to find port for get_value responder."); - } else if (_responder->client()) { - _responder->respond_ok(); - _responder->client()->control_change(_port_path, _value); - } else { - _responder->respond_error("Unable to find client to send port value"); - } -#endif -} - - -} // namespace Ingen - diff --git a/src/libs/engine/events/DisablePortMonitoringEvent.hpp b/src/libs/engine/events/DisablePortMonitoringEvent.hpp deleted file mode 100644 index 7a8e23f7..00000000 --- a/src/libs/engine/events/DisablePortMonitoringEvent.hpp +++ /dev/null @@ -1,58 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard <http://drobilla.net> - * - * 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 DISABLEPORTNOTIFICATIONEVENT_H -#define DISABLEPORTNOTIFICATIONEVENT_H - -#include <string> -#include "QueuedEvent.hpp" -#include "types.hpp" - -using std::string; - -namespace Ingen { - -class PortImpl; -namespace Shared { class ClientInterface; } -using Shared::ClientInterface; - - -/** Disable sending of dynamic value change notifications for a port. - * - * \ingroup engine - */ -class DisablePortMonitoringEvent : public QueuedEvent -{ -public: - DisablePortMonitoringEvent(Engine& engine, - SharedPtr<Responder> responder, - SampleCount timestamp, - const std::string& port_path); - - void pre_process(); - void execute(ProcessContext& context); - void post_process(); - -private: - const std::string _port_path; - Port* _port; -}; - - -} // namespace Ingen - -#endif // DISABLEPORTNOTIFICATIONEVENT_H diff --git a/src/libs/engine/events/DisconnectAllEvent.cpp b/src/libs/engine/events/DisconnectAllEvent.cpp deleted file mode 100644 index 77b1b1b3..00000000 --- a/src/libs/engine/events/DisconnectAllEvent.cpp +++ /dev/null @@ -1,183 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard <http://drobilla.net> - * - * 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 <boost/format.hpp> -#include <raul/Array.hpp> -#include <raul/List.hpp> -#include <raul/Maid.hpp> -#include <raul/Path.hpp> -#include "ClientBroadcaster.hpp" -#include "ConnectionImpl.hpp" -#include "DisconnectAllEvent.hpp" -#include "DisconnectionEvent.hpp" -#include "Engine.hpp" -#include "InputPort.hpp" -#include "NodeImpl.hpp" -#include "EngineStore.hpp" -#include "OutputPort.hpp" -#include "PatchImpl.hpp" -#include "PortImpl.hpp" -#include "Responder.hpp" -#include "util.hpp" - -namespace Ingen { - - -DisconnectAllEvent::DisconnectAllEvent(Engine& engine, SharedPtr<Responder> responder, SampleCount timestamp, const string& parent_path, const string& node_path) - : QueuedEvent(engine, responder, timestamp) - , _parent_path(parent_path) - , _path(node_path) - , _parent(NULL) - , _node(NULL) - , _port(NULL) - , _lookup(true) - , _error(NO_ERROR) -{ -} - - -/** Internal version for use by other events. - */ -DisconnectAllEvent::DisconnectAllEvent(Engine& engine, PatchImpl* parent, GraphObjectImpl* object) - : QueuedEvent(engine) - , _parent_path(parent->path()) - , _path(object->path()) - , _parent(parent) - , _node(dynamic_cast<NodeImpl*>(object)) - , _port(dynamic_cast<PortImpl*>(object)) - , _lookup(false) - , _error(NO_ERROR) -{ -} - - -DisconnectAllEvent::~DisconnectAllEvent() -{ - for (Raul::List<DisconnectionEvent*>::iterator i = _disconnection_events.begin(); i != _disconnection_events.end(); ++i) - delete (*i); -} - - -void -DisconnectAllEvent::pre_process() -{ - if (_lookup) { - _parent = _engine.engine_store()->find_patch(_parent_path); - - if (_parent == NULL) { - _error = PARENT_NOT_FOUND; - QueuedEvent::pre_process(); - return; - } - - GraphObjectImpl* object = _engine.engine_store()->find_object(_path); - - if (object == NULL) { - _error = OBJECT_NOT_FOUND; - QueuedEvent::pre_process(); - return; - } - - if (object->parent_patch() != _parent && object->parent()->parent_patch() != _parent) { - _error = INVALID_PARENT_PATH; - QueuedEvent::pre_process(); - return; - } - - // Only one of these will succeed - _node = dynamic_cast<NodeImpl*>(object); - _port = dynamic_cast<PortImpl*>(object); - - assert((_node || _port) && !(_node && _port)); - } - - if (_node) { - for (PatchImpl::Connections::const_iterator i = _parent->connections().begin(); - i != _parent->connections().end(); ++i) { - ConnectionImpl* c = (ConnectionImpl*)i->get(); - if ((c->src_port()->parent_node() == _node || c->dst_port()->parent_node() == _node) - && !c->pending_disconnection()) { - DisconnectionEvent* ev = new DisconnectionEvent(_engine, - SharedPtr<Responder>(new Responder()), _time, c->src_port(), c->dst_port()); - ev->pre_process(); - _disconnection_events.push_back(new Raul::List<DisconnectionEvent*>::Node(ev)); - c->pending_disconnection(true); - } - } - } else { // _port - for (PatchImpl::Connections::const_iterator i = _parent->connections().begin(); - i != _parent->connections().end(); ++i) { - ConnectionImpl* c = (ConnectionImpl*)i->get(); - if ((c->src_port() == _port || c->dst_port() == _port) && !c->pending_disconnection()) { - DisconnectionEvent* ev = new DisconnectionEvent(_engine, - SharedPtr<Responder>(new Responder()), _time, c->src_port(), c->dst_port()); - ev->pre_process(); - _disconnection_events.push_back(new Raul::List<DisconnectionEvent*>::Node(ev)); - c->pending_disconnection(true); - } - } - } - - QueuedEvent::pre_process(); -} - - -void -DisconnectAllEvent::execute(ProcessContext& context) -{ - QueuedEvent::execute(context); - - if (_error == NO_ERROR) { - for (Raul::List<DisconnectionEvent*>::iterator i = _disconnection_events.begin(); i != _disconnection_events.end(); ++i) - (*i)->execute(context); - } -} - - -void -DisconnectAllEvent::post_process() -{ - if (_error == NO_ERROR) { - if (_responder) - _responder->respond_ok(); - for (Raul::List<DisconnectionEvent*>::iterator i = _disconnection_events.begin(); - i != _disconnection_events.end(); ++i) - (*i)->post_process(); - } else { - if (_responder) { - boost::format fmt("Unable to disconnect %1% (%2%)"); - fmt % _path; - switch (_error) { - case INVALID_PARENT_PATH: - fmt % string("Invalid parent path: ").append(_parent_path); - break; - case PARENT_NOT_FOUND: - fmt % string("Unable to find parent: ").append(_parent_path); - break; - case OBJECT_NOT_FOUND: - fmt % string("Unable to find object"); - default: - break; - } - _responder->respond_error(fmt.str()); - } - } -} - - -} // namespace Ingen - diff --git a/src/libs/engine/events/DisconnectAllEvent.hpp b/src/libs/engine/events/DisconnectAllEvent.hpp deleted file mode 100644 index 6b75e6df..00000000 --- a/src/libs/engine/events/DisconnectAllEvent.hpp +++ /dev/null @@ -1,79 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard <http://drobilla.net> - * - * 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 DISCONNECTNODEEVENT_H -#define DISCONNECTNODEEVENT_H - -#include <string> -#include <raul/List.hpp> -#include <raul/Path.hpp> -#include "QueuedEvent.hpp" - -using std::string; - -namespace Ingen { - -class DisconnectionEvent; -class PatchImpl; -class NodeImpl; -class Connection; -class PortImpl; -class InputPort; -class OutputPort; - - -/** An event to disconnect all connections to a Node. - * - * \ingroup engine - */ -class DisconnectAllEvent : public QueuedEvent -{ -public: - DisconnectAllEvent(Engine& engine, SharedPtr<Responder> responder, SampleCount timestamp, const string& parent_path, const string& node_path); - DisconnectAllEvent(Engine& engine, PatchImpl* parent, GraphObjectImpl* object); - ~DisconnectAllEvent(); - - void pre_process(); - void execute(ProcessContext& context); - void post_process(); - -private: - enum ErrorType { - NO_ERROR, - INVALID_PARENT_PATH, - PARENT_NOT_FOUND, - OBJECT_NOT_FOUND, - }; - - Raul::Path _parent_path; - Raul::Path _path; - PatchImpl* _parent; - NodeImpl* _node; - PortImpl* _port; - Raul::List<DisconnectionEvent*> _disconnection_events; - - bool _lookup; - bool _disconnect_parent; - - ErrorType _error; -}; - - -} // namespace Ingen - - -#endif // DISCONNECTNODEEVENT_H diff --git a/src/libs/engine/events/DisconnectionEvent.cpp b/src/libs/engine/events/DisconnectionEvent.cpp deleted file mode 100644 index 86ad8b4e..00000000 --- a/src/libs/engine/events/DisconnectionEvent.cpp +++ /dev/null @@ -1,213 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard <http://drobilla.net> - * - * 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 "DisconnectionEvent.hpp" -#include <string> -#include <raul/Maid.hpp> -#include <raul/Path.hpp> -#include "Responder.hpp" -#include "Engine.hpp" -#include "ConnectionImpl.hpp" -#include "InputPort.hpp" -#include "OutputPort.hpp" -#include "PatchImpl.hpp" -#include "ClientBroadcaster.hpp" -#include "PortImpl.hpp" -#include "EngineStore.hpp" - -using std::string; -namespace Ingen { - - -//// DisconnectionEvent //// - - -DisconnectionEvent::DisconnectionEvent(Engine& engine, SharedPtr<Responder> responder, SampleCount timestamp, const string& src_port_path, const string& dst_port_path) -: QueuedEvent(engine, responder, timestamp), - _src_port_path(src_port_path), - _dst_port_path(dst_port_path), - _patch(NULL), - _src_port(NULL), - _dst_port(NULL), - _lookup(true), - _patch_connection(NULL), - _compiled_patch(NULL), - _error(NO_ERROR) -{ -} - - -DisconnectionEvent::DisconnectionEvent(Engine& engine, SharedPtr<Responder> responder, SampleCount timestamp, PortImpl* const src_port, PortImpl* const dst_port) -: QueuedEvent(engine, responder, timestamp), - _src_port_path(src_port->path()), - _dst_port_path(dst_port->path()), - _patch(src_port->parent_node()->parent_patch()), - _src_port(src_port), - _dst_port(dst_port), - _lookup(false), - _compiled_patch(NULL), - _error(NO_ERROR) -{ - // FIXME: These break for patch ports.. is that ok? - /*assert(src_port->is_output()); - assert(dst_port->is_input()); - assert(src_port->type() == dst_port->type()); - assert(src_port->parent_node()->parent_patch() - == dst_port->parent_node()->parent_patch()); */ -} - - -void -DisconnectionEvent::pre_process() -{ - if (_lookup) { - if (_src_port_path.parent().parent() != _dst_port_path.parent().parent() - && _src_port_path.parent() != _dst_port_path.parent().parent() - && _src_port_path.parent().parent() != _dst_port_path.parent()) { - _error = PARENT_PATCH_DIFFERENT; - QueuedEvent::pre_process(); - return; - } - - _src_port = _engine.engine_store()->find_port(_src_port_path); - _dst_port = _engine.engine_store()->find_port(_dst_port_path); - } - - if (_src_port == NULL || _dst_port == NULL) { - _error = PORT_NOT_FOUND; - QueuedEvent::pre_process(); - return; - } - - _dst_input_port = dynamic_cast<InputPort*>(_dst_port); - _src_output_port = dynamic_cast<OutputPort*>(_src_port); - assert(_src_output_port); - assert(_dst_input_port); - - NodeImpl* const src_node = _src_port->parent_node(); - NodeImpl* const dst_node = _dst_port->parent_node(); - - // Connection to a patch port from inside the patch - if (src_node->parent_patch() != dst_node->parent_patch()) { - - assert(src_node->parent() == dst_node || dst_node->parent() == src_node); - if (src_node->parent() == dst_node) - _patch = dynamic_cast<PatchImpl*>(dst_node); - else - _patch = dynamic_cast<PatchImpl*>(src_node); - - // Connection from a patch input to a patch output (pass through) - } else if (src_node == dst_node && dynamic_cast<PatchImpl*>(src_node)) { - _patch = dynamic_cast<PatchImpl*>(src_node); - - // Normal connection between nodes with the same parent - } else { - _patch = src_node->parent_patch(); - } - - assert(_patch); - - //if (_dst_input_port->is_connected_to(_src_output_port)) { - if (!_patch->has_connection(_src_output_port, _dst_input_port)) { - _error = NOT_CONNECTED; - QueuedEvent::pre_process(); - return; - } - - if (src_node == NULL || dst_node == NULL) { - _error = PARENTS_NOT_FOUND; - QueuedEvent::pre_process(); - return; - } - - for (Raul::List<NodeImpl*>::iterator i = dst_node->providers()->begin(); i != dst_node->providers()->end(); ++i) - if ((*i) == src_node) { - delete dst_node->providers()->erase(i); - break; - } - - for (Raul::List<NodeImpl*>::iterator i = src_node->dependants()->begin(); i != src_node->dependants()->end(); ++i) - if ((*i) == dst_node) { - delete src_node->dependants()->erase(i); - break; - } - - _patch_connection = _patch->remove_connection(_src_port, _dst_port); - - if (_patch->enabled()) - _compiled_patch = _patch->compile(); - - QueuedEvent::pre_process(); -} - - -void -DisconnectionEvent::execute(ProcessContext& context) -{ - QueuedEvent::execute(context); - - if (_error == NO_ERROR) { - InputPort::Connections::Node* const port_connection - = _dst_input_port->remove_connection(_src_output_port); - - if (port_connection != NULL) { - assert(_patch_connection); - - if (port_connection->elem() != _patch_connection->elem()) { - cerr << "ERROR: Corrupt connections:" << endl; - cerr << "\t" << port_connection->elem() << ": " - << port_connection->elem()->src_port_path() - << " -> " << port_connection->elem()->dst_port_path() << endl - << "!=" << endl - << "\t" << _patch_connection->elem() << ": " - << _patch_connection->elem()->src_port_path() - << " -> " << _patch_connection->elem()->dst_port_path() << endl; - } - assert(port_connection->elem() == _patch_connection->elem()); - - // Destroy list node, which will drop reference to connection itself - _engine.maid()->push(port_connection); - _engine.maid()->push(_patch_connection); - - if (_patch->compiled_patch() != NULL) - _engine.maid()->push(_patch->compiled_patch()); - _patch->compiled_patch(_compiled_patch); - } else { - _error = CONNECTION_NOT_FOUND; - } - } -} - - -void -DisconnectionEvent::post_process() -{ - if (_error == NO_ERROR) { - _responder->respond_ok(); - _engine.broadcaster()->send_disconnection(_src_port->path(), _dst_port->path()); - } else { - // FIXME: better error messages - string msg = "Unable to disconnect "; - msg.append(_src_port_path + " -> " + _dst_port_path); - cerr << "DISCONNECTION ERROR " << (unsigned)_error << endl; - _responder->respond_error(msg); - } -} - - -} // namespace Ingen - diff --git a/src/libs/engine/events/DisconnectionEvent.hpp b/src/libs/engine/events/DisconnectionEvent.hpp deleted file mode 100644 index 700febeb..00000000 --- a/src/libs/engine/events/DisconnectionEvent.hpp +++ /dev/null @@ -1,90 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard <http://drobilla.net> - * - * 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 DISCONNECTIONEVENT_H -#define DISCONNECTIONEVENT_H - -#include <string> -#include <raul/Path.hpp> -#include "QueuedEvent.hpp" -#include "types.hpp" -#include "PatchImpl.hpp" -using std::string; - -namespace Raul { - template <typename T> class ListNode; - template <typename T> class Array; -} - -namespace Ingen { - -class NodeImpl; -class ConnectionImpl; -class MidiMessage; -class PortImpl; -class InputPort; -class OutputPort; -class CompiledPatch; - - -/** Make a Connection between two Ports. - * - * \ingroup engine - */ -class DisconnectionEvent : public QueuedEvent -{ -public: - DisconnectionEvent(Engine& engine, SharedPtr<Responder> responder, SampleCount timestamp, const string& src_port_path, const string& dst_port_path); - DisconnectionEvent(Engine& engine, SharedPtr<Responder> responder, SampleCount timestamp, PortImpl* const src_port, PortImpl* const dst_port); - - void pre_process(); - void execute(ProcessContext& context); - void post_process(); - -private: - - enum ErrorType { - NO_ERROR, - PARENT_PATCH_DIFFERENT, - PORT_NOT_FOUND, - TYPE_MISMATCH, - NOT_CONNECTED, - PARENTS_NOT_FOUND, - CONNECTION_NOT_FOUND - }; - - Raul::Path _src_port_path; - Raul::Path _dst_port_path; - - PatchImpl* _patch; - PortImpl* _src_port; - PortImpl* _dst_port; - OutputPort* _src_output_port; - InputPort* _dst_input_port; - - bool _lookup; - - PatchImpl::Connections::Node* _patch_connection; - CompiledPatch* _compiled_patch; ///< New process order for Patch - - ErrorType _error; -}; - - -} // namespace Ingen - -#endif // DISCONNECTIONEVENT_H diff --git a/src/libs/engine/events/EnablePatchEvent.cpp b/src/libs/engine/events/EnablePatchEvent.cpp deleted file mode 100644 index 04759cea..00000000 --- a/src/libs/engine/events/EnablePatchEvent.cpp +++ /dev/null @@ -1,86 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard <http://drobilla.net> - * - * 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 "EnablePatchEvent.hpp" -#include "Responder.hpp" -#include "Engine.hpp" -#include "PatchImpl.hpp" -#include "util.hpp" -#include "ClientBroadcaster.hpp" -#include "EngineStore.hpp" - -namespace Ingen { - - -EnablePatchEvent::EnablePatchEvent(Engine& engine, SharedPtr<Responder> responder, SampleCount timestamp, const string& patch_path, bool enable) -: QueuedEvent(engine, responder, timestamp), - _patch_path(patch_path), - _patch(NULL), - _compiled_patch(NULL), - _enable(enable) -{ -} - - -void -EnablePatchEvent::pre_process() -{ - _patch = _engine.engine_store()->find_patch(_patch_path); - - if (_enable && _patch) { - /* Any event that requires a new process order will set the patch's - * compiled_patch to NULL if it is executed when the patch is not - * active. So, if the CP is NULL, calculate it here */ - if (_patch->compiled_patch() == NULL) - _compiled_patch = _patch->compile(); - } - - QueuedEvent::pre_process(); -} - - -void -EnablePatchEvent::execute(ProcessContext& context) -{ - QueuedEvent::execute(context); - - if (_patch != NULL) { - if (_enable) - _patch->enable(); - else - _patch->disable(); - - if (_enable && _patch->compiled_patch() == NULL) - _patch->compiled_patch(_compiled_patch); - } -} - - -void -EnablePatchEvent::post_process() -{ - if (_patch != NULL) { - _responder->respond_ok(); - _engine.broadcaster()->send_property_change(_patch_path, "ingen:enabled", (bool)_enable); - } else { - _responder->respond_error(string("Patch ") + _patch_path + " not found"); - } -} - - -} // namespace Ingen - diff --git a/src/libs/engine/events/EnablePatchEvent.hpp b/src/libs/engine/events/EnablePatchEvent.hpp deleted file mode 100644 index dad1803a..00000000 --- a/src/libs/engine/events/EnablePatchEvent.hpp +++ /dev/null @@ -1,63 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard <http://drobilla.net> - * - * 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 ENABLEPATCHEVENT_H -#define ENABLEPATCHEVENT_H - -#include <string> -#include "QueuedEvent.hpp" - -using std::string; - -namespace Raul { template <typename T> class Array; } - -namespace Ingen { - -class PatchImpl; -class NodeImpl; -class CompiledPatch; - - -/** Enables a patch's DSP processing. - * - * \ingroup engine - */ -class EnablePatchEvent : public QueuedEvent -{ -public: - EnablePatchEvent(Engine& engine, - SharedPtr<Responder> responder, - SampleCount timestamp, - const string& patch_path, - bool enable); - - void pre_process(); - void execute(ProcessContext& context); - void post_process(); - -private: - string _patch_path; - PatchImpl* _patch; - CompiledPatch* _compiled_patch; // Patch's new process order - bool _enable; -}; - - -} // namespace Ingen - - -#endif // ENABLEPATCHEVENT_H diff --git a/src/libs/engine/events/LoadPluginsEvent.cpp b/src/libs/engine/events/LoadPluginsEvent.cpp deleted file mode 100644 index df5ff5d9..00000000 --- a/src/libs/engine/events/LoadPluginsEvent.cpp +++ /dev/null @@ -1,56 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard <http://drobilla.net> - * - * 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 "LoadPluginsEvent.hpp" -#include "Responder.hpp" -#include "Engine.hpp" -#include "NodeFactory.hpp" -#include "ClientBroadcaster.hpp" -#include "QueuedEventSource.hpp" - -#include <iostream> -using std::cerr; - -namespace Ingen { - - -LoadPluginsEvent::LoadPluginsEvent(Engine& engine, SharedPtr<Responder> responder, SampleCount timestamp, QueuedEventSource* source) -: QueuedEvent(engine, responder, timestamp, true, source) -{ - /* FIXME: Not sure why this has to be blocking, but it fixes some nasty bugs.. */ -} - -void -LoadPluginsEvent::pre_process() -{ - _engine.node_factory()->load_plugins(); - - QueuedEvent::pre_process(); -} - -void -LoadPluginsEvent::post_process() -{ - if (_source) - _source->unblock(); - - _responder->respond_ok(); -} - - -} // namespace Ingen - diff --git a/src/libs/engine/events/LoadPluginsEvent.hpp b/src/libs/engine/events/LoadPluginsEvent.hpp deleted file mode 100644 index cd9a2884..00000000 --- a/src/libs/engine/events/LoadPluginsEvent.hpp +++ /dev/null @@ -1,46 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard <http://drobilla.net> - * - * 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 LOADPLUGINSEVENT_H -#define LOADPLUGINSEVENT_H - -#include <list> -#include "QueuedEvent.hpp" - -namespace Ingen { - - -/** Loads all plugins into the internal plugin database (in NodeFactory). - * - * \ingroup engine - */ -class LoadPluginsEvent : public QueuedEvent -{ -public: - LoadPluginsEvent(Engine& engine, - SharedPtr<Responder> responder, - SampleCount timestamp, - QueuedEventSource* source); - - void pre_process(); - void post_process(); -}; - - -} // namespace Ingen - -#endif // LOADPLUGINSEVENT_H diff --git a/src/libs/engine/events/Makefile.am b/src/libs/engine/events/Makefile.am deleted file mode 100644 index 9a8cfbd5..00000000 --- a/src/libs/engine/events/Makefile.am +++ /dev/null @@ -1,63 +0,0 @@ -MAINTAINERCLEANFILES = Makefile.in - -EXTRA_DIST = \ - AllNotesOffEvent.cpp \ - AllNotesOffEvent.hpp \ - ClearPatchEvent.cpp \ - ClearPatchEvent.hpp \ - ConnectionEvent.cpp \ - ConnectionEvent.hpp \ - CreateNodeEvent.cpp \ - CreateNodeEvent.hpp \ - CreatePatchEvent.cpp \ - CreatePatchEvent.hpp \ - CreatePortEvent.cpp \ - CreatePortEvent.hpp \ - DeactivateEvent.cpp \ - DeactivateEvent.hpp \ - DestroyEvent.cpp \ - DestroyEvent.hpp \ - DisconnectAllEvent.cpp \ - DisconnectAllEvent.hpp \ - DisconnectionEvent.cpp \ - DisconnectionEvent.hpp \ - EnablePatchEvent.cpp \ - EnablePatchEvent.hpp \ - LoadPluginsEvent.cpp \ - LoadPluginsEvent.hpp \ - MidiLearnEvent.cpp \ - MidiLearnEvent.hpp \ - NoteEvent.cpp \ - NoteEvent.hpp \ - PingQueuedEvent.hpp \ - RegisterClientEvent.cpp \ - RegisterClientEvent.hpp \ - RenameEvent.cpp \ - RenameEvent.hpp \ - RequestAllObjectsEvent.cpp \ - RequestAllObjectsEvent.hpp \ - RequestMetadataEvent.cpp \ - RequestMetadataEvent.hpp \ - RequestObjectEvent.cpp \ - RequestObjectEvent.hpp \ - RequestPluginEvent.cpp \ - RequestPluginEvent.hpp \ - RequestPluginsEvent.cpp \ - RequestPluginsEvent.hpp \ - RequestPortValueEvent.cpp \ - RequestPortValueEvent.hpp \ - SendPortActivityEvent.cpp \ - SendPortActivityEvent.hpp \ - SendPortValueEvent.cpp \ - SendPortValueEvent.hpp \ - SetMetadataEvent.cpp \ - SetMetadataEvent.hpp \ - SetPolyphonicEvent.cpp \ - SetPolyphonicEvent.hpp \ - SetPolyphonyEvent.cpp \ - SetPolyphonyEvent.hpp \ - SetPortValueEvent.cpp \ - SetPortValueEvent.hpp \ - UnregisterClientEvent.cpp \ - UnregisterClientEvent.hpp - diff --git a/src/libs/engine/events/MidiLearnEvent.cpp b/src/libs/engine/events/MidiLearnEvent.cpp deleted file mode 100644 index 2f37f30d..00000000 --- a/src/libs/engine/events/MidiLearnEvent.cpp +++ /dev/null @@ -1,89 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard <http://drobilla.net> - * - * 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 "MidiLearnEvent.hpp" -#include "Responder.hpp" -#include "Engine.hpp" -#include "EngineStore.hpp" -#include "NodeImpl.hpp" -#include "MidiControlNode.hpp" -#include "ClientBroadcaster.hpp" -#include "PluginImpl.hpp" - -namespace Ingen { - - -// MidiLearnResponseEvent - -void -MidiLearnResponseEvent::post_process() -{ - _engine.broadcaster()->send_port_value(_port_path, _value); -} - - - -// MidiLearnEvent - -MidiLearnEvent::MidiLearnEvent(Engine& engine, SharedPtr<Responder> responder, SampleCount timestamp, const string& node_path) -: QueuedEvent(engine, responder, timestamp), - _node_path(node_path), - _node(NULL), - _response_event(NULL) -{ -} - - -void -MidiLearnEvent::pre_process() -{ - _node = _engine.engine_store()->find_node(_node_path); - _response_event = new MidiLearnResponseEvent(_engine, _node_path + "/Controller_Number", _time); - - QueuedEvent::pre_process(); -} - - -void -MidiLearnEvent::execute(ProcessContext& context) -{ - QueuedEvent::execute(context); - - // FIXME: this isn't very good at all. - if (_node != NULL && _node->plugin_impl()->type() == Plugin::Internal - && _node->plugin_impl()->uri() == "ingen:control_node") { - ((MidiControlNode*)_node)->learn(_response_event); - } -} - - -void -MidiLearnEvent::post_process() -{ - if (_node != NULL) { - _responder->respond_ok(); - } else { - string msg = "Did not find node '"; - msg.append(_node_path).append("' for MIDI learn."); - _responder->respond_error(msg); - } -} - - -} // namespace Ingen - - diff --git a/src/libs/engine/events/MidiLearnEvent.hpp b/src/libs/engine/events/MidiLearnEvent.hpp deleted file mode 100644 index c0fc4a17..00000000 --- a/src/libs/engine/events/MidiLearnEvent.hpp +++ /dev/null @@ -1,85 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard <http://drobilla.net> - * - * 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 MIDILEARNEVENT_H -#define MIDILEARNEVENT_H - -#include "QueuedEvent.hpp" -#include "MidiControlNode.hpp" -#include "types.hpp" -#include <string> -using std::string; - -namespace Ingen { - -class NodeImpl; -class ControlChangeEvent; - - -/** Response event for a MIDI learn. - * - * This is a trivial event that sends a control change in it's post_process - * method (used by MidiLearnEvent to notify clients when the learn happens) - */ -class MidiLearnResponseEvent : public Event -{ -public: - MidiLearnResponseEvent(Engine& engine, const string& port_path, SampleCount timestamp) - : Event(engine, SharedPtr<Responder>(), timestamp), - _port_path(port_path), - _value(0.0f) - {} - - void set_value(Sample val) { _value = val; } - void post_process(); - -private: - string _port_path; - Sample _value; -}; - - - -/** A MIDI learn event. - * - * This creates a MidiLearnResponseEvent and passes it to the learning node, which - * will push it to the post-processor once the learn happens in order to reply - * to the client with the new port (learned controller) value. - * - * \ingroup engine - */ -class MidiLearnEvent : public QueuedEvent -{ -public: - MidiLearnEvent(Engine& engine, SharedPtr<Responder> responder, SampleCount timestamp, const string& node_path); - - void pre_process(); - void execute(ProcessContext& context); - void post_process(); - -private: - const string _node_path; - NodeImpl* _node; - - /// Event to respond with when learned - MidiLearnResponseEvent* _response_event; -}; - - -} // namespace Ingen - -#endif // MIDILEARNEVENT_H diff --git a/src/libs/engine/events/NoteEvent.cpp b/src/libs/engine/events/NoteEvent.cpp deleted file mode 100644 index 58842ae6..00000000 --- a/src/libs/engine/events/NoteEvent.cpp +++ /dev/null @@ -1,102 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard <http://drobilla.net> - * - * 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 "NoteEvent.hpp" -#include "Responder.hpp" -#include "Engine.hpp" -#include "EngineStore.hpp" -#include "NodeImpl.hpp" -#include "MidiNoteNode.hpp" -#include "MidiTriggerNode.hpp" -#include "PluginImpl.hpp" -#include "InternalPlugin.hpp" -#include "ProcessContext.hpp" - -namespace Ingen { - - -/** Note on with Patch explicitly passed. - * - * Used to be triggered by MIDI. Not used anymore. - */ -NoteEvent::NoteEvent(Engine& engine, SharedPtr<Responder> responder, SampleCount timestamp, NodeImpl* node, bool on, uchar note_num, uchar velocity) -: Event(engine, responder, timestamp), - _node(node), - _on(on), - _note_num(note_num), - _velocity(velocity) -{ -} - - -/** Note on with Node lookup. - * - * Triggered by OSC. - */ -NoteEvent::NoteEvent(Engine& engine, SharedPtr<Responder> responder, SampleCount timestamp, const string& node_path, bool on, uchar note_num, uchar velocity) -: Event(engine, responder, timestamp), - _node(NULL), - _node_path(node_path), - _on(on), - _note_num(note_num), - _velocity(velocity) -{ -} - - -void -NoteEvent::execute(ProcessContext& context) -{ - Event::execute(context); - assert(_time >= context.start() && _time <= context.end()); - - // Lookup if neccessary - if (!_node) - _node = _engine.engine_store()->find_node(_node_path); - - // FIXME: barf - - if (_node != NULL && _node->plugin()->type() == Plugin::Internal) { - if (_on) { - if (_node->plugin_impl()->uri() == NS_INGEN "note_node") - ((MidiNoteNode*)_node)->note_on(context, _note_num, _velocity, _time); - else if (_node->plugin_impl()->uri() == NS_INGEN "trigger_node") - ((MidiTriggerNode*)_node)->note_on(context, _note_num, _velocity, _time); - } else { - if (_node->plugin_impl()->uri() == NS_INGEN "note_node") - ((MidiNoteNode*)_node)->note_off(context, _note_num, _time); - else if (_node->plugin_impl()->uri() == NS_INGEN "trigger_node") - ((MidiTriggerNode*)_node)->note_off(context, _note_num, _time); - } - } -} - - -void -NoteEvent::post_process() -{ - if (_responder) { - if (_node) - _responder->respond_ok(); - else - _responder->respond_error("Did not find node for note_on"); - } -} - - -} // namespace Ingen - diff --git a/src/libs/engine/events/NoteEvent.hpp b/src/libs/engine/events/NoteEvent.hpp deleted file mode 100644 index 31ae9d27..00000000 --- a/src/libs/engine/events/NoteEvent.hpp +++ /dev/null @@ -1,68 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard <http://drobilla.net> - * - * 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 NOTEEVENT_H -#define NOTEEVENT_H - -#include "Event.hpp" -#include "types.hpp" -#include <string> -using std::string; - -namespace Ingen { - -class NodeImpl; - - -/** A note on event. - * - * \ingroup engine - */ -class NoteEvent : public Event -{ -public: - NoteEvent(Engine& engine, - SharedPtr<Responder> responder, - SampleCount timestamp, - NodeImpl* node, - bool on, - uchar note_num, - uchar velocity); - - NoteEvent(Engine& engine, - SharedPtr<Responder> responder, - SampleCount timestamp, - const string& node_path, - bool on, - uchar note_num, - uchar velocity); - - void execute(ProcessContext& context); - void post_process(); - -private: - NodeImpl* _node; - const string _node_path; - bool _on; - uchar _note_num; - uchar _velocity; -}; - - -} // namespace Ingen - -#endif // NOTEEVENT_H diff --git a/src/libs/engine/events/PingQueuedEvent.hpp b/src/libs/engine/events/PingQueuedEvent.hpp deleted file mode 100644 index 08897bfe..00000000 --- a/src/libs/engine/events/PingQueuedEvent.hpp +++ /dev/null @@ -1,48 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard <http://drobilla.net> - * - * 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 PINGQUEUEDEVENT_H -#define PINGQUEUEDEVENT_H - -#include "QueuedEvent.hpp" -#include "types.hpp" -#include "Responder.hpp" - -namespace Ingen { - -class PortImpl; - - -/** A ping that travels through the pre-processed event queue before responding - * (useful for the order guarantee). - * - * \ingroup engine - */ -class PingQueuedEvent : public QueuedEvent -{ -public: - PingQueuedEvent(Engine& engine, SharedPtr<Responder> responder, SampleCount timestamp) - : QueuedEvent(engine, responder, timestamp) - {} - - void post_process() { _responder->respond_ok(); } -}; - - -} // namespace Ingen - -#endif // PINGQUEUEDEVENT_H diff --git a/src/libs/engine/events/RegisterClientEvent.cpp b/src/libs/engine/events/RegisterClientEvent.cpp deleted file mode 100644 index a8f68e21..00000000 --- a/src/libs/engine/events/RegisterClientEvent.cpp +++ /dev/null @@ -1,55 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard <http://drobilla.net> - * - * 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 "Responder.hpp" -#include "RegisterClientEvent.hpp" -#include "Engine.hpp" -#include "ClientBroadcaster.hpp" - -namespace Ingen { - - -RegisterClientEvent::RegisterClientEvent(Engine& engine, - SharedPtr<Responder> responder, - SampleCount timestamp, - const string& uri, - ClientInterface* client) - : QueuedEvent(engine, responder, timestamp) - , _uri(uri) - , _client(client) -{ -} - - -void -RegisterClientEvent::pre_process() -{ - _engine.broadcaster()->register_client(_uri, _client); - - QueuedEvent::pre_process(); -} - - -void -RegisterClientEvent::post_process() -{ - _responder->respond_ok(); -} - - -} // namespace Ingen - diff --git a/src/libs/engine/events/RegisterClientEvent.hpp b/src/libs/engine/events/RegisterClientEvent.hpp deleted file mode 100644 index 9e12b5ba..00000000 --- a/src/libs/engine/events/RegisterClientEvent.hpp +++ /dev/null @@ -1,55 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard <http://drobilla.net> - * - * 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 REGISTERCLIENTEVENT_H -#define REGISTERCLIENTEVENT_H - -#include "QueuedEvent.hpp" -#include "interface/ClientInterface.hpp" -#include <string> -using std::string; -using Ingen::Shared::ClientInterface; -using Ingen::Responder; - -namespace Ingen { - - -/** Registers a new client with the OSC system, so it can receive updates. - * - * \ingroup engine - */ -class RegisterClientEvent : public QueuedEvent -{ -public: - RegisterClientEvent(Engine& engine, - SharedPtr<Responder> responder, - SampleCount timestamp, - const string& uri, - ClientInterface* client); - - void pre_process(); - void post_process(); - -private: - string _uri; - ClientInterface* _client; -}; - - -} // namespace Ingen - -#endif // REGISTERCLIENTEVENT_H diff --git a/src/libs/engine/events/RenameEvent.cpp b/src/libs/engine/events/RenameEvent.cpp deleted file mode 100644 index 164676aa..00000000 --- a/src/libs/engine/events/RenameEvent.cpp +++ /dev/null @@ -1,152 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard <http://drobilla.net> - * - * 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 <raul/Path.hpp> -#include "ClientBroadcaster.hpp" -#include "Engine.hpp" -#include "NodeImpl.hpp" -#include "EngineStore.hpp" -#include "PatchImpl.hpp" -#include "RenameEvent.hpp" -#include "Responder.hpp" -#include "AudioDriver.hpp" -#include "MidiDriver.hpp" - -using namespace std; - -namespace Ingen { - - -RenameEvent::RenameEvent(Engine& engine, SharedPtr<Responder> responder, SampleCount timestamp, const string& path, const string& name) -: QueuedEvent(engine, responder, timestamp), - _old_path(path), - _name(name), - _new_path("/"), - _parent_patch(NULL), - _store_iterator(engine.engine_store()->end()), - _error(NO_ERROR) -{ - /* - if (_old_path.parent() == "/") - _new_path = string("/") + _name; - else - _new_path = _old_path.parent() +"/"+ _name;*/ -} - - -RenameEvent::~RenameEvent() -{ -} - - -void -RenameEvent::pre_process() -{ - if ((!Raul::Path::is_valid_name(_name)) || _name.find("/") != string::npos) { - _error = INVALID_NAME; - QueuedEvent::pre_process(); - return; - } - - _new_path = _old_path.parent().base() + _name; - - _store_iterator = _engine.engine_store()->find(_old_path); - if (_store_iterator == _engine.engine_store()->end()) { - _error = OBJECT_NOT_FOUND; - QueuedEvent::pre_process(); - return; - } - - if (_engine.engine_store()->find_object(_new_path)) { - _error = OBJECT_EXISTS; - QueuedEvent::pre_process(); - return; - } - - SharedPtr< Table<Path, SharedPtr<Shared::GraphObject> > > removed - = _engine.engine_store()->remove(_store_iterator); - - assert(removed->size() > 0); - - for (Table<Path, SharedPtr<Shared::GraphObject> >::iterator i = removed->begin(); i != removed->end(); ++i) { - const Path& child_old_path = i->first; - assert(Path::descendant_comparator(_old_path, child_old_path)); - - Path child_new_path; - if (child_old_path == _old_path) - child_new_path = _new_path; - else - child_new_path = _new_path.base() + child_old_path.substr(_old_path.length()+1); - - PtrCast<GraphObjectImpl>(i->second)->set_path(child_new_path); - i->first = child_new_path; - } - - _engine.engine_store()->add(*removed.get()); - - QueuedEvent::pre_process(); -} - - -void -RenameEvent::execute(ProcessContext& context) -{ - QueuedEvent::execute(context); - - SharedPtr<PortImpl> port = PtrCast<PortImpl>(_store_iterator->second); - if (port && port->parent()->parent() == NULL) { - DriverPort* driver_port = NULL; - - if (port->type() == DataType::AUDIO) - driver_port = _engine.audio_driver()->driver_port(_new_path); - else if (port->type() == DataType::EVENT) - driver_port = _engine.midi_driver()->driver_port(_new_path); - - if (driver_port) { - cerr << "DRIVER PORT :)!" << endl; - driver_port->set_name(_new_path); - } else { - cerr << "NO DRIVER PORT :(" << endl; - } - } -} - - -void -RenameEvent::post_process() -{ - string msg = "Unable to rename object - "; - - if (_error == NO_ERROR) { - _responder->respond_ok(); - _engine.broadcaster()->send_rename(_old_path, _new_path); - } else { - if (_error == OBJECT_EXISTS) - msg.append("Object already exists at ").append(_new_path); - else if (_error == OBJECT_NOT_FOUND) - msg.append("Could not find object ").append(_old_path); - else if (_error == OBJECT_NOT_RENAMABLE) - msg.append(_old_path).append(" is not renamable"); - else if (_error == INVALID_NAME) - msg.append(_name).append(" is not a valid name"); - - _responder->respond_error(msg); - } -} - - -} // namespace Ingen diff --git a/src/libs/engine/events/RenameEvent.hpp b/src/libs/engine/events/RenameEvent.hpp deleted file mode 100644 index e230c589..00000000 --- a/src/libs/engine/events/RenameEvent.hpp +++ /dev/null @@ -1,64 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard <http://drobilla.net> - * - * 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 RENAMEEVENT_H -#define RENAMEEVENT_H - -#include <string> -#include <raul/Path.hpp> -#include "QueuedEvent.hpp" -#include "EngineStore.hpp" - -using std::string; - -template<typename T> class TreeNode; -template<typename T> class ListNode; - -namespace Ingen { - -class PatchImpl; - - -/** An event to change the name of an GraphObjectImpl. - * - * \ingroup engine - */ -class RenameEvent : public QueuedEvent -{ -public: - RenameEvent(Engine& engine, SharedPtr<Responder> responder, SampleCount timestamp, const string& path, const string& name); - ~RenameEvent(); - - void pre_process(); - void execute(ProcessContext& context); - void post_process(); - -private: - enum ErrorType { NO_ERROR, OBJECT_NOT_FOUND, OBJECT_EXISTS, OBJECT_NOT_RENAMABLE, INVALID_NAME }; - - Path _old_path; - string _name; - Path _new_path; - PatchImpl* _parent_patch; - EngineStore::iterator _store_iterator; - ErrorType _error; -}; - - -} // namespace Ingen - -#endif // RENAMEEVENT_H diff --git a/src/libs/engine/events/RequestAllObjectsEvent.cpp b/src/libs/engine/events/RequestAllObjectsEvent.cpp deleted file mode 100644 index d57080aa..00000000 --- a/src/libs/engine/events/RequestAllObjectsEvent.cpp +++ /dev/null @@ -1,59 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard <http://drobilla.net> - * - * 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 "RequestAllObjectsEvent.hpp" -#include "Responder.hpp" -#include "Engine.hpp" -#include "ObjectSender.hpp" -#include "ClientBroadcaster.hpp" -#include "EngineStore.hpp" - -namespace Ingen { - - -RequestAllObjectsEvent::RequestAllObjectsEvent(Engine& engine, SharedPtr<Responder> responder, SampleCount timestamp) -: QueuedEvent(engine, responder, timestamp) -{ -} - - -void -RequestAllObjectsEvent::pre_process() -{ - QueuedEvent::pre_process(); -} - - -void -RequestAllObjectsEvent::post_process() -{ - if (_responder->client()) { - _responder->respond_ok(); - - // Everything is a child of the root patch, so this sends it all - PatchImpl* root = _engine.engine_store()->find_patch("/"); - if (root && _responder->client()) - ObjectSender::send_patch(_responder->client(), root, true); - - } else { - _responder->respond_error("Unable to find client to send all objects"); - } -} - - -} // namespace Ingen - diff --git a/src/libs/engine/events/RequestAllObjectsEvent.hpp b/src/libs/engine/events/RequestAllObjectsEvent.hpp deleted file mode 100644 index 0537575a..00000000 --- a/src/libs/engine/events/RequestAllObjectsEvent.hpp +++ /dev/null @@ -1,48 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard <http://drobilla.net> - * - * 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 REQUESTALLOBJECTSEVENT_H -#define REQUESTALLOBJECTSEVENT_H - -#include <string> -#include "QueuedEvent.hpp" -using std::string; - -namespace Ingen { - -namespace Shared { - class ClientInterface; -} using Shared::ClientInterface; - - -/** A request from a client to send notification of all objects (ie refresh). - * - * \ingroup engine - */ -class RequestAllObjectsEvent : public QueuedEvent -{ -public: - RequestAllObjectsEvent(Engine& engine, SharedPtr<Responder> responder, SampleCount timestamp); - - void pre_process(); - void post_process(); -}; - - -} // namespace Ingen - -#endif // REQUESTALLOBJECTSEVENT_H diff --git a/src/libs/engine/events/RequestMetadataEvent.cpp b/src/libs/engine/events/RequestMetadataEvent.cpp deleted file mode 100644 index 733a6a82..00000000 --- a/src/libs/engine/events/RequestMetadataEvent.cpp +++ /dev/null @@ -1,85 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard <http://drobilla.net> - * - * 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 "RequestMetadataEvent.hpp" -#include <string> -#include "Responder.hpp" -#include "Engine.hpp" -#include "GraphObjectImpl.hpp" -#include "EngineStore.hpp" -#include "interface/ClientInterface.hpp" -#include "ClientBroadcaster.hpp" -using std::string; - -namespace Ingen { - - -RequestMetadataEvent::RequestMetadataEvent(Engine& engine, - SharedPtr<Responder> responder, - SampleCount timestamp, - bool property, - const string& node_path, - const string& key) - : QueuedEvent(engine, responder, timestamp) - , _path(node_path) - , _property(property) - , _key(key) - , _object(NULL) -{ -} - - -void -RequestMetadataEvent::pre_process() -{ - if (_responder->client()) { - _object = _engine.engine_store()->find_object(_path); - if (_object == NULL) { - QueuedEvent::pre_process(); - return; - } - } - - if (_property) - _value = _object->get_property(_key); - else - _value = _object->get_variable(_key); - - QueuedEvent::pre_process(); -} - - -void -RequestMetadataEvent::post_process() -{ - if (_responder->client()) { - if (!_object) { - string msg = "Unable to find variable subject "; - msg += _path; - _responder->respond_error(msg); - } else { - _responder->respond_ok(); - _responder->client()->set_variable(_path, _key, _value); - } - } else { - _responder->respond_error("Unknown client"); - } -} - - -} // namespace Ingen - diff --git a/src/libs/engine/events/RequestMetadataEvent.hpp b/src/libs/engine/events/RequestMetadataEvent.hpp deleted file mode 100644 index f6a18dfc..00000000 --- a/src/libs/engine/events/RequestMetadataEvent.hpp +++ /dev/null @@ -1,62 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard <http://drobilla.net> - * - * 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 REQUESTMETADATAEVENT_H -#define REQUESTMETADATAEVENT_H - -#include <string> -#include "QueuedEvent.hpp" -#include <raul/Atom.hpp> -using std::string; - -namespace Ingen { - -class GraphObjectImpl; -namespace Shared { - class ClientInterface; -} using Shared::ClientInterface; - - -/** A request from a client for a piece of variable. - * - * \ingroup engine - */ -class RequestMetadataEvent : public QueuedEvent -{ -public: - RequestMetadataEvent(Engine& engine, - SharedPtr<Responder> responder, - SampleCount timestamp, - bool property, - const string& path, - const string& key); - - void pre_process(); - void post_process(); - -private: - string _path; - bool _property; - string _key; - Raul::Atom _value; - GraphObjectImpl* _object; -}; - - -} // namespace Ingen - -#endif // REQUESTMETADATAEVENT_H diff --git a/src/libs/engine/events/RequestObjectEvent.cpp b/src/libs/engine/events/RequestObjectEvent.cpp deleted file mode 100644 index 88479482..00000000 --- a/src/libs/engine/events/RequestObjectEvent.cpp +++ /dev/null @@ -1,98 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard <http://drobilla.net> - * - * 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 "RequestObjectEvent.hpp" -#include <string> -#include "interface/ClientInterface.hpp" -#include "Responder.hpp" -#include "Engine.hpp" -#include "EngineStore.hpp" -#include "ClientBroadcaster.hpp" -#include "PatchImpl.hpp" -#include "NodeImpl.hpp" -#include "PortImpl.hpp" -#include "ObjectSender.hpp" -#include "ProcessContext.hpp" - -using std::string; - -namespace Ingen { - - -RequestObjectEvent::RequestObjectEvent(Engine& engine, SharedPtr<Responder> responder, SampleCount timestamp, const string& path) -: QueuedEvent(engine, responder, timestamp), - _path(path), - _object(NULL) -{ -} - - -void -RequestObjectEvent::pre_process() -{ - _object = _engine.engine_store()->find_object(_path); - - QueuedEvent::pre_process(); -} - - -void -RequestObjectEvent::execute(ProcessContext& context) -{ - QueuedEvent::execute(context); - assert(_time >= context.start() && _time <= context.end()); -} - - -void -RequestObjectEvent::post_process() -{ - if (!_object) { - _responder->respond_error("Unable to find object requested."); - - } else if (_responder->client()) { - PatchImpl* const patch = dynamic_cast<PatchImpl*>(_object); - if (patch) { - _responder->respond_ok(); - ObjectSender::send_patch(_responder->client(), patch, true); - return; - } - - NodeImpl* const node = dynamic_cast<NodeImpl*>(_object); - if (node) { - _responder->respond_ok(); - ObjectSender::send_node(_responder->client(), node, true); - return; - } - - PortImpl* const port = dynamic_cast<PortImpl*>(_object); - if (port) { - _responder->respond_ok(); - ObjectSender::send_port(_responder->client(), port); - return; - } - - _responder->respond_error("Object of unknown type requested."); - - } else { - _responder->respond_error("Unable to find client to send object."); - } -} - - -} // namespace Ingen - diff --git a/src/libs/engine/events/RequestObjectEvent.hpp b/src/libs/engine/events/RequestObjectEvent.hpp deleted file mode 100644 index 52459ada..00000000 --- a/src/libs/engine/events/RequestObjectEvent.hpp +++ /dev/null @@ -1,55 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard <http://drobilla.net> - * - * 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 REQUESTOBJECTEVENT_H -#define REQUESTOBJECTEVENT_H - -#include <string> -#include "QueuedEvent.hpp" -#include "types.hpp" - -using std::string; - -namespace Ingen { - -class GraphObjectImpl; -namespace Shared { class ClientInterface; } -using Shared::ClientInterface; - - -/** A request from a client to send the value of a port. - * - * \ingroup engine - */ -class RequestObjectEvent : public QueuedEvent -{ -public: - RequestObjectEvent(Engine& engine, SharedPtr<Responder> responder, SampleCount timestamp, const string& port_path); - - void pre_process(); - void execute(ProcessContext& context); - void post_process(); - -private: - const string _path; - GraphObjectImpl* _object; -}; - - -} // namespace Ingen - -#endif // REQUESTOBJECTEVENT_H diff --git a/src/libs/engine/events/RequestPluginEvent.cpp b/src/libs/engine/events/RequestPluginEvent.cpp deleted file mode 100644 index 36358df7..00000000 --- a/src/libs/engine/events/RequestPluginEvent.cpp +++ /dev/null @@ -1,79 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard <http://drobilla.net> - * - * 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 <string> -#include "interface/ClientInterface.hpp" -#include "RequestPluginEvent.hpp" -#include "Responder.hpp" -#include "Engine.hpp" -#include "PortImpl.hpp" -#include "EngineStore.hpp" -#include "ClientBroadcaster.hpp" -#include "NodeFactory.hpp" -#include "PluginImpl.hpp" -#include "ProcessContext.hpp" - -using std::string; - -namespace Ingen { - - -RequestPluginEvent::RequestPluginEvent(Engine& engine, SharedPtr<Responder> responder, SampleCount timestamp, const string& uri) -: QueuedEvent(engine, responder, timestamp), - _uri(uri), - _plugin(NULL) -{ -} - - -void -RequestPluginEvent::pre_process() -{ - _plugin = _engine.node_factory()->plugin(_uri); - - QueuedEvent::pre_process(); -} - - -void -RequestPluginEvent::execute(ProcessContext& context) -{ - QueuedEvent::execute(context); - assert(_time >= context.start() && _time <= context.end()); -} - - -void -RequestPluginEvent::post_process() -{ - if (!_plugin) { - _responder->respond_error("Unable to find plugin requested."); - - } else if (_responder->client()) { - - _responder->respond_ok(); - assert(_plugin->uri() == _uri); - _responder->client()->new_plugin(_uri, _plugin->type_uri(), _plugin->symbol(), _plugin->name()); - - } else { - _responder->respond_error("Unable to find client to send plugin."); - } -} - - -} // namespace Ingen - diff --git a/src/libs/engine/events/RequestPluginEvent.hpp b/src/libs/engine/events/RequestPluginEvent.hpp deleted file mode 100644 index 8f936098..00000000 --- a/src/libs/engine/events/RequestPluginEvent.hpp +++ /dev/null @@ -1,53 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard <http://drobilla.net> - * - * 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 REQUESTPLUGINEVENT_H -#define REQUESTPLUGINEVENT_H - -#include <string> -#include "QueuedEvent.hpp" -#include "types.hpp" - -using std::string; - -namespace Ingen { - -class PluginImpl; - - -/** A request from a client to send information about a plugin. - * - * \ingroup engine - */ -class RequestPluginEvent : public QueuedEvent -{ -public: - RequestPluginEvent(Engine& engine, SharedPtr<Responder> responder, SampleCount timestamp, const string& uri); - - void pre_process(); - void execute(ProcessContext& context); - void post_process(); - -private: - const string _uri; - const PluginImpl* _plugin; -}; - - -} // namespace Ingen - -#endif // REQUESTPLUGINEVENT_H diff --git a/src/libs/engine/events/RequestPluginsEvent.cpp b/src/libs/engine/events/RequestPluginsEvent.cpp deleted file mode 100644 index 8d7fc1ba..00000000 --- a/src/libs/engine/events/RequestPluginsEvent.cpp +++ /dev/null @@ -1,57 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard <http://drobilla.net> - * - * 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 "RequestPluginsEvent.hpp" -#include "Responder.hpp" -#include "Engine.hpp" -#include "ClientBroadcaster.hpp" -#include "NodeFactory.hpp" - -namespace Ingen { - - -RequestPluginsEvent::RequestPluginsEvent(Engine& engine, SharedPtr<Responder> responder, SampleCount timestamp) -: QueuedEvent(engine, responder, timestamp) -{ -} - - -void -RequestPluginsEvent::pre_process() -{ - // Take a copy to send in the post processing thread (to avoid problems - // because std::map isn't thread safe) - _plugins = _engine.node_factory()->plugins(); - - QueuedEvent::pre_process(); -} - - -void -RequestPluginsEvent::post_process() -{ - if (_responder->client()) { - _engine.broadcaster()->send_plugins_to(_responder->client(), _plugins); - _responder->respond_ok(); - } else { - _responder->respond_error("Unable to find client to send plugins"); - } -} - - -} // namespace Ingen - diff --git a/src/libs/engine/events/RequestPluginsEvent.hpp b/src/libs/engine/events/RequestPluginsEvent.hpp deleted file mode 100644 index f6b41d7a..00000000 --- a/src/libs/engine/events/RequestPluginsEvent.hpp +++ /dev/null @@ -1,47 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard <http://drobilla.net> - * - * 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 REQUESTPLUGINSEVENT_H -#define REQUESTPLUGINSEVENT_H - -#include "QueuedEvent.hpp" -#include "NodeFactory.hpp" - -namespace Ingen { - -class Responder; - -/** A request from a client to send notification of all objects (ie refresh). - * - * \ingroup engine - */ -class RequestPluginsEvent : public QueuedEvent -{ -public: - RequestPluginsEvent(Engine& engine, SharedPtr<Responder> responder, SampleCount timestamp); - - void pre_process(); - void post_process(); - -private: - NodeFactory::Plugins _plugins; -}; - - -} // namespace Ingen - -#endif // REQUESTPLUGINSEVENT_H diff --git a/src/libs/engine/events/RequestPortValueEvent.cpp b/src/libs/engine/events/RequestPortValueEvent.cpp deleted file mode 100644 index 025d3700..00000000 --- a/src/libs/engine/events/RequestPortValueEvent.cpp +++ /dev/null @@ -1,81 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard <http://drobilla.net> - * - * 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 "RequestPortValueEvent.hpp" -#include <string> -#include "interface/ClientInterface.hpp" -#include "Responder.hpp" -#include "Engine.hpp" -#include "PortImpl.hpp" -#include "EngineStore.hpp" -#include "ClientBroadcaster.hpp" -#include "AudioBuffer.hpp" -#include "ProcessContext.hpp" - -using std::string; - -namespace Ingen { - - -RequestPortValueEvent::RequestPortValueEvent(Engine& engine, SharedPtr<Responder> responder, SampleCount timestamp, const string& port_path) -: QueuedEvent(engine, responder, timestamp), - _port_path(port_path), - _port(NULL), - _value(0.0) -{ -} - - -void -RequestPortValueEvent::pre_process() -{ - _port = _engine.engine_store()->find_port(_port_path); - - QueuedEvent::pre_process(); -} - - -void -RequestPortValueEvent::execute(ProcessContext& context) -{ - QueuedEvent::execute(context); - assert(_time >= context.start() && _time <= context.end()); - - if (_port != NULL && (_port->type() == DataType::CONTROL || _port->type() == DataType::AUDIO)) - _value = ((AudioBuffer*)_port->buffer(0))->value_at(0/*_time - start*/); - else - _port = NULL; // triggers error response -} - - -void -RequestPortValueEvent::post_process() -{ - string msg; - if (!_port) { - _responder->respond_error("Unable to find port for get_value responder."); - } else if (_responder->client()) { - _responder->respond_ok(); - _responder->client()->set_port_value(_port_path, _value); - } else { - _responder->respond_error("Unable to find client to send port value"); - } -} - - -} // namespace Ingen - diff --git a/src/libs/engine/events/RequestPortValueEvent.hpp b/src/libs/engine/events/RequestPortValueEvent.hpp deleted file mode 100644 index dd52c535..00000000 --- a/src/libs/engine/events/RequestPortValueEvent.hpp +++ /dev/null @@ -1,56 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard <http://drobilla.net> - * - * 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 REQUESTPORTVALUEEVENT_H -#define REQUESTPORTVALUEEVENT_H - -#include <string> -#include "QueuedEvent.hpp" -#include "types.hpp" - -using std::string; - -namespace Ingen { - -class PortImpl; -namespace Shared { class ClientInterface; } -using Shared::ClientInterface; - - -/** A request from a client to send the value of a port. - * - * \ingroup engine - */ -class RequestPortValueEvent : public QueuedEvent -{ -public: - RequestPortValueEvent(Engine& engine, SharedPtr<Responder> responder, SampleCount timestamp, const string& port_path); - - void pre_process(); - void execute(ProcessContext& context); - void post_process(); - -private: - const string _port_path; - PortImpl* _port; - Sample _value; -}; - - -} // namespace Ingen - -#endif // REQUESTPORTVALUEEVENT_H diff --git a/src/libs/engine/events/SendPortActivityEvent.cpp b/src/libs/engine/events/SendPortActivityEvent.cpp deleted file mode 100644 index 0ab3abdd..00000000 --- a/src/libs/engine/events/SendPortActivityEvent.cpp +++ /dev/null @@ -1,34 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard <http://drobilla.net> - * - * 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 "SendPortActivityEvent.hpp" -#include "Engine.hpp" -#include "PortImpl.hpp" -#include "ClientBroadcaster.hpp" - -namespace Ingen { - - -void -SendPortActivityEvent::post_process() -{ - _engine.broadcaster()->send_port_activity(_port->path()); -} - - -} // namespace Ingen - diff --git a/src/libs/engine/events/SendPortActivityEvent.hpp b/src/libs/engine/events/SendPortActivityEvent.hpp deleted file mode 100644 index dfbb8a10..00000000 --- a/src/libs/engine/events/SendPortActivityEvent.hpp +++ /dev/null @@ -1,67 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard <http://drobilla.net> - * - * 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 SENDPORTACTIVITYEVENT_H -#define SENDPORTACTIVITYEVENT_H - -#include <string> -#include "Event.hpp" -#include "types.hpp" -using std::string; - -namespace Ingen { - -class PortImpl; - - -/** A special event used internally to send port activity notification (e.g. - * MIDI event activity) from the audio thread. - * - * This is created in the audio thread (directly in a ringbuffer, not new'd) - * for processing in the post processing thread (unlike normal events which - * are created in the pre-processor thread then run through the audio - * thread). This event's job is done entirely in post_process. - * - * This only really makes sense for message ports. - * - * \ingroup engine - */ -class SendPortActivityEvent : public Event -{ -public: - inline SendPortActivityEvent(Engine& engine, - SampleCount timestamp, - PortImpl* port) - : Event(engine, SharedPtr<Responder>(), timestamp) - , _port(port) - { - } - - inline void operator=(const SendPortActivityEvent& ev) { - _port = ev._port; - } - - void post_process(); - -private: - PortImpl* _port; -}; - - -} // namespace Ingen - -#endif // SENDPORTACTIVITYEVENT_H diff --git a/src/libs/engine/events/SendPortValueEvent.cpp b/src/libs/engine/events/SendPortValueEvent.cpp deleted file mode 100644 index d3fb0d36..00000000 --- a/src/libs/engine/events/SendPortValueEvent.cpp +++ /dev/null @@ -1,43 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard <http://drobilla.net> - * - * 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 <sstream> -#include "SendPortValueEvent.hpp" -#include "Engine.hpp" -#include "PortImpl.hpp" -#include "ClientBroadcaster.hpp" - -using namespace std; - -namespace Ingen { - - -void -SendPortValueEvent::post_process() -{ - // FIXME... - - if (_omni) { - _engine.broadcaster()->send_port_value(_port->path(), _value); - } else { - _engine.broadcaster()->send_port_value(_port->path(), _value); - } -} - - -} // namespace Ingen - diff --git a/src/libs/engine/events/SendPortValueEvent.hpp b/src/libs/engine/events/SendPortValueEvent.hpp deleted file mode 100644 index e8505914..00000000 --- a/src/libs/engine/events/SendPortValueEvent.hpp +++ /dev/null @@ -1,78 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard <http://drobilla.net> - * - * 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 SENDPORTVALUEEVENT_H -#define SENDPORTVALUEEVENT_H - -#include <string> -#include "Event.hpp" -#include "types.hpp" -using std::string; - -namespace Ingen { - -class PortImpl; - - -/** A special event used internally to send port values from the audio thread. - * - * This is created in the audio thread (using in-place new on a preallocated - * buffer) for processing in the post processing thread (unlike normal events - * which are created in the pre-processor thread then run through the audio - * thread). This event's job is done entirely in post_process. - * - * This only works for control ports right now. - * - * \ingroup engine - */ -class SendPortValueEvent : public Event -{ -public: - inline SendPortValueEvent(Engine& engine, - SampleCount timestamp, - PortImpl* port, - bool omni, - uint32_t voice_num, - Sample value) - : Event(engine, SharedPtr<Responder>(), timestamp) - , _port(port) - , _omni(omni) - , _voice_num(voice_num) - , _value(value) - { - } - - inline void operator=(const SendPortValueEvent& ev) { - _port = ev._port; - _omni = ev._omni; - _voice_num = ev._voice_num; - _value = ev._value; - } - - void post_process(); - -private: - PortImpl* _port; - bool _omni; - uint32_t _voice_num; - Sample _value; -}; - - -} // namespace Ingen - -#endif // SENDPORTVALUEEVENT_H diff --git a/src/libs/engine/events/SetMetadataEvent.cpp b/src/libs/engine/events/SetMetadataEvent.cpp deleted file mode 100644 index db4bbc30..00000000 --- a/src/libs/engine/events/SetMetadataEvent.cpp +++ /dev/null @@ -1,114 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard <http://drobilla.net> - * - * 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 "SetMetadataEvent.hpp" -#include <string> -#include <boost/format.hpp> -#include "Responder.hpp" -#include "Engine.hpp" -#include "PortImpl.hpp" -#include "ClientBroadcaster.hpp" -#include "GraphObjectImpl.hpp" -#include "EngineStore.hpp" - -using std::string; - -namespace Ingen { - - -SetMetadataEvent::SetMetadataEvent( - Engine& engine, - SharedPtr<Responder> responder, - SampleCount timestamp, - bool property, - const string& path, - const string& key, - const Atom& value) - : QueuedEvent(engine, responder, timestamp) - , _error(NO_ERROR) - , _special_type(NONE) - , _property(property) - , _path(path) - , _key(key) - , _value(value) - , _object(NULL) -{ -} - - -void -SetMetadataEvent::pre_process() -{ - if (!Path::is_valid(_path)) { - _error = INVALID_PATH; - QueuedEvent::pre_process(); - return; - } - - _object = _engine.engine_store()->find_object(_path); - if (_object == NULL) { - QueuedEvent::pre_process(); - return; - } - - if (_property) - _object->set_property(_key, _value); - else - _object->set_variable(_key, _value); - - if (_key == "ingen:broadcast") { - std::cout << "BROADCAST" << std::endl; - _special_type = ENABLE_BROADCAST; - } - - QueuedEvent::pre_process(); -} - - -void -SetMetadataEvent::execute(ProcessContext& context) -{ - if (_special_type == ENABLE_BROADCAST) { - PortImpl* port = dynamic_cast<PortImpl*>(_object); - if (port) - port->broadcast(_value.get_bool()); - } - - QueuedEvent::execute(context); - // Do nothing -} - - -void -SetMetadataEvent::post_process() -{ - if (_error == INVALID_PATH) { - _responder->respond_error((boost::format("Invalid path %1% setting %2%") % _path % _key).str()); - } else if (_object == NULL) { - string msg = (boost::format("Unable to find object %1% to set %2%") % _path % _key).str(); - _responder->respond_error(msg); - } else { - _responder->respond_ok(); - if (_property) - _engine.broadcaster()->send_property_change(_path, _key, _value); - else - _engine.broadcaster()->send_variable_change(_path, _key, _value); - } -} - - -} // namespace Ingen diff --git a/src/libs/engine/events/SetMetadataEvent.hpp b/src/libs/engine/events/SetMetadataEvent.hpp deleted file mode 100644 index 6b9be81c..00000000 --- a/src/libs/engine/events/SetMetadataEvent.hpp +++ /dev/null @@ -1,65 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard <http://drobilla.net> - * - * 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 SETMETADATAEVENT_H -#define SETMETADATAEVENT_H - -#include <string> -#include "QueuedEvent.hpp" -#include <raul/Atom.hpp> - -using std::string; - -namespace Ingen { - -class GraphObjectImpl; - - -/** An event to set a piece of variable for an GraphObjectImpl. - * - * \ingroup engine - */ -class SetMetadataEvent : public QueuedEvent -{ -public: - SetMetadataEvent(Engine& engine, - SharedPtr<Responder> responder, - SampleCount timestamp, - bool property, - const string& path, - const string& key, - const Raul::Atom& value); - - void pre_process(); - void execute(ProcessContext& context); - void post_process(); - -private: - enum { NO_ERROR, INVALID_PATH } _error; - enum { NONE, ENABLE_BROADCAST } _special_type; - - bool _property; - string _path; - string _key; - Raul::Atom _value; - GraphObjectImpl* _object; -}; - - -} // namespace Ingen - -#endif // SETMETADATAEVENT_H diff --git a/src/libs/engine/events/SetPolyphonicEvent.cpp b/src/libs/engine/events/SetPolyphonicEvent.cpp deleted file mode 100644 index d1fc6a7c..00000000 --- a/src/libs/engine/events/SetPolyphonicEvent.cpp +++ /dev/null @@ -1,82 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard <http://drobilla.net> - * - * 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 <raul/Maid.hpp> -#include "SetPolyphonicEvent.hpp" -#include "Responder.hpp" -#include "Engine.hpp" -#include "PatchImpl.hpp" -#include "ClientBroadcaster.hpp" -#include "util.hpp" -#include "EngineStore.hpp" -#include "PortImpl.hpp" -#include "NodeImpl.hpp" -#include "ConnectionImpl.hpp" -#include "QueuedEventSource.hpp" - -namespace Ingen { - - -SetPolyphonicEvent::SetPolyphonicEvent(Engine& engine, SharedPtr<Responder> responder, FrameTime time, QueuedEventSource* source, const string& path, bool poly) -: QueuedEvent(engine, responder, time, true, source), - _path(path), - _object(NULL), - _poly(poly), - _success(false) -{ -} - - -void -SetPolyphonicEvent::pre_process() -{ - _object = _engine.engine_store()->find_object(_path); - - QueuedEvent::pre_process(); -} - - -void -SetPolyphonicEvent::execute(ProcessContext& context) -{ - QueuedEvent::execute(context); - - if (_object) - _success = _object->set_polyphonic(*_engine.maid(), _poly); - - _source->unblock(); -} - - -void -SetPolyphonicEvent::post_process() -{ - if (_object) { - if (_success) { - _responder->respond_ok(); - _engine.broadcaster()->send_property_change(_path, "ingen:polyphonic", _poly); - } else { - _responder->respond_error("Unable to set object as polyphonic"); - } - } else { - _responder->respond_error("Unable to find object to set polyphonic"); - } -} - - -} // namespace Ingen - diff --git a/src/libs/engine/events/SetPolyphonicEvent.hpp b/src/libs/engine/events/SetPolyphonicEvent.hpp deleted file mode 100644 index 9079d49f..00000000 --- a/src/libs/engine/events/SetPolyphonicEvent.hpp +++ /dev/null @@ -1,56 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard <http://drobilla.net> - * - * 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 SETPOLYPHONICEVENT_H -#define SETPOLYPHONICEVENT_H - -#include <string> -#include <raul/Array.hpp> -#include "QueuedEvent.hpp" - -using std::string; - -namespace Ingen { - -class GraphObjectImpl; - - -/** Delete all nodes from a patch. - * - * \ingroup engine - */ -class SetPolyphonicEvent : public QueuedEvent -{ -public: - SetPolyphonicEvent(Engine& engine, SharedPtr<Responder> responder, FrameTime time, QueuedEventSource* source, const string& path, bool poly); - - void pre_process(); - void execute(ProcessContext& context); - void post_process(); - -private: - const string _path; - GraphObjectImpl* _object; - bool _poly; - bool _success; -}; - - -} // namespace Ingen - - -#endif // SETPOLYPHONICEVENT_H diff --git a/src/libs/engine/events/SetPolyphonyEvent.cpp b/src/libs/engine/events/SetPolyphonyEvent.cpp deleted file mode 100644 index eb6550cb..00000000 --- a/src/libs/engine/events/SetPolyphonyEvent.cpp +++ /dev/null @@ -1,79 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard <http://drobilla.net> - * - * 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 <raul/Maid.hpp> -#include "SetPolyphonyEvent.hpp" -#include "Responder.hpp" -#include "Engine.hpp" -#include "PatchImpl.hpp" -#include "ClientBroadcaster.hpp" -#include "util.hpp" -#include "EngineStore.hpp" -#include "PortImpl.hpp" -#include "NodeImpl.hpp" -#include "ConnectionImpl.hpp" -#include "QueuedEventSource.hpp" - -namespace Ingen { - - -SetPolyphonyEvent::SetPolyphonyEvent(Engine& engine, SharedPtr<Responder> responder, FrameTime time, QueuedEventSource* source, const string& patch_path, uint32_t poly) -: QueuedEvent(engine, responder, time, true, source), - _patch_path(patch_path), - _patch(NULL), - _poly(poly) -{ -} - - -void -SetPolyphonyEvent::pre_process() -{ - _patch = _engine.engine_store()->find_patch(_patch_path); - if (_patch && _poly > _patch->internal_polyphony()) - _patch->prepare_internal_poly(_poly); - - QueuedEvent::pre_process(); -} - - -void -SetPolyphonyEvent::execute(ProcessContext& context) -{ - QueuedEvent::execute(context); - - if (_patch) - _patch->apply_internal_poly(*_engine.maid(), _poly); - - _source->unblock(); -} - - -void -SetPolyphonyEvent::post_process() -{ - if (_patch) { - _responder->respond_ok(); - _engine.broadcaster()->send_property_change(_patch_path, "ingen:polyphony", (int32_t)_poly); - } else { - _responder->respond_error("Unable to find patch"); - } -} - - -} // namespace Ingen - diff --git a/src/libs/engine/events/SetPolyphonyEvent.hpp b/src/libs/engine/events/SetPolyphonyEvent.hpp deleted file mode 100644 index 8aba997a..00000000 --- a/src/libs/engine/events/SetPolyphonyEvent.hpp +++ /dev/null @@ -1,56 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard <http://drobilla.net> - * - * 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 SETPOLYPHONYEVENT_H -#define SETPOLYPHONYEVENT_H - -#include <string> -#include <raul/Array.hpp> -#include "QueuedEvent.hpp" - -using std::string; - -namespace Ingen { - -class PatchImpl; - - -/** Delete all nodes from a patch. - * - * \ingroup engine - */ -class SetPolyphonyEvent : public QueuedEvent -{ -public: - SetPolyphonyEvent(Engine& engine, SharedPtr<Responder> responder, FrameTime time, QueuedEventSource* source, const string& patch_path, uint32_t poly); - - void pre_process(); - void execute(ProcessContext& context); - void post_process(); - -private: - const string _patch_path; - PatchImpl* _patch; - const uint32_t _poly; - -}; - - -} // namespace Ingen - - -#endif // SETPOLYPHONYEVENT_H diff --git a/src/libs/engine/events/SetPortValueEvent.cpp b/src/libs/engine/events/SetPortValueEvent.cpp deleted file mode 100644 index a99b9f9a..00000000 --- a/src/libs/engine/events/SetPortValueEvent.cpp +++ /dev/null @@ -1,224 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard <http://drobilla.net> - * - * 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 <sstream> -#include <lv2ext/lv2_event.h> -#include "Responder.hpp" -#include "SetPortValueEvent.hpp" -#include "Engine.hpp" -#include "PortImpl.hpp" -#include "ClientBroadcaster.hpp" -#include "NodeImpl.hpp" -#include "EngineStore.hpp" -#include "AudioBuffer.hpp" -#include "EventBuffer.hpp" -#include "ProcessContext.hpp" -#include "MessageContext.hpp" - -using namespace std; - -namespace Ingen { - - -/** Omni (all voices) control setting */ -SetPortValueEvent::SetPortValueEvent(Engine& engine, - SharedPtr<Responder> responder, - bool queued, - SampleCount timestamp, - const string& port_path, - const Raul::Atom& value) - : QueuedEvent(engine, responder, timestamp) - , _queued(queued) - , _omni(true) - , _voice_num(0) - , _port_path(port_path) - , _value(value) - , _port(NULL) - , _error(NO_ERROR) -{ -} - - -/** Voice-specific control setting */ -SetPortValueEvent::SetPortValueEvent(Engine& engine, - SharedPtr<Responder> responder, - bool queued, - SampleCount timestamp, - uint32_t voice_num, - const string& port_path, - const Raul::Atom& value) - : QueuedEvent(engine, responder, timestamp) - , _queued(queued) - , _omni(false) - , _voice_num(voice_num) - , _port_path(port_path) - , _value(value) - , _port(NULL) - , _error(NO_ERROR) -{ -} - - -SetPortValueEvent::~SetPortValueEvent() -{ -} - - -void -SetPortValueEvent::pre_process() -{ - if (_queued) { - if (_port == NULL) { - if (Path::is_valid(_port_path)) - _port = _engine.engine_store()->find_port(_port_path); - else - _error = ILLEGAL_PATH; - } - - if (_port == NULL && _error == NO_ERROR) - _error = PORT_NOT_FOUND; - } - - // Port is a message context port, set its value and - // call the plugin's message run function once - if (_port && _port->context() == Context::MESSAGE) { - _engine.message_context()->run(_port->parent_node()); - } - - QueuedEvent::pre_process(); -} - - -void -SetPortValueEvent::execute(ProcessContext& context) -{ - Event::execute(context); - assert(_time >= context.start() && _time <= context.end()); - - if (_port && _port->context() == Context::MESSAGE) - return; - - if (_error == NO_ERROR && _port == NULL) { - if (Path::is_valid(_port_path)) - _port = _engine.engine_store()->find_port(_port_path); - else - _error = ILLEGAL_PATH; - } - - if (_port == NULL) { - if (_error == NO_ERROR) - _error = PORT_NOT_FOUND; - /*} else if (_port->buffer(0)->capacity() < _data_size) { - _error = NO_SPACE;*/ - } else { - Buffer* const buf = _port->buffer(0); - AudioBuffer* const abuf = dynamic_cast<AudioBuffer*>(buf); - if (abuf) { - if (_value.type() != Atom::FLOAT) { - _error = TYPE_MISMATCH; - return; - } - - if (_omni) { - for (uint32_t i=0; i < _port->poly(); ++i) - ((AudioBuffer*)_port->buffer(i))->set_value( - _value.get_float(), context.start(), _time); - } else { - if (_voice_num < _port->poly()) - ((AudioBuffer*)_port->buffer(_voice_num))->set_value( - _value.get_float(), context.start(), _time); - else - _error = ILLEGAL_VOICE; - } - return; - } - - EventBuffer* const ebuf = dynamic_cast<EventBuffer*>(buf); - - const LV2Features::Feature* f = _engine.world()->lv2_features->feature(LV2_URI_MAP_URI); - LV2URIMap* map = (LV2URIMap*)f->controller; - - // FIXME: eliminate lookups - // FIXME: need a proper prefix system - if (ebuf && _value.type() == Atom::BLOB) { - const uint32_t frames = std::max( - (uint32_t)(_time - context.start()), - ebuf->latest_frames()); - - // Size 0 event, pass it along to the plugin as a typed but empty event - if (_value.data_size() == 0) { - cout << "BANG!" << endl; - const uint32_t type_id = map->uri_to_id(NULL, _value.get_blob_type()); - ebuf->append(frames, 0, type_id, 0, NULL); - _port->raise_set_by_user_flag(); - return; - - } else if (!strcmp(_value.get_blob_type(), "lv2_midi:MidiEvent")) { - const uint32_t type_id = map->uri_to_id(NULL, - "http://lv2plug.in/ns/ext/midi#MidiEvent"); - - ebuf->prepare_write(context.start(), context.nframes()); - // FIXME: use OSC midi type? avoid MIDI over OSC entirely? - ebuf->append(frames, 0, type_id, _value.data_size(), - (const uint8_t*)_value.get_blob()); - _port->raise_set_by_user_flag(); - return; - } - } - - if (_value.type() == Atom::BLOB) - cerr << "WARNING: Unknown value blob type " << _value.get_blob_type() << endl; - else - cerr << "WARNING: Unknown value type " << (int)_value.type() << endl; - } -} - - -void -SetPortValueEvent::post_process() -{ - if (_error == NO_ERROR) { - assert(_port != NULL); - _responder->respond_ok(); - _engine.broadcaster()->send_port_value(_port_path, _value); - - } else if (_error == ILLEGAL_PATH) { - string msg = "Illegal port path \""; - msg.append(_port_path).append("\""); - _responder->respond_error(msg); - - } else if (_error == ILLEGAL_VOICE) { - std::ostringstream ss; - ss << "Illegal voice number " << _voice_num; - _responder->respond_error(ss.str()); - - } else if (_error == PORT_NOT_FOUND) { - string msg = "Unable to find port "; - msg.append(_port_path).append(" for set_port_value"); - _responder->respond_error(msg); - - } else if (_error == NO_SPACE) { - std::ostringstream msg("Attempt to write "); - msg << _value.data_size() << " bytes to " << _port_path << ", with capacity " - << _port->buffer_size() << endl; - _responder->respond_error(msg.str()); - } -} - - -} // namespace Ingen - diff --git a/src/libs/engine/events/SetPortValueEvent.hpp b/src/libs/engine/events/SetPortValueEvent.hpp deleted file mode 100644 index 2fc68d9b..00000000 --- a/src/libs/engine/events/SetPortValueEvent.hpp +++ /dev/null @@ -1,80 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard <http://drobilla.net> - * - * 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 SETPORTVALUEEVENT_H -#define SETPORTVALUEEVENT_H - -#include <string> -#include "QueuedEvent.hpp" -#include "types.hpp" -using std::string; - -namespace Ingen { - -class PortImpl; - - -/** An event to change the value of a port. - * - * This event can either be queued or immediate, depending on the queued - * parameter passed to the constructor. It must be passed to the appropriate - * place (ie queued event passed to the event queue and non-queued event - * processed in the audio thread) or nasty things will happen. - * - * \ingroup engine - */ -class SetPortValueEvent : public QueuedEvent -{ -public: - SetPortValueEvent(Engine& engine, - SharedPtr<Responder> responder, - bool queued, - SampleCount timestamp, - const string& port_path, - const Raul::Atom& value); - - SetPortValueEvent(Engine& engine, - SharedPtr<Responder> responder, - bool queued, - SampleCount timestamp, - uint32_t voice_num, - const string& port_path, - const Raul::Atom& value); - - ~SetPortValueEvent(); - - void pre_process(); - void execute(ProcessContext& context); - void post_process(); - -private: - enum ErrorType { NO_ERROR, PORT_NOT_FOUND, NO_SPACE, - ILLEGAL_PATH, ILLEGAL_VOICE, TYPE_MISMATCH }; - - bool _queued; - bool _omni; - uint32_t _voice_num; - const string _port_path; - const Raul::Atom _value; - PortImpl* _port; - ErrorType _error; -}; - - -} // namespace Ingen - -#endif // SETPORTVALUEEVENT_H diff --git a/src/libs/engine/events/UnregisterClientEvent.cpp b/src/libs/engine/events/UnregisterClientEvent.cpp deleted file mode 100644 index 72ab8048..00000000 --- a/src/libs/engine/events/UnregisterClientEvent.cpp +++ /dev/null @@ -1,45 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard <http://drobilla.net> - * - * 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 "interface/ClientInterface.hpp" -#include "Responder.hpp" -#include "UnregisterClientEvent.hpp" -#include "Engine.hpp" -#include "ClientBroadcaster.hpp" - -namespace Ingen { - - -UnregisterClientEvent::UnregisterClientEvent(Engine& engine, SharedPtr<Responder> responder, SampleCount timestamp, const string& uri) -: QueuedEvent(engine, responder, timestamp) -, _uri(uri) -{ -} - - -void -UnregisterClientEvent::post_process() -{ - if (_engine.broadcaster()->unregister_client(_uri)) - _responder->respond_ok(); - else - _responder->respond_error("Unable to unregister client"); -} - - -} // namespace Ingen - diff --git a/src/libs/engine/events/UnregisterClientEvent.hpp b/src/libs/engine/events/UnregisterClientEvent.hpp deleted file mode 100644 index c21bc5da..00000000 --- a/src/libs/engine/events/UnregisterClientEvent.hpp +++ /dev/null @@ -1,54 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard <http://drobilla.net> - * - * 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 UNREGISTERCLIENTEVENT_H -#define UNREGISTERCLIENTEVENT_H - -#include "QueuedEvent.hpp" -#include <string> -using std::string; - -namespace Ingen { - -namespace Shared { - class ClientInterface; -} -using Shared::ClientInterface; - - -/** Unregisters an OSC client so it no longer receives notifications. - * - * \ingroup engine - */ -class UnregisterClientEvent : public QueuedEvent -{ -public: - UnregisterClientEvent(Engine& engine, - SharedPtr<Responder> responder, - SampleCount timestamp, - const string& uri); - - void post_process(); - -private: - string _uri; -}; - - -} // namespace Ingen - -#endif // UNREGISTERCLIENTEVENT_H diff --git a/src/libs/engine/jack_compat.h b/src/libs/engine/jack_compat.h deleted file mode 100644 index 792148e8..00000000 --- a/src/libs/engine/jack_compat.h +++ /dev/null @@ -1,56 +0,0 @@ -/* JACK MIDI API compatibility hacks. - * Copyright (C) 2007 Nedko Arnaudov <nedko@arnaudov.name> - * - * This program 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; version 2 of the License - * - * This program 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 more 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 JACK_COMPAT_H -#define JACK_COMPAT_H - - -#if defined(JACK_MIDI_NEEDS_NFRAMES) - -jack_nframes_t -jack_midi_get_event_count_compat( - void * port_buffer) -{ -#if defined(HAVE_OLD_JACK_MIDI) - return jack_midi_port_get_info(port_buffer, 0)->event_count; -#else - return jack_midi_get_event_count(port_buffer, 0); -#endif -} - -#define jack_midi_get_event_count jack_midi_get_event_count_compat - -int -jack_midi_event_get_compat( - jack_midi_event_t * event, - void * port_buffer, - jack_nframes_t event_index) -{ - return jack_midi_event_get(event, port_buffer, event_index, 0); -} - -#define jack_midi_event_get jack_midi_event_get_compat - -#else - -#if defined(HAVE_OLD_JACK_MIDI) -#error "Old (0.102.20) JACK MIDI API needs nframes (autotools probably gone mad)" -#endif - -#endif /* #if defined(JACK_MIDI_NEEDS_NFRAMES) */ - -#endif /* JACK_COMPAT_H */ diff --git a/src/libs/engine/lv2_contexts.h b/src/libs/engine/lv2_contexts.h deleted file mode 120000 index 8556a582..00000000 --- a/src/libs/engine/lv2_contexts.h +++ /dev/null @@ -1 +0,0 @@ -../../../../lv2/lv2/contexts/lv2_contexts.h
\ No newline at end of file diff --git a/src/libs/engine/tuning.hpp b/src/libs/engine/tuning.hpp deleted file mode 100644 index 7ec55ae4..00000000 --- a/src/libs/engine/tuning.hpp +++ /dev/null @@ -1,39 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard <http://drobilla.net> - * - * 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 TUNING_H -#define TUNING_H - -#include <stddef.h> -#include <time.h> - -namespace Ingen { - -// FIXME: put this in a Config class - -static const size_t event_queue_size = 1024; -static const size_t pre_processor_queue_size = 1024; -static const size_t post_processor_queue_size = 1024; -static const size_t maid_queue_size = 1024; - -//static const timespec main_rate = { 0, 500000000 }; // 1/2 second -static const timespec main_rate = { 0, 125000000 }; // 1/8 second - - -} // namespace Ingen - -#endif // TUNING_H diff --git a/src/libs/engine/types.hpp b/src/libs/engine/types.hpp deleted file mode 100644 index d242e61d..00000000 --- a/src/libs/engine/types.hpp +++ /dev/null @@ -1,33 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard <http://drobilla.net> - * - * 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 TYPES_HPP -#define TYPES_HPP - -#include <cstddef> // for NULL, size_t, etc -#include <jack/jack.h> - -typedef unsigned char uchar; -typedef unsigned int uint; -typedef unsigned long ulong; - -typedef jack_default_audio_sample_t Sample; -typedef jack_nframes_t SampleCount; -typedef jack_nframes_t SampleRate; -typedef jack_nframes_t FrameTime; - -#endif // TYPES_HPP diff --git a/src/libs/engine/util.hpp b/src/libs/engine/util.hpp deleted file mode 100644 index 8f97beb3..00000000 --- a/src/libs/engine/util.hpp +++ /dev/null @@ -1,78 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard <http://drobilla.net> - * - * 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 UTIL_HPP -#define UTIL_HPP - -#include CONFIG_H_PATH -#include <iostream> -#include <cstdlib> - -#include <fenv.h> -#ifdef __SSE__ -#include <xmmintrin.h> -#endif - -#ifdef USE_ASSEMBLY -# if SIZEOF_VOID_P==8 -# define cpuid(a,b,c,d,n) asm("xchgq %%rbx, %1; cpuid; xchgq %%rbx, %1": "=a" (a), "=r" (b), "=c" (c), "=d" (d) : "a" (n)); -# else -# define cpuid(a,b,c,d,n) asm("xchgl %%ebx, %1; cpuid; xchgl %%ebx, %1": "=a" (a), "=r" (b), "=c" (c), "=d" (d) : "a" (n)); -# endif -#endif - -namespace Ingen { - -/** Set flags to disable denormal processing. - */ -inline void -set_denormal_flags() -{ -#ifdef USE_ASSEMBLY -#ifdef __SSE__ - unsigned long a, b, c, d0, d1; - int stepping, model, family, extfamily; - - cpuid(a,b,c,d1,1); - if (d1 & 1<<25) { /* It has SSE support */ - _MM_SET_FLUSH_ZERO_MODE(_MM_FLUSH_ZERO_ON); - family = (a >> 8) & 0xf; - extfamily = (a >> 20) & 0xff; - model = (a >> 4) & 0xf; - stepping = a & 0xf; - cpuid(a,b,c,d0,0); - if (b == 0x756e6547) { /* It's an Intel */ - if (family == 15 && extfamily == 0 && model == 0 && stepping < 7) { - return; - } - } - if (d1 & 1<<26) { /* bit 26, SSE2 support */ - _mm_setcsr(_mm_getcsr() | 0x8040); // set DAZ and FZ bits of MXCSR - //cerr << "Set SSE denormal fix flag." << endl; - } - } else { - std::cerr << "This code has been built with SSE support, but your processor does" - << " not support the SSE instruction set." << std::endl << "Exiting." << std::endl; - exit(EXIT_FAILURE); - } -#endif -#endif -} - -} // namespace Ingen - -#endif // UTIL_HPP diff --git a/src/libs/engine/wscript b/src/libs/engine/wscript deleted file mode 100644 index 1ad135d3..00000000 --- a/src/libs/engine/wscript +++ /dev/null @@ -1,73 +0,0 @@ -#!/usr/bin/env python -import Params - -def build(bld): - obj = bld.create_obj('cpp', 'shlib') - obj.source = ''' - AudioBuffer.cpp - Buffer.cpp - ClientBroadcaster.cpp - ConnectionImpl.cpp - DuplexPort.cpp - Engine.cpp - EngineStore.cpp - Event.cpp - EventBuffer.cpp - EventSink.cpp - InputPort.cpp - InternalPlugin.cpp - JackAudioDriver.cpp - JackMidiDriver.cpp - LADSPAPlugin.cpp - LV2Info.cpp - LV2Plugin.cpp - MessageContext.cpp - MidiControlNode.cpp - MidiNoteNode.cpp - MidiTriggerNode.cpp - NodeBase.cpp - NodeFactory.cpp - OSCClientSender.cpp - OSCEngineReceiver.cpp - ObjectSender.cpp - OutputPort.cpp - PluginImpl.cpp - PortImpl.cpp - PostProcessor.cpp - ProcessSlave.cpp - QueuedEngineInterface.cpp - QueuedEvent.cpp - QueuedEventSource.cpp - TransportNode.cpp - engine.cpp - events/AllNotesOffEvent.cpp - events/ConnectionEvent.cpp - events/CreateNodeEvent.cpp - events/CreatePortEvent.cpp - events/DeactivateEvent.cpp - events/DestroyEvent.cpp - events/DisconnectAllEvent.cpp - events/DisconnectionEvent.cpp - events/LoadPluginsEvent.cpp - events/MidiLearnEvent.cpp - events/NoteEvent.cpp - events/RegisterClientEvent.cpp - events/RenameEvent.cpp - events/RequestAllObjectsEvent.cpp - events/RequestMetadataEvent.cpp - events/RequestObjectEvent.cpp - events/RequestPluginEvent.cpp - events/RequestPluginsEvent.cpp - events/RequestPortValueEvent.cpp - events/SendPortActivityEvent.cpp - events/SendPortValueEvent.cpp - events/SetMetadataEvent.cpp - events/SetPortValueEvent.cpp - events/UnregisterClientEvent.cpp - ''' - obj.includes = ['..', '../../common', '../..', './events'] - obj.name = 'libingen_engine' - obj.target = 'ingen_engine' - obj.uselib = 'GLIBMM GTHREAD SLV2 JACK LIBLO RAUL REDLANDMM SOUP' - obj.vnum = '0.0.0' - |