From 36f1e2ea3d2c7d20d8fa267a3a66438044e99e8e Mon Sep 17 00:00:00 2001 From: David Robillard Date: Sun, 18 Jun 2006 19:26:53 +0000 Subject: Reworked use of Plugin class in engine slightly (more RAII-ey) git-svn-id: http://svn.drobilla.net/lad/grauph@56 a436a847-0d15-0410-975c-d299462d15a1 --- src/libs/engine/DSSINode.cpp | 338 ++++++++++++++++++++++++++ src/libs/engine/DSSINode.h | 109 +++++++++ src/libs/engine/DSSIPlugin.cpp | 338 -------------------------- src/libs/engine/DSSIPlugin.h | 109 --------- src/libs/engine/InternalNode.h | 5 +- src/libs/engine/LADSPANode.cpp | 269 ++++++++++++++++++++ src/libs/engine/LADSPANode.h | 65 +++++ src/libs/engine/LADSPAPlugin.cpp | 269 -------------------- src/libs/engine/LADSPAPlugin.h | 67 ----- src/libs/engine/LV2Node.cpp | 263 ++++++++++++++++++++ src/libs/engine/LV2Node.h | 69 ++++++ src/libs/engine/LV2Plugin.cpp | 263 -------------------- src/libs/engine/LV2Plugin.h | 74 ------ src/libs/engine/Makefile.am | 12 +- src/libs/engine/MidiControlNode.cpp | 6 +- src/libs/engine/MidiNoteNode.cpp | 6 +- src/libs/engine/MidiTriggerNode.cpp | 4 +- src/libs/engine/Node.h | 1 - src/libs/engine/NodeBase.cpp | 18 +- src/libs/engine/NodeBase.h | 10 +- src/libs/engine/NodeFactory.cpp | 23 +- src/libs/engine/NodeFactory.h | 2 +- src/libs/engine/Patch.cpp | 18 +- src/libs/engine/Patch.h | 8 +- src/libs/engine/Plugin.h | 8 +- src/libs/engine/TransportNode.cpp | 4 +- src/libs/engine/events/DSSIConfigureEvent.cpp | 2 +- src/libs/engine/events/DSSIConfigureEvent.h | 10 +- src/libs/engine/events/DSSIControlEvent.cpp | 2 +- src/libs/engine/events/DSSIControlEvent.h | 10 +- src/libs/engine/events/DSSIProgramEvent.cpp | 2 +- src/libs/engine/events/DSSIProgramEvent.h | 10 +- src/libs/engine/events/DSSIUpdateEvent.cpp | 4 +- src/libs/engine/events/DSSIUpdateEvent.h | 8 +- 34 files changed, 1186 insertions(+), 1220 deletions(-) create mode 100644 src/libs/engine/DSSINode.cpp create mode 100644 src/libs/engine/DSSINode.h delete mode 100644 src/libs/engine/DSSIPlugin.cpp delete mode 100644 src/libs/engine/DSSIPlugin.h create mode 100644 src/libs/engine/LADSPANode.cpp create mode 100644 src/libs/engine/LADSPANode.h delete mode 100644 src/libs/engine/LADSPAPlugin.cpp delete mode 100644 src/libs/engine/LADSPAPlugin.h create mode 100644 src/libs/engine/LV2Node.cpp create mode 100644 src/libs/engine/LV2Node.h delete mode 100644 src/libs/engine/LV2Plugin.cpp delete mode 100644 src/libs/engine/LV2Plugin.h diff --git a/src/libs/engine/DSSINode.cpp b/src/libs/engine/DSSINode.cpp new file mode 100644 index 00000000..2eb72361 --- /dev/null +++ b/src/libs/engine/DSSINode.cpp @@ -0,0 +1,338 @@ +/* This file is part of Om. Copyright (C) 2006 Dave Robillard. + * + * Om 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. + * + * Om 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., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include "DSSINode.h" +#include +#include +#include "Om.h" +#include "OmApp.h" +#include "ClientBroadcaster.h" +#include "interface/ClientInterface.h" +#include "InputPort.h" + +using namespace std; + +namespace Om { + + +DSSINode::DSSINode(const Plugin* plugin, const string& name, size_t poly, Patch* parent, DSSI_Descriptor* descriptor, samplerate srate, size_t buffer_size) +: LADSPANode(plugin, name, 1, parent, descriptor->LADSPA_Plugin, srate, buffer_size), + _dssi_descriptor(descriptor), + _ui_addr(NULL), + _bank(-1), + _program(-1), + _midi_in_port(NULL), + _alsa_events(new snd_seq_event_t[_buffer_size]), + _alsa_encoder(NULL) +{ + snd_midi_event_new(3, &_alsa_encoder); +} + + +DSSINode::~DSSINode() +{ + if (_ui_addr != NULL) + lo_address_free(_ui_addr); + + snd_midi_event_free(_alsa_encoder); + delete [] _alsa_events; +} + + +/** This needs to be overridden here because LADSPANode::instantiate() + * allocates the port array, and we want to add the MIDI input port to that + * array. + */ +bool +DSSINode::instantiate() +{ + assert(!_ports); + + if (has_midi_input()) { + _ports = new Array(_descriptor->PortCount + 1); + _midi_in_port = new InputPort(this, "MIDI In", _ports->size()-1, 1, DataType::MIDI, _buffer_size); + _ports->at(_ports->size()-1) = _midi_in_port; + } + + // LADSPANode::instantiate checks if _ports is already allocated + if (!LADSPANode::instantiate()) { + delete _ports; + return false; + } + + return true; +} + + +void +DSSINode::activate() +{ + LADSPANode::activate(); + + update_programs(false); + set_default_program(); + + snd_midi_event_reset_encode(_alsa_encoder); +} + + +void +DSSINode::set_ui_url(const string& url) +{ + if (_ui_addr != NULL) + lo_address_free(_ui_addr); + + _ui_url = url; + _ui_addr = lo_address_new_from_url(url.c_str()); + char* base_path = lo_url_get_path(url.c_str()); + _ui_base_path = base_path; + free(base_path); + cerr << "Set UI base path to " << _ui_base_path << endl; +} + + +void +DSSINode::set_control(size_t port_num, sample val) +{ + assert(port_num < _descriptor->PortCount); + ((PortBase*)_ports->at(port_num))->set_value(val, 0); +} + + +void +DSSINode::configure(const string& key, const string& val) +{ + _dssi_descriptor->configure(_instances[0], key.c_str(), val.c_str()); + _configures[key] = val; + update_programs(true); +} + + +void +DSSINode::program(int bank, int program) +{ + if (_dssi_descriptor->select_program) + _dssi_descriptor->select_program(_instances[0], bank, program); + + _bank = bank; + _program = program; +} + + +void +DSSINode::convert_events() +{ + assert(has_midi_input()); + assert(_midi_in_port != NULL); + + Buffer& buffer = *_midi_in_port->buffer(0); + _encoded_events = 0; + + for (size_t i = 0; i < buffer.filled_size(); ++i) { + snd_midi_event_encode(_alsa_encoder, buffer.value_at(i).buffer, + buffer.value_at(i).size, + &_alsa_events[_encoded_events]); + _alsa_events[_encoded_events].time.tick = buffer.value_at(i).time; + if (_alsa_events[_encoded_events].type != SND_SEQ_EVENT_NONE) + ++_encoded_events; + } +} + + +bool +DSSINode::has_midi_input() const +{ + return (_dssi_descriptor->run_synth || _dssi_descriptor->run_multiple_synths); +} + + +void +DSSINode::run(size_t nframes) +{ + NodeBase::run(nframes); + + if (_dssi_descriptor->run_synth) { + convert_events(); + _dssi_descriptor->run_synth(_instances[0], nframes, + _alsa_events, _encoded_events); + } else if (_dssi_descriptor->run_multiple_synths) { + convert_events(); + // I hate this stupid function + snd_seq_event_t* events[1] = { _alsa_events }; + long unsigned events_sizes[1] = { _encoded_events }; + _dssi_descriptor->run_multiple_synths(1, _instances, nframes, + events, events_sizes); + } else { + LADSPANode::run(nframes); + } +} + + +void +DSSINode::send_control(int port_num, float value) +{ + string path = _ui_base_path + "/control"; + lo_send(_ui_addr, path.c_str(), "if", port_num, value); +} + + +void +DSSINode::send_program(int bank, int value) +{ + string path = _ui_base_path + "/program"; + lo_send(_ui_addr, path.c_str(), "ii", bank, value); +} + + +void +DSSINode::send_configure(const string& key, const string& val) +{ + string path = _ui_base_path + "/configure"; + lo_send(_ui_addr, path.c_str(), "ss", key.c_str(), val.c_str()); +} + + +void +DSSINode::send_show() +{ + string path = _ui_base_path + "/show"; + lo_send(_ui_addr, path.c_str(), NULL); +} + + +void +DSSINode::send_hide() +{ + string path = _ui_base_path + "/hide"; + lo_send(_ui_addr, path.c_str(), NULL); +} + + +void +DSSINode::send_quit() +{ + string path = _ui_base_path + "/quit"; + lo_send(_ui_addr, path.c_str(), NULL); +} + + +void +DSSINode::send_update() +{ + // send "configure"s + for (map::iterator i = _configures.begin(); i != _configures.end(); ++i) + send_configure((*i).first, (*i).second); + + // send "program" + send_program(_bank, _program); + + // send "control"s + for (size_t i=0; i < _ports->size(); ++i) + if (_ports->at(i)->type() == DataType::FLOAT && _ports->at(i)->buffer_size() == 1) + send_control(_ports->at(i)->num(), ((PortBase*)_ports->at(i))->buffer(0)->value_at(0)); + + // send "show" FIXME: not to spec + send_show(); +} + + +bool +DSSINode::update_programs(bool send_events) +{ + // remember all old banks and programs + set > to_be_deleted; + map::const_iterator iter; + Bank::const_iterator iter2; + for (iter = _banks.begin(); iter != _banks.end(); ++iter) { + for (iter2 = iter->second.begin(); iter2 != iter->second.end(); ++iter2) { + to_be_deleted.insert(make_pair(iter->first, iter2->first)); + } + } + + // iterate over all programs + if (_dssi_descriptor->get_program) { + for (int i = 0; true; ++i) { + const DSSI_Program_Descriptor* descriptor = + _dssi_descriptor->get_program(_instances[0], i); + if (!descriptor) + break; + + iter = _banks.find(descriptor->Bank); + if (iter == _banks.end() || + iter->second.find(descriptor->Program) == iter->second.end() || + iter->second.find(descriptor->Program)->second != descriptor->Name) { + _banks[descriptor->Bank][descriptor->Program] = descriptor->Name; + if (send_events) { + om->client_broadcaster()->send_program_add(path(), descriptor->Bank, + descriptor->Program, + descriptor->Name); + } + to_be_deleted.erase(make_pair(descriptor->Bank, descriptor->Program)); + } + } + } + + // remove programs that has disappeared from the plugin + set >::const_iterator set_iter; + for (set_iter = to_be_deleted.begin(); + set_iter != to_be_deleted.end(); ++set_iter) { + _banks[set_iter->first].erase(set_iter->second); + if (send_events) + om->client_broadcaster()->send_program_remove(path(), set_iter->first, set_iter->second); + if (_banks[set_iter->first].size() == 0) + _banks.erase(set_iter->first); + } + + return true; +} + + +void +DSSINode::set_default_program() +{ + map::const_iterator iter = _banks.begin(); + if (iter != _banks.end()) { + Bank::const_iterator iter2 = iter->second.begin(); + if (iter2 != iter->second.end()) + program(iter->first, iter2->first); + } +} + + +const map& +DSSINode::get_programs() const +{ + return _banks; +} + + +/* +void +DSSINode::send_creation_messages(ClientInterface* client) const +{ + LADSPANode::send_creation_messages(client); + + for (map::const_iterator i = get_programs().begin(); + i != get_programs().end(); ++i) { + + for (Bank::const_iterator j = i->second.begin(); j != i->second.end(); ++j) + client->program_add(path(), + i->first, j->first, j->second); + } +} +*/ + +} // namespace Om diff --git a/src/libs/engine/DSSINode.h b/src/libs/engine/DSSINode.h new file mode 100644 index 00000000..deef0b8b --- /dev/null +++ b/src/libs/engine/DSSINode.h @@ -0,0 +1,109 @@ +/* This file is part of Om. Copyright (C) 2006 Dave Robillard. + * + * Om 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. + * + * Om 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., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef DSSINODE_H +#define DSSINODE_H + +#include +#include +#include +#include "LADSPANode.h" + +namespace Om { + +class MidiMessage; +template class InputPort; +namespace Shared { + class ClientInterface; +} using Shared::ClientInterface; + + +/** An instance of a DSSI plugin. + */ +class DSSINode : public LADSPANode +{ +public: + + typedef map Bank; + + DSSINode(const Plugin* plugin, const string& name, size_t poly, Patch* parent, DSSI_Descriptor* descriptor, samplerate srate, size_t buffer_size); + ~DSSINode(); + + bool instantiate(); + + void activate(); + + void set_ui_url(const string& url); + void send_update(); + + void set_control(size_t port_num, sample val); + void configure(const string& key, const string& val); + void program(int bank, int program); + + void run(size_t nframes); + + bool update_programs(bool send_events); + void set_default_program(); + const map& get_programs() const; + + //void send_creation_messages(ClientInterface* client) const; + + const Plugin* plugin() const { return _plugin; } + void plugin(const Plugin* const pi) { _plugin = pi; } + +private: + // Prevent copies (undefined) + DSSINode(const DSSINode& copy); + DSSINode& operator=(const DSSINode& copy); + + bool has_midi_input() const; + + // DSSI GUI messages + void send_control(int port_num, float value); + void send_program(int bank, int value); + void send_configure(const string& key, const string& val); + void send_show(); + void send_hide(); + void send_quit(); + + // Conversion to ALSA MIDI events + void convert_events(); + + + DSSI_Descriptor* _dssi_descriptor; + + string _ui_url; + string _ui_base_path; + lo_address _ui_addr; + + // Current values + int _bank; + int _program; + map _configures; + map _banks; + + InputPort* _midi_in_port; + snd_seq_event_t* _alsa_events; + unsigned long _encoded_events; + snd_midi_event_t* _alsa_encoder; +}; + + +} // namespace Om + + +#endif // DSSINODE_H + diff --git a/src/libs/engine/DSSIPlugin.cpp b/src/libs/engine/DSSIPlugin.cpp deleted file mode 100644 index 8876f797..00000000 --- a/src/libs/engine/DSSIPlugin.cpp +++ /dev/null @@ -1,338 +0,0 @@ -/* This file is part of Om. Copyright (C) 2006 Dave Robillard. - * - * Om 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. - * - * Om 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., - * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#include "DSSIPlugin.h" -#include -#include -#include "Om.h" -#include "OmApp.h" -#include "ClientBroadcaster.h" -#include "interface/ClientInterface.h" -#include "InputPort.h" - -using namespace std; - -namespace Om { - - -DSSIPlugin::DSSIPlugin(const string& name, size_t poly, Patch* parent, DSSI_Descriptor* descriptor, samplerate srate, size_t buffer_size) -: LADSPAPlugin(name, 1, parent, descriptor->LADSPA_Plugin, srate, buffer_size), - _dssi_descriptor(descriptor), - _ui_addr(NULL), - _bank(-1), - _program(-1), - _midi_in_port(NULL), - _alsa_events(new snd_seq_event_t[_buffer_size]), - _alsa_encoder(NULL) -{ - snd_midi_event_new(3, &_alsa_encoder); -} - - -DSSIPlugin::~DSSIPlugin() -{ - if (_ui_addr != NULL) - lo_address_free(_ui_addr); - - snd_midi_event_free(_alsa_encoder); - delete [] _alsa_events; -} - - -/** This needs to be overridden here because LADSPAPlugin::instantiate() - * allocates the port array, and we want to add the MIDI input port to that - * array. - */ -bool -DSSIPlugin::instantiate() -{ - assert(!_ports); - - if (has_midi_input()) { - _ports = new Array(_descriptor->PortCount + 1); - _midi_in_port = new InputPort(this, "MIDI In", _ports->size()-1, 1, DataType::MIDI, _buffer_size); - _ports->at(_ports->size()-1) = _midi_in_port; - } - - // LADSPAPlugin::instantiate checks if _ports is already allocated - if (!LADSPAPlugin::instantiate()) { - delete _ports; - return false; - } - - return true; -} - - -void -DSSIPlugin::activate() -{ - LADSPAPlugin::activate(); - - update_programs(false); - set_default_program(); - - snd_midi_event_reset_encode(_alsa_encoder); -} - - -void -DSSIPlugin::set_ui_url(const string& url) -{ - if (_ui_addr != NULL) - lo_address_free(_ui_addr); - - _ui_url = url; - _ui_addr = lo_address_new_from_url(url.c_str()); - char* base_path = lo_url_get_path(url.c_str()); - _ui_base_path = base_path; - free(base_path); - cerr << "Set UI base path to " << _ui_base_path << endl; -} - - -void -DSSIPlugin::set_control(size_t port_num, sample val) -{ - assert(port_num < _descriptor->PortCount); - ((PortBase*)_ports->at(port_num))->set_value(val, 0); -} - - -void -DSSIPlugin::configure(const string& key, const string& val) -{ - _dssi_descriptor->configure(_instances[0], key.c_str(), val.c_str()); - _configures[key] = val; - update_programs(true); -} - - -void -DSSIPlugin::program(int bank, int program) -{ - if (_dssi_descriptor->select_program) - _dssi_descriptor->select_program(_instances[0], bank, program); - - _bank = bank; - _program = program; -} - - -void -DSSIPlugin::convert_events() -{ - assert(has_midi_input()); - assert(_midi_in_port != NULL); - - Buffer& buffer = *_midi_in_port->buffer(0); - _encoded_events = 0; - - for (size_t i = 0; i < buffer.filled_size(); ++i) { - snd_midi_event_encode(_alsa_encoder, buffer.value_at(i).buffer, - buffer.value_at(i).size, - &_alsa_events[_encoded_events]); - _alsa_events[_encoded_events].time.tick = buffer.value_at(i).time; - if (_alsa_events[_encoded_events].type != SND_SEQ_EVENT_NONE) - ++_encoded_events; - } -} - - -bool -DSSIPlugin::has_midi_input() const -{ - return (_dssi_descriptor->run_synth || _dssi_descriptor->run_multiple_synths); -} - - -void -DSSIPlugin::run(size_t nframes) -{ - NodeBase::run(nframes); - - if (_dssi_descriptor->run_synth) { - convert_events(); - _dssi_descriptor->run_synth(_instances[0], nframes, - _alsa_events, _encoded_events); - } else if (_dssi_descriptor->run_multiple_synths) { - convert_events(); - // I hate this stupid function - snd_seq_event_t* events[1] = { _alsa_events }; - long unsigned events_sizes[1] = { _encoded_events }; - _dssi_descriptor->run_multiple_synths(1, _instances, nframes, - events, events_sizes); - } else { - LADSPAPlugin::run(nframes); - } -} - - -void -DSSIPlugin::send_control(int port_num, float value) -{ - string path = _ui_base_path + "/control"; - lo_send(_ui_addr, path.c_str(), "if", port_num, value); -} - - -void -DSSIPlugin::send_program(int bank, int value) -{ - string path = _ui_base_path + "/program"; - lo_send(_ui_addr, path.c_str(), "ii", bank, value); -} - - -void -DSSIPlugin::send_configure(const string& key, const string& val) -{ - string path = _ui_base_path + "/configure"; - lo_send(_ui_addr, path.c_str(), "ss", key.c_str(), val.c_str()); -} - - -void -DSSIPlugin::send_show() -{ - string path = _ui_base_path + "/show"; - lo_send(_ui_addr, path.c_str(), NULL); -} - - -void -DSSIPlugin::send_hide() -{ - string path = _ui_base_path + "/hide"; - lo_send(_ui_addr, path.c_str(), NULL); -} - - -void -DSSIPlugin::send_quit() -{ - string path = _ui_base_path + "/quit"; - lo_send(_ui_addr, path.c_str(), NULL); -} - - -void -DSSIPlugin::send_update() -{ - // send "configure"s - for (map::iterator i = _configures.begin(); i != _configures.end(); ++i) - send_configure((*i).first, (*i).second); - - // send "program" - send_program(_bank, _program); - - // send "control"s - for (size_t i=0; i < _ports->size(); ++i) - if (_ports->at(i)->type() == DataType::FLOAT && _ports->at(i)->buffer_size() == 1) - send_control(_ports->at(i)->num(), ((PortBase*)_ports->at(i))->buffer(0)->value_at(0)); - - // send "show" FIXME: not to spec - send_show(); -} - - -bool -DSSIPlugin::update_programs(bool send_events) -{ - // remember all old banks and programs - set > to_be_deleted; - map::const_iterator iter; - Bank::const_iterator iter2; - for (iter = _banks.begin(); iter != _banks.end(); ++iter) { - for (iter2 = iter->second.begin(); iter2 != iter->second.end(); ++iter2) { - to_be_deleted.insert(make_pair(iter->first, iter2->first)); - } - } - - // iterate over all programs - if (_dssi_descriptor->get_program) { - for (int i = 0; true; ++i) { - const DSSI_Program_Descriptor* descriptor = - _dssi_descriptor->get_program(_instances[0], i); - if (!descriptor) - break; - - iter = _banks.find(descriptor->Bank); - if (iter == _banks.end() || - iter->second.find(descriptor->Program) == iter->second.end() || - iter->second.find(descriptor->Program)->second != descriptor->Name) { - _banks[descriptor->Bank][descriptor->Program] = descriptor->Name; - if (send_events) { - om->client_broadcaster()->send_program_add(path(), descriptor->Bank, - descriptor->Program, - descriptor->Name); - } - to_be_deleted.erase(make_pair(descriptor->Bank, descriptor->Program)); - } - } - } - - // remove programs that has disappeared from the plugin - set >::const_iterator set_iter; - for (set_iter = to_be_deleted.begin(); - set_iter != to_be_deleted.end(); ++set_iter) { - _banks[set_iter->first].erase(set_iter->second); - if (send_events) - om->client_broadcaster()->send_program_remove(path(), set_iter->first, set_iter->second); - if (_banks[set_iter->first].size() == 0) - _banks.erase(set_iter->first); - } - - return true; -} - - -void -DSSIPlugin::set_default_program() -{ - map::const_iterator iter = _banks.begin(); - if (iter != _banks.end()) { - Bank::const_iterator iter2 = iter->second.begin(); - if (iter2 != iter->second.end()) - program(iter->first, iter2->first); - } -} - - -const map& -DSSIPlugin::get_programs() const -{ - return _banks; -} - - -/* -void -DSSIPlugin::send_creation_messages(ClientInterface* client) const -{ - LADSPAPlugin::send_creation_messages(client); - - for (map::const_iterator i = get_programs().begin(); - i != get_programs().end(); ++i) { - - for (Bank::const_iterator j = i->second.begin(); j != i->second.end(); ++j) - client->program_add(path(), - i->first, j->first, j->second); - } -} -*/ - -} // namespace Om diff --git a/src/libs/engine/DSSIPlugin.h b/src/libs/engine/DSSIPlugin.h deleted file mode 100644 index 30afd9d2..00000000 --- a/src/libs/engine/DSSIPlugin.h +++ /dev/null @@ -1,109 +0,0 @@ -/* This file is part of Om. Copyright (C) 2006 Dave Robillard. - * - * Om 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. - * - * Om 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., - * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#ifndef DSSIPLUGIN_H -#define DSSIPLUGIN_H - -#include -#include -#include -#include "LADSPAPlugin.h" - -namespace Om { - -class MidiMessage; -template class InputPort; -namespace Shared { - class ClientInterface; -} using Shared::ClientInterface; - - -/** An instance of a DSSI plugin. - */ -class DSSIPlugin : public LADSPAPlugin -{ -public: - - typedef map Bank; - - DSSIPlugin(const string& name, size_t poly, Patch* parent, DSSI_Descriptor* descriptor, samplerate srate, size_t buffer_size); - ~DSSIPlugin(); - - bool instantiate(); - - void activate(); - - void set_ui_url(const string& url); - void send_update(); - - void set_control(size_t port_num, sample val); - void configure(const string& key, const string& val); - void program(int bank, int program); - - void run(size_t nframes); - - bool update_programs(bool send_events); - void set_default_program(); - const map& get_programs() const; - - //void send_creation_messages(ClientInterface* client) const; - - const Plugin* plugin() const { return _plugin; } - void plugin(const Plugin* const pi) { _plugin = pi; } - -private: - // Prevent copies (undefined) - DSSIPlugin(const DSSIPlugin& copy); - DSSIPlugin& operator=(const DSSIPlugin& copy); - - bool has_midi_input() const; - - // DSSI GUI messages - void send_control(int port_num, float value); - void send_program(int bank, int value); - void send_configure(const string& key, const string& val); - void send_show(); - void send_hide(); - void send_quit(); - - // Conversion to ALSA MIDI events - void convert_events(); - - - DSSI_Descriptor* _dssi_descriptor; - - string _ui_url; - string _ui_base_path; - lo_address _ui_addr; - - // Current values - int _bank; - int _program; - map _configures; - map _banks; - - InputPort* _midi_in_port; - snd_seq_event_t* _alsa_events; - unsigned long _encoded_events; - snd_midi_event_t* _alsa_encoder; -}; - - -} // namespace Om - - -#endif // DSSIPLUGIN_H - diff --git a/src/libs/engine/InternalNode.h b/src/libs/engine/InternalNode.h index 14a4bc95..e7c35ebd 100644 --- a/src/libs/engine/InternalNode.h +++ b/src/libs/engine/InternalNode.h @@ -33,8 +33,8 @@ class Patch; class InternalNode : public NodeBase { public: - InternalNode(const string& path, size_t poly, Patch* parent, samplerate srate, size_t buffer_size) - : NodeBase(path, poly, parent, srate, buffer_size), + InternalNode(const Plugin* plugin, const string& path, size_t poly, Patch* parent, samplerate srate, size_t buffer_size) + : NodeBase(plugin, path, poly, parent, srate, buffer_size), _is_added(false) { _plugin.lib_path("/Om"); @@ -53,7 +53,6 @@ public: //{ NodeBase::send_creation_messages(client); } virtual const Plugin* plugin() const { return &_plugin; } - virtual void plugin(const Plugin* const) { exit(EXIT_FAILURE); } protected: // Disallow copies (undefined) diff --git a/src/libs/engine/LADSPANode.cpp b/src/libs/engine/LADSPANode.cpp new file mode 100644 index 00000000..0ca0aca7 --- /dev/null +++ b/src/libs/engine/LADSPANode.cpp @@ -0,0 +1,269 @@ +/* This file is part of Om. Copyright (C) 2006 Dave Robillard. + * + * Om 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. + * + * Om 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., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + + +#include "LADSPANode.h" +#include +#include +#include "float.h" +#include +#include +#include "InputPort.h" +#include "OutputPort.h" +#include "Plugin.h" + +namespace Om { + + +/** Partially construct a LADSPANode. + * + * Object is not usable until instantiate() is called with success. + * (It _will_ crash!) + */ +LADSPANode::LADSPANode(const Plugin* plugin, const string& path, size_t poly, Patch* parent, const LADSPA_Descriptor* descriptor, samplerate srate, size_t buffer_size) +: NodeBase(plugin, path, poly, parent, srate, buffer_size), + _descriptor(descriptor), + _instances(NULL) +{ + assert(_descriptor != NULL); +} + + +/** 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() +{ + // Note that a DSSI plugin might tack more on to the end of this + if (!_ports) + _ports = new Array(_descriptor->PortCount); + + _instances = new LADSPA_Handle[_poly]; + + size_t port_buffer_size = 0; + + for (size_t i=0; i < _poly; ++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; + + Port* port = NULL; + + for (size_t j=0; j < _descriptor->PortCount; ++j) { + port_name = _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] = '-'; + } + + port_path = path() + "/" + port_name; + + if (LADSPA_IS_PORT_CONTROL(_descriptor->PortDescriptors[j])) + port_buffer_size = 1; + else if (LADSPA_IS_PORT_AUDIO(_descriptor->PortDescriptors[j])) + port_buffer_size = _buffer_size; + + assert (LADSPA_IS_PORT_INPUT(_descriptor->PortDescriptors[j]) + || LADSPA_IS_PORT_OUTPUT(_descriptor->PortDescriptors[j])); + + if (LADSPA_IS_PORT_INPUT(_descriptor->PortDescriptors[j])) { + port = new InputPort(this, port_name, j, _poly, DataType::FLOAT, port_buffer_size); + _ports->at(j) = port; + } else if (LADSPA_IS_PORT_OUTPUT(_descriptor->PortDescriptors[j])) { + port = new OutputPort(this, port_name, j, _poly, DataType::FLOAT, port_buffer_size); + _ports->at(j) = port; + } + + assert(_ports->at(j) != NULL); + + /*PortInfo* pi = port->port_info(); + get_port_vals(j, pi); + */ + float default_val = 0.; // FIXME + + // Set default control val + if (port->buffer_size() == 1) + ((PortBase*)port)->set_value(default_val, 0); + else + ((PortBase*)port)->set_value(0.0f, 0); + } + + return true; +} + + +LADSPANode::~LADSPANode() +{ + for (size_t i=0; i < _poly; ++i) + _descriptor->cleanup(_instances[i]); + + delete[] _instances; +} + + +void +LADSPANode::activate() +{ + NodeBase::activate(); + + PortBase* port = NULL; + + for (size_t i=0; i < _poly; ++i) { + for (unsigned long j=0; j < _descriptor->PortCount; ++j) { + port = static_cast*>(_ports->at(j)); + set_port_buffer(i, j, ((PortBase*)_ports->at(j))->buffer(i)->data()); + 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 (size_t i=0; i < _poly; ++i) + if (_descriptor->deactivate != NULL) + _descriptor->deactivate(_instances[i]); +} + + +void +LADSPANode::run(size_t nframes) +{ + NodeBase::run(nframes); // mixes down input ports + for (size_t i=0; i < _poly; ++i) + _descriptor->run(_instances[i], nframes); +} + + +void +LADSPANode::set_port_buffer(size_t voice, size_t port_num, void* buf) +{ + assert(voice < _poly); + + // Could be a MIDI port after this + if (port_num < _descriptor->PortCount) { + _descriptor->connect_port(_instances[voice], port_num, (sample*)buf); + } +} + +#if 0 +// Based on code stolen from jack-rack +void +LADSPANode::get_port_vals(ulong port_index, PortInfo* info) +{ + LADSPA_Data upper = 0.0f; + LADSPA_Data lower = 0.0f; + LADSPA_Data normal = 0.0f; + 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 < 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)) { + if (LADSPA_IS_HINT_LOGARITHMIC(hint_descriptor)) { + normal = exp(log(lower) * 0.75 + log(upper) * 0.25); + } else { + normal = lower * 0.75 + upper * 0.25; + } + } else if (LADSPA_IS_HINT_DEFAULT_MIDDLE(hint_descriptor)) { + if (LADSPA_IS_HINT_LOGARITHMIC(hint_descriptor)) { + normal = exp(log(lower) * 0.5 + log(upper) * 0.5); + } else { + normal = lower * 0.5 + upper * 0.5; + } + } else if (LADSPA_IS_HINT_DEFAULT_HIGH(hint_descriptor)) { + if (LADSPA_IS_HINT_LOGARITHMIC(hint_descriptor)) { + normal = exp(log(lower) * 0.25 + log(upper) * 0.75); + } else { + normal = lower * 0.25 + upper * 0.75; + } + } else if (LADSPA_IS_HINT_DEFAULT_MAXIMUM(hint_descriptor)) { + normal = upper; + } 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)) { + normal = lower; + } else if (LADSPA_IS_HINT_BOUNDED_ABOVE(hint_descriptor)) { + normal = upper; + } + } + + info->min_val(lower); + info->default_val(normal); + info->max_val(upper); +} +#endif + +} // namespace Om + diff --git a/src/libs/engine/LADSPANode.h b/src/libs/engine/LADSPANode.h new file mode 100644 index 00000000..c8b498c9 --- /dev/null +++ b/src/libs/engine/LADSPANode.h @@ -0,0 +1,65 @@ +/* This file is part of Om. Copyright (C) 2006 Dave Robillard. + * + * Om 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. + * + * Om 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., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef LADSPANODE_H +#define LADSPANODE_H + +#include +#include +#include "util/types.h" +#include "NodeBase.h" +#include "Plugin.h" + +namespace Om { + + +/** An instance of a LADSPA plugin. + * + * \ingroup engine + */ +class LADSPANode : public NodeBase +{ +public: + LADSPANode(const Plugin* plugin, const string& name, size_t poly, Patch* parent, const LADSPA_Descriptor* descriptor, samplerate srate, size_t buffer_size); + virtual ~LADSPANode(); + + virtual bool instantiate(); + + void activate(); + void deactivate(); + + void run(size_t nframes); + + void set_port_buffer(size_t voice, size_t port_num, void* buf); + + const Plugin* plugin() const { return _plugin; } + void plugin(const Plugin* const pi) { _plugin = pi; } + +protected: + // Prevent copies (undefined) + LADSPANode(const LADSPANode& copy); + LADSPANode& operator=(const LADSPANode&); + + //void get_port_vals(ulong port_index, PortInfo* info); + + const LADSPA_Descriptor* _descriptor; + LADSPA_Handle* _instances; +}; + + +} // namespace Om + +#endif // LADSPANODE_H diff --git a/src/libs/engine/LADSPAPlugin.cpp b/src/libs/engine/LADSPAPlugin.cpp deleted file mode 100644 index 37d66805..00000000 --- a/src/libs/engine/LADSPAPlugin.cpp +++ /dev/null @@ -1,269 +0,0 @@ -/* This file is part of Om. Copyright (C) 2006 Dave Robillard. - * - * Om 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. - * - * Om 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., - * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - - -#include "LADSPAPlugin.h" -#include -#include -#include "float.h" -#include -#include -#include "InputPort.h" -#include "OutputPort.h" -#include "Plugin.h" - -namespace Om { - - -/** Partially construct a LADSPAPlugin. - * - * Object is not usable until instantiate() is called with success. - * (It _will_ crash!) - */ -LADSPAPlugin::LADSPAPlugin(const string& path, size_t poly, Patch* parent, const LADSPA_Descriptor* descriptor, samplerate srate, size_t buffer_size) -: NodeBase(path, poly, parent, srate, buffer_size), - _descriptor(descriptor), - _instances(NULL) -{ - assert(_descriptor != NULL); -} - - -/** 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 -LADSPAPlugin::instantiate() -{ - // Note that a DSSI plugin might tack more on to the end of this - if (!_ports) - _ports = new Array(_descriptor->PortCount); - - _instances = new LADSPA_Handle[_poly]; - - size_t port_buffer_size = 0; - - for (size_t i=0; i < _poly; ++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; - - Port* port = NULL; - - for (size_t j=0; j < _descriptor->PortCount; ++j) { - port_name = _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] = '-'; - } - - port_path = path() + "/" + port_name; - - if (LADSPA_IS_PORT_CONTROL(_descriptor->PortDescriptors[j])) - port_buffer_size = 1; - else if (LADSPA_IS_PORT_AUDIO(_descriptor->PortDescriptors[j])) - port_buffer_size = _buffer_size; - - assert (LADSPA_IS_PORT_INPUT(_descriptor->PortDescriptors[j]) - || LADSPA_IS_PORT_OUTPUT(_descriptor->PortDescriptors[j])); - - if (LADSPA_IS_PORT_INPUT(_descriptor->PortDescriptors[j])) { - port = new InputPort(this, port_name, j, _poly, DataType::FLOAT, port_buffer_size); - _ports->at(j) = port; - } else if (LADSPA_IS_PORT_OUTPUT(_descriptor->PortDescriptors[j])) { - port = new OutputPort(this, port_name, j, _poly, DataType::FLOAT, port_buffer_size); - _ports->at(j) = port; - } - - assert(_ports->at(j) != NULL); - - /*PortInfo* pi = port->port_info(); - get_port_vals(j, pi); - */ - float default_val = 0.; // FIXME - - // Set default control val - if (port->buffer_size() == 1) - ((PortBase*)port)->set_value(default_val, 0); - else - ((PortBase*)port)->set_value(0.0f, 0); - } - - return true; -} - - -LADSPAPlugin::~LADSPAPlugin() -{ - for (size_t i=0; i < _poly; ++i) - _descriptor->cleanup(_instances[i]); - - delete[] _instances; -} - - -void -LADSPAPlugin::activate() -{ - NodeBase::activate(); - - PortBase* port = NULL; - - for (size_t i=0; i < _poly; ++i) { - for (unsigned long j=0; j < _descriptor->PortCount; ++j) { - port = static_cast*>(_ports->at(j)); - set_port_buffer(i, j, ((PortBase*)_ports->at(j))->buffer(i)->data()); - 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 -LADSPAPlugin::deactivate() -{ - NodeBase::deactivate(); - - for (size_t i=0; i < _poly; ++i) - if (_descriptor->deactivate != NULL) - _descriptor->deactivate(_instances[i]); -} - - -void -LADSPAPlugin::run(size_t nframes) -{ - NodeBase::run(nframes); // mixes down input ports - for (size_t i=0; i < _poly; ++i) - _descriptor->run(_instances[i], nframes); -} - - -void -LADSPAPlugin::set_port_buffer(size_t voice, size_t port_num, void* buf) -{ - assert(voice < _poly); - - // Could be a MIDI port after this - if (port_num < _descriptor->PortCount) { - _descriptor->connect_port(_instances[voice], port_num, (sample*)buf); - } -} - -#if 0 -// Based on code stolen from jack-rack -void -LADSPAPlugin::get_port_vals(ulong port_index, PortInfo* info) -{ - LADSPA_Data upper = 0.0f; - LADSPA_Data lower = 0.0f; - LADSPA_Data normal = 0.0f; - 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 < 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)) { - if (LADSPA_IS_HINT_LOGARITHMIC(hint_descriptor)) { - normal = exp(log(lower) * 0.75 + log(upper) * 0.25); - } else { - normal = lower * 0.75 + upper * 0.25; - } - } else if (LADSPA_IS_HINT_DEFAULT_MIDDLE(hint_descriptor)) { - if (LADSPA_IS_HINT_LOGARITHMIC(hint_descriptor)) { - normal = exp(log(lower) * 0.5 + log(upper) * 0.5); - } else { - normal = lower * 0.5 + upper * 0.5; - } - } else if (LADSPA_IS_HINT_DEFAULT_HIGH(hint_descriptor)) { - if (LADSPA_IS_HINT_LOGARITHMIC(hint_descriptor)) { - normal = exp(log(lower) * 0.25 + log(upper) * 0.75); - } else { - normal = lower * 0.25 + upper * 0.75; - } - } else if (LADSPA_IS_HINT_DEFAULT_MAXIMUM(hint_descriptor)) { - normal = upper; - } 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)) { - normal = lower; - } else if (LADSPA_IS_HINT_BOUNDED_ABOVE(hint_descriptor)) { - normal = upper; - } - } - - info->min_val(lower); - info->default_val(normal); - info->max_val(upper); -} -#endif - -} // namespace Om - diff --git a/src/libs/engine/LADSPAPlugin.h b/src/libs/engine/LADSPAPlugin.h deleted file mode 100644 index e91b6a36..00000000 --- a/src/libs/engine/LADSPAPlugin.h +++ /dev/null @@ -1,67 +0,0 @@ -/* This file is part of Om. Copyright (C) 2006 Dave Robillard. - * - * Om 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. - * - * Om 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., - * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#ifndef LADSPAPLUGIN_H -#define LADSPAPLUGIN_H - -#include -#include -#include "util/types.h" -#include "NodeBase.h" -#include "Plugin.h" - -namespace Om { - - -/** An instance of a LADSPA plugin. - * - * \ingroup engine - */ -class LADSPAPlugin : public NodeBase -{ -public: - LADSPAPlugin(const string& name, size_t poly, Patch* parent, const LADSPA_Descriptor* descriptor, samplerate srate, size_t buffer_size); - virtual ~LADSPAPlugin(); - - virtual bool instantiate(); - - void activate(); - void deactivate(); - - void run(size_t nframes); - - void set_port_buffer(size_t voice, size_t port_num, void* buf); - - const Plugin* plugin() const { return _plugin; } - void plugin(const Plugin* const pi) { _plugin = pi; } - -protected: - // Prevent copies (undefined) - LADSPAPlugin(const LADSPAPlugin& copy); - LADSPAPlugin& operator=(const LADSPAPlugin&); - - //void get_port_vals(ulong port_index, PortInfo* info); - - const LADSPA_Descriptor* _descriptor; - LADSPA_Handle* _instances; - - const Plugin* _plugin; -}; - - -} // namespace Om - -#endif // LADSPAPLUGIN_H diff --git a/src/libs/engine/LV2Node.cpp b/src/libs/engine/LV2Node.cpp new file mode 100644 index 00000000..34bbe61e --- /dev/null +++ b/src/libs/engine/LV2Node.cpp @@ -0,0 +1,263 @@ +/* This file is part of Om. Copyright (C) 2006 Dave Robillard. + * + * Om 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. + * + * Om 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., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include "LV2Node.h" +#include +#include +#include "float.h" +#include +#include +#include "InputPort.h" +#include "OutputPort.h" +#include "Plugin.h" + +namespace Om { + + +/** Partially construct a LV2Node. + * + * Object is not usable until instantiate() is called with success. + * (It _will_ crash!) + */ +LV2Node::LV2Node(const Plugin* plugin, + const string& name, + size_t poly, + Patch* parent, + samplerate srate, + size_t buffer_size) +: NodeBase(plugin, name, poly, parent, srate, buffer_size), + _lv2_plugin(plugin->slv2_plugin()), + _instances(NULL) +{ + assert(_lv2_plugin); +} + + +/** 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() +{ + size_t num_ports = slv2_plugin_get_num_ports(_lv2_plugin); + assert(num_ports > 0); + _ports->alloc(num_ports); + + _instances = new SLV2Instance*[_poly]; + + size_t port_buffer_size = 0; + + for (size_t i=0; i < _poly; ++i) { + _instances[i] = slv2_plugin_instantiate(_lv2_plugin, _srate, NULL); + if (_instances[i] == NULL) { + cerr << "Failed to instantiate plugin!" << endl; + return false; + } + } + + string port_name; + string port_path; + + Port* port = NULL; + + for (size_t j=0; j < num_ports; ++j) { + // LV2 shortnames are guaranteed to be unique, valid C identifiers + port_name = (char*)slv2_port_get_symbol(_lv2_plugin, j); + + assert(port_name.find("/") == string::npos); + + port_path = path() + "/" + port_name; + + // Assumes there is only the 4 classes + + SLV2PortClass port_class = slv2_port_get_class(_lv2_plugin, j); + const bool is_control = (port_class == SLV2_CONTROL_RATE_INPUT + || port_class == SLV2_CONTROL_RATE_OUTPUT); + const bool is_input = (port_class == SLV2_CONTROL_RATE_INPUT + || port_class == SLV2_AUDIO_RATE_INPUT); + + if (is_control) + port_buffer_size = 1; + else + port_buffer_size = _buffer_size; + + if (is_input) { + port = new InputPort(this, port_name, j, _poly, DataType::FLOAT, port_buffer_size); + _ports->at(j) = port; + } else /* output */ { + port = new OutputPort(this, port_name, j, _poly, DataType::FLOAT, port_buffer_size); + _ports->at(j) = port; + } + + assert(_ports->at(j) != NULL); + + //PortInfo* pi = port->port_info(); + //get_port_vals(j, pi); + + // Set default control val + /*if (pi->is_control()) + ((PortBase*)port)->set_value(pi->default_val(), 0); + else + ((PortBase*)port)->set_value(0.0f, 0);*/ + } + return true; +} + + +LV2Node::~LV2Node() +{ + for (size_t i=0; i < _poly; ++i) + slv2_instance_free(_instances[i]); + + delete[] _instances; +} + + +void +LV2Node::activate() +{ + NodeBase::activate(); + + PortBase* port = NULL; + + for (size_t i=0; i < _poly; ++i) { + for (unsigned long j=0; j < num_ports(); ++j) { + port = static_cast*>(_ports->at(j)); + set_port_buffer(i, j, ((PortBase*)_ports->at(j))->buffer(i)->data()); + 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); + } + slv2_instance_activate(_instances[i]); + } +} + + +void +LV2Node::deactivate() +{ + NodeBase::deactivate(); + + for (size_t i=0; i < _poly; ++i) + slv2_instance_deactivate(_instances[i]); +} + + +void +LV2Node::run(size_t nframes) +{ + NodeBase::run(nframes); // mixes down input ports + for (size_t i=0; i < _poly; ++i) + slv2_instance_run(_instances[i], nframes); +} + + +void +LV2Node::set_port_buffer(size_t voice, size_t port_num, void* buf) +{ + assert(voice < _poly); + + // Could be a MIDI port after this + if (port_num < num_ports()) { + slv2_instance_connect_port(_instances[voice], port_num, buf); + } +} + + +#if 0 +// Based on code stolen from jack-rack +void +LV2Node::get_port_vals(ulong port_index, PortInfo* info) +{ + LV2_Data upper = 0.0f; + LV2_Data lower = 0.0f; + LV2_Data normal = 0.0f; + LV2_PortRangeHintDescriptor hint_descriptor = _descriptor->PortRangeHints[port_index].HintDescriptor; + + /* set upper and lower, possibly adjusted to the sample rate */ + if (LV2_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 (LV2_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 < FLT_EPSILON) lower = FLT_EPSILON; + } + + + if (LV2_IS_HINT_HAS_DEFAULT(hint_descriptor)) { + + if (LV2_IS_HINT_DEFAULT_MINIMUM(hint_descriptor)) { + normal = lower; + } else if (LV2_IS_HINT_DEFAULT_LOW(hint_descriptor)) { + if (LV2_IS_HINT_LOGARITHMIC(hint_descriptor)) { + normal = exp(log(lower) * 0.75 + log(upper) * 0.25); + } else { + normal = lower * 0.75 + upper * 0.25; + } + } else if (LV2_IS_HINT_DEFAULT_MIDDLE(hint_descriptor)) { + if (LV2_IS_HINT_LOGARITHMIC(hint_descriptor)) { + normal = exp(log(lower) * 0.5 + log(upper) * 0.5); + } else { + normal = lower * 0.5 + upper * 0.5; + } + } else if (LV2_IS_HINT_DEFAULT_HIGH(hint_descriptor)) { + if (LV2_IS_HINT_LOGARITHMIC(hint_descriptor)) { + normal = exp(log(lower) * 0.25 + log(upper) * 0.75); + } else { + normal = lower * 0.25 + upper * 0.75; + } + } else if (LV2_IS_HINT_DEFAULT_MAXIMUM(hint_descriptor)) { + normal = upper; + } else if (LV2_IS_HINT_DEFAULT_0(hint_descriptor)) { + normal = 0.0; + } else if (LV2_IS_HINT_DEFAULT_1(hint_descriptor)) { + normal = 1.0; + } else if (LV2_IS_HINT_DEFAULT_100(hint_descriptor)) { + normal = 100.0; + } else if (LV2_IS_HINT_DEFAULT_440(hint_descriptor)) { + normal = 440.0; + } + } else { // No default hint + if (LV2_IS_HINT_BOUNDED_BELOW(hint_descriptor)) { + normal = lower; + } else if (LV2_IS_HINT_BOUNDED_ABOVE(hint_descriptor)) { + normal = upper; + } + } + + info->min_val(lower); + info->default_val(normal); + info->max_val(upper); +} +#endif + + +} // namespace Om + diff --git a/src/libs/engine/LV2Node.h b/src/libs/engine/LV2Node.h new file mode 100644 index 00000000..0956271c --- /dev/null +++ b/src/libs/engine/LV2Node.h @@ -0,0 +1,69 @@ +/* This file is part of Om. Copyright (C) 2006 Dave Robillard. + * + * Om 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. + * + * Om 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., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef LV2NODE_H +#define LV2NODE_H + +#include +#include +#include "util/types.h" +#include "NodeBase.h" +#include "Plugin.h" + +namespace Om { + + +/** An instance of a LV2 plugin. + * + * \ingroup engine + */ +class LV2Node : public NodeBase +{ +public: + LV2Node(const Plugin* plugin, + const string& name, + size_t poly, + Patch* parent, + samplerate srate, + size_t buffer_size); + + virtual ~LV2Node(); + + virtual bool instantiate(); + + void activate(); + void deactivate(); + + void run(size_t nframes); + + void set_port_buffer(size_t voice, size_t port_num, void* buf); + +protected: + // Prevent copies (undefined) + LV2Node(const LV2Node& copy); + LV2Node& operator=(const LV2Node&); + + //void get_port_vals(ulong port_index, PortInfo* info); + + const SLV2Plugin* _lv2_plugin; + SLV2Instance** _instances; +}; + + +} // namespace Om + +#endif // LV2NODE_H + diff --git a/src/libs/engine/LV2Plugin.cpp b/src/libs/engine/LV2Plugin.cpp deleted file mode 100644 index 411caa36..00000000 --- a/src/libs/engine/LV2Plugin.cpp +++ /dev/null @@ -1,263 +0,0 @@ -/* This file is part of Om. Copyright (C) 2006 Dave Robillard. - * - * Om 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. - * - * Om 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., - * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#include "LV2Plugin.h" -#include -#include -#include "float.h" -#include -#include -#include "InputPort.h" -#include "OutputPort.h" -#include "Plugin.h" - -namespace Om { - - -/** Partially construct a LV2Plugin. - * - * Object is not usable until instantiate() is called with success. - * (It _will_ crash!) - */ -LV2Plugin::LV2Plugin(const string& name, - size_t poly, - Patch* parent, - const SLV2Plugin* plugin, - samplerate srate, - size_t buffer_size) -: NodeBase(name, poly, parent, srate, buffer_size), - _lv2_plugin(plugin), - _instances(NULL) -{ - assert(_lv2_plugin); -} - - -/** 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 -LV2Plugin::instantiate() -{ - size_t num_ports = slv2_plugin_get_num_ports(_lv2_plugin); - assert(num_ports > 0); - _ports->alloc(num_ports); - - _instances = new SLV2Instance*[_poly]; - - size_t port_buffer_size = 0; - - for (size_t i=0; i < _poly; ++i) { - _instances[i] = slv2_plugin_instantiate(_lv2_plugin, _srate, NULL); - if (_instances[i] == NULL) { - cerr << "Failed to instantiate plugin!" << endl; - return false; - } - } - - string port_name; - string port_path; - - Port* port = NULL; - - for (size_t j=0; j < num_ports; ++j) { - // LV2 shortnames are guaranteed to be unique, valid C identifiers - port_name = (char*)slv2_port_get_symbol(_lv2_plugin, j); - - assert(port_name.find("/") == string::npos); - - port_path = path() + "/" + port_name; - - // Assumes there is only the 4 classes - - SLV2PortClass port_class = slv2_port_get_class(_lv2_plugin, j); - const bool is_control = (port_class == SLV2_CONTROL_RATE_INPUT - || port_class == SLV2_CONTROL_RATE_OUTPUT); - const bool is_input = (port_class == SLV2_CONTROL_RATE_INPUT - || port_class == SLV2_AUDIO_RATE_INPUT); - - if (is_control) - port_buffer_size = 1; - else - port_buffer_size = _buffer_size; - - if (is_input) { - port = new InputPort(this, port_name, j, _poly, DataType::FLOAT, port_buffer_size); - _ports->at(j) = port; - } else /* output */ { - port = new OutputPort(this, port_name, j, _poly, DataType::FLOAT, port_buffer_size); - _ports->at(j) = port; - } - - assert(_ports->at(j) != NULL); - - //PortInfo* pi = port->port_info(); - //get_port_vals(j, pi); - - // Set default control val - /*if (pi->is_control()) - ((PortBase*)port)->set_value(pi->default_val(), 0); - else - ((PortBase*)port)->set_value(0.0f, 0);*/ - } - return true; -} - - -LV2Plugin::~LV2Plugin() -{ - for (size_t i=0; i < _poly; ++i) - slv2_instance_free(_instances[i]); - - delete[] _instances; -} - - -void -LV2Plugin::activate() -{ - NodeBase::activate(); - - PortBase* port = NULL; - - for (size_t i=0; i < _poly; ++i) { - for (unsigned long j=0; j < num_ports(); ++j) { - port = static_cast*>(_ports->at(j)); - set_port_buffer(i, j, ((PortBase*)_ports->at(j))->buffer(i)->data()); - 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); - } - slv2_instance_activate(_instances[i]); - } -} - - -void -LV2Plugin::deactivate() -{ - NodeBase::deactivate(); - - for (size_t i=0; i < _poly; ++i) - slv2_instance_deactivate(_instances[i]); -} - - -void -LV2Plugin::run(size_t nframes) -{ - NodeBase::run(nframes); // mixes down input ports - for (size_t i=0; i < _poly; ++i) - slv2_instance_run(_instances[i], nframes); -} - - -void -LV2Plugin::set_port_buffer(size_t voice, size_t port_num, void* buf) -{ - assert(voice < _poly); - - // Could be a MIDI port after this - if (port_num < num_ports()) { - slv2_instance_connect_port(_instances[voice], port_num, buf); - } -} - - -#if 0 -// Based on code stolen from jack-rack -void -LV2Plugin::get_port_vals(ulong port_index, PortInfo* info) -{ - LV2_Data upper = 0.0f; - LV2_Data lower = 0.0f; - LV2_Data normal = 0.0f; - LV2_PortRangeHintDescriptor hint_descriptor = _descriptor->PortRangeHints[port_index].HintDescriptor; - - /* set upper and lower, possibly adjusted to the sample rate */ - if (LV2_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 (LV2_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 < FLT_EPSILON) lower = FLT_EPSILON; - } - - - if (LV2_IS_HINT_HAS_DEFAULT(hint_descriptor)) { - - if (LV2_IS_HINT_DEFAULT_MINIMUM(hint_descriptor)) { - normal = lower; - } else if (LV2_IS_HINT_DEFAULT_LOW(hint_descriptor)) { - if (LV2_IS_HINT_LOGARITHMIC(hint_descriptor)) { - normal = exp(log(lower) * 0.75 + log(upper) * 0.25); - } else { - normal = lower * 0.75 + upper * 0.25; - } - } else if (LV2_IS_HINT_DEFAULT_MIDDLE(hint_descriptor)) { - if (LV2_IS_HINT_LOGARITHMIC(hint_descriptor)) { - normal = exp(log(lower) * 0.5 + log(upper) * 0.5); - } else { - normal = lower * 0.5 + upper * 0.5; - } - } else if (LV2_IS_HINT_DEFAULT_HIGH(hint_descriptor)) { - if (LV2_IS_HINT_LOGARITHMIC(hint_descriptor)) { - normal = exp(log(lower) * 0.25 + log(upper) * 0.75); - } else { - normal = lower * 0.25 + upper * 0.75; - } - } else if (LV2_IS_HINT_DEFAULT_MAXIMUM(hint_descriptor)) { - normal = upper; - } else if (LV2_IS_HINT_DEFAULT_0(hint_descriptor)) { - normal = 0.0; - } else if (LV2_IS_HINT_DEFAULT_1(hint_descriptor)) { - normal = 1.0; - } else if (LV2_IS_HINT_DEFAULT_100(hint_descriptor)) { - normal = 100.0; - } else if (LV2_IS_HINT_DEFAULT_440(hint_descriptor)) { - normal = 440.0; - } - } else { // No default hint - if (LV2_IS_HINT_BOUNDED_BELOW(hint_descriptor)) { - normal = lower; - } else if (LV2_IS_HINT_BOUNDED_ABOVE(hint_descriptor)) { - normal = upper; - } - } - - info->min_val(lower); - info->default_val(normal); - info->max_val(upper); -} -#endif - - -} // namespace Om - diff --git a/src/libs/engine/LV2Plugin.h b/src/libs/engine/LV2Plugin.h deleted file mode 100644 index 5e19b6c4..00000000 --- a/src/libs/engine/LV2Plugin.h +++ /dev/null @@ -1,74 +0,0 @@ -/* This file is part of Om. Copyright (C) 2006 Dave Robillard. - * - * Om 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. - * - * Om 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., - * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#ifndef LV2PLUGIN_H -#define LV2PLUGIN_H - -#include -#include -#include "util/types.h" -#include "NodeBase.h" -#include "Plugin.h" - -namespace Om { - - -/** An instance of a LV2 plugin. - * - * \ingroup engine - */ -class LV2Plugin : public NodeBase -{ -public: - LV2Plugin(const string& name, - size_t poly, - Patch* parent, - const SLV2Plugin* plugin, - samplerate srate, - size_t buffer_size); - - virtual ~LV2Plugin(); - - virtual bool instantiate(); - - void activate(); - void deactivate(); - - void run(size_t nframes); - - void set_port_buffer(size_t voice, size_t port_num, void* buf); - - const Plugin* plugin() const { return _om_plugin; } - void plugin(const Plugin* const p) { _om_plugin = p; } - -protected: - // Prevent copies (undefined) - LV2Plugin(const LV2Plugin& copy); - LV2Plugin& operator=(const LV2Plugin&); - - //void get_port_vals(ulong port_index, PortInfo* info); - - const SLV2Plugin* _lv2_plugin; - SLV2Instance** _instances; - - const Plugin* _om_plugin; -}; - - -} // namespace Om - -#endif // LV2PLUGIN_H - diff --git a/src/libs/engine/Makefile.am b/src/libs/engine/Makefile.am index 8a01b21e..0aae5647 100644 --- a/src/libs/engine/Makefile.am +++ b/src/libs/engine/Makefile.am @@ -180,14 +180,14 @@ endif if WITH_LADSPA libom_la_SOURCES += \ - LADSPAPlugin.h \ - LADSPAPlugin.cpp + LADSPANode.h \ + LADSPANode.cpp endif if WITH_DSSI libom_la_SOURCES += \ - DSSIPlugin.h \ - DSSIPlugin.cpp \ + DSSINode.h \ + DSSINode.cpp \ events/DSSIConfigureEvent.cpp \ events/DSSIConfigureEvent.h \ events/DSSIControlEvent.cpp \ @@ -200,8 +200,8 @@ endif if WITH_LV2 libom_la_SOURCES += \ - LV2Plugin.h \ - LV2Plugin.cpp + LV2Node.h \ + LV2Node.cpp endif if WITH_LASH diff --git a/src/libs/engine/MidiControlNode.cpp b/src/libs/engine/MidiControlNode.cpp index 0ce45136..225c3753 100644 --- a/src/libs/engine/MidiControlNode.cpp +++ b/src/libs/engine/MidiControlNode.cpp @@ -31,11 +31,10 @@ namespace Om { MidiControlNode::MidiControlNode(const string& path, size_t poly, Patch* parent, samplerate srate, size_t buffer_size) -: InternalNode(path, 1, parent, srate, buffer_size), +: InternalNode(new Plugin(Plugin::Internal, "Om:ControlNode"), path, 1, parent, srate, buffer_size), _learning(false) { - _num_ports = 7; - _ports = new Array(_num_ports); + _ports = new Array(7); _midi_in_port = new InputPort(this, "MIDI In", 0, 1, DataType::MIDI, _buffer_size); _ports->at(0) = _midi_in_port; @@ -58,7 +57,6 @@ MidiControlNode::MidiControlNode(const string& path, size_t poly, Patch* parent, _control_port = new OutputPort(this, "Out (CR)", 6, 1, DataType::FLOAT, 1); _ports->at(6) = _control_port; - _plugin.type(Plugin::Internal); _plugin.plug_label("midi_control_in"); _plugin.name("Om Control Node (MIDI)"); } diff --git a/src/libs/engine/MidiNoteNode.cpp b/src/libs/engine/MidiNoteNode.cpp index 4c0280bd..a2a95039 100644 --- a/src/libs/engine/MidiNoteNode.cpp +++ b/src/libs/engine/MidiNoteNode.cpp @@ -35,12 +35,11 @@ namespace Om { MidiNoteNode::MidiNoteNode(const string& path, size_t poly, Patch* parent, samplerate srate, size_t buffer_size) -: InternalNode(path, poly, parent, srate, buffer_size), +: InternalNode(new Plugin(Plugin::Internal, "Om:NoteNode"), path, poly, parent, srate, buffer_size), _voices(new Voice[poly]), _sustain(false) { - _num_ports = 5; - _ports = new Array(_num_ports); + _ports = new Array(5); _midi_in_port = new InputPort(this, "DataType::MIDI In", 0, 1, DataType::MIDI, _buffer_size); _ports->at(0) = _midi_in_port; @@ -61,7 +60,6 @@ MidiNoteNode::MidiNoteNode(const string& path, size_t poly, Patch* parent, sampl // new PortInfo("Trigger", AUDIO, OUTPUT, 0, 0, 1), _buffer_size); _ports->at(4) = _trig_port; - _plugin.type(Plugin::Internal); _plugin.plug_label("note_in"); _plugin.name("Om Note Node (MIDI, OSC)"); } diff --git a/src/libs/engine/MidiTriggerNode.cpp b/src/libs/engine/MidiTriggerNode.cpp index d658ddc0..6a2e0a1c 100644 --- a/src/libs/engine/MidiTriggerNode.cpp +++ b/src/libs/engine/MidiTriggerNode.cpp @@ -26,9 +26,8 @@ namespace Om { MidiTriggerNode::MidiTriggerNode(const string& path, size_t poly, Patch* parent, samplerate srate, size_t buffer_size) -: InternalNode(path, 1, parent, srate, buffer_size) +: InternalNode(new Plugin(Plugin::Internal, "Om:TriggerNode"), path, 1, parent, srate, buffer_size) { - _num_ports = 5; _ports = new Array(5); _midi_in_port = new InputPort(this, "DataType::MIDI In", 0, 1, DataType::MIDI, _buffer_size); @@ -50,7 +49,6 @@ MidiTriggerNode::MidiTriggerNode(const string& path, size_t poly, Patch* parent, // new PortInfo("Velocity", AUDIO, OUTPUT, 0, 0, 1), _buffer_size); _ports->at(4) = _vel_port; - _plugin.type(Plugin::Internal); _plugin.plug_label("trigger_in"); _plugin.name("Om Trigger Node (MIDI, OSC)"); } diff --git a/src/libs/engine/Node.h b/src/libs/engine/Node.h index d169e772..f706dc64 100644 --- a/src/libs/engine/Node.h +++ b/src/libs/engine/Node.h @@ -99,7 +99,6 @@ public: * Not the best name - not all nodes come from plugins (ie Patch) */ virtual const Plugin* plugin() const = 0; - virtual void plugin(const Plugin* const pi) = 0; /** Add self to a Patch. * diff --git a/src/libs/engine/NodeBase.cpp b/src/libs/engine/NodeBase.cpp index 4eeada15..a5f23e84 100644 --- a/src/libs/engine/NodeBase.cpp +++ b/src/libs/engine/NodeBase.cpp @@ -34,18 +34,19 @@ using std::cout; using std::cerr; using std::endl; namespace Om { -NodeBase::NodeBase(const string& name, size_t poly, Patch* parent, samplerate srate, size_t buffer_size) +NodeBase::NodeBase(const Plugin* plugin, const string& name, size_t poly, Patch* parent, samplerate srate, size_t buffer_size) : Node(parent, name), + _plugin(plugin), _poly(poly), _srate(srate), _buffer_size(buffer_size), _activated(false), - _num_ports(0), _ports(NULL), _traversed(false), _providers(new List()), _dependants(new List()) { + assert(_plugin); assert(_poly > 0); assert(_parent == NULL || (_poly == parent->internal_poly() || _poly == 1)); } @@ -58,7 +59,7 @@ NodeBase::~NodeBase() delete _providers; delete _dependants; - for (size_t i=0; i < _num_ports; ++i) + for (size_t i=0; i < num_ports(); ++i) delete _ports->at(i); } @@ -108,7 +109,7 @@ NodeBase::remove_from_store() } // Remove ports - for (size_t i=0; i < _num_ports; ++i) { + for (size_t i=0; i < num_ports(); ++i) { node = om->object_store()->remove(_ports->at(i)->path()); if (node != NULL) { assert(om->object_store()->find(_ports->at(i)->path()) == NULL); @@ -125,11 +126,8 @@ NodeBase::run(size_t nframes) { assert(_activated); // Mix down any ports with multiple inputs - Port* p; - for (size_t i=0; i < _ports->size(); ++i) { - p = _ports->at(i); - p->prepare_buffers(nframes); - } + for (size_t i=0; i < _ports->size(); ++i) + _ports->at(i)->prepare_buffers(nframes); } @@ -147,7 +145,7 @@ NodeBase::set_path(const Path& new_path) TreeNode* treenode = NULL; // Reinsert ports - for (size_t i=0; i < _num_ports; ++i) { + for (size_t i=0; i < num_ports(); ++i) { treenode = om->object_store()->remove(old_path +"/"+ _ports->at(i)->name()); assert(treenode != NULL); assert(treenode->node() == _ports->at(i)); diff --git a/src/libs/engine/NodeBase.h b/src/libs/engine/NodeBase.h index c114aa96..d7748543 100644 --- a/src/libs/engine/NodeBase.h +++ b/src/libs/engine/NodeBase.h @@ -40,7 +40,7 @@ namespace Shared { class NodeBase : public Node { public: - NodeBase(const string& name, size_t poly, Patch* parent, samplerate srate, size_t buffer_size); + NodeBase(const Plugin* plugin, const string& name, size_t poly, Patch* parent, samplerate srate, size_t buffer_size); virtual ~NodeBase(); @@ -60,7 +60,7 @@ public: //void send_creation_messages(ClientInterface* client) const; - size_t num_ports() const { return _num_ports; } + size_t num_ports() const { return _ports ? _ports->size() : 0; } size_t poly() const { return _poly; } bool traversed() const { return _traversed; } void traversed(bool b) { _traversed = b; } @@ -75,8 +75,7 @@ public: Patch* parent_patch() const { return (_parent == NULL) ? NULL : _parent->as_patch(); } - virtual const Plugin* plugin() const { exit(EXIT_FAILURE); } - virtual void plugin(const Plugin* const pi) { exit(EXIT_FAILURE); } + virtual const Plugin* plugin() const { return _plugin; } void set_path(const Path& new_path); @@ -85,13 +84,14 @@ protected: NodeBase(const NodeBase&); NodeBase& operator=(const NodeBase&); + const Plugin* _plugin; + size_t _poly; samplerate _srate; size_t _buffer_size; bool _activated; - size_t _num_ports; ///< number of ports PER VOICE Array* _ports; ///< Access in audio thread only bool _traversed; ///< Flag for process order algorithm diff --git a/src/libs/engine/NodeFactory.cpp b/src/libs/engine/NodeFactory.cpp index 9e7128b6..a26744d2 100644 --- a/src/libs/engine/NodeFactory.cpp +++ b/src/libs/engine/NodeFactory.cpp @@ -41,14 +41,14 @@ #include "Om.h" #include "OmApp.h" #ifdef HAVE_SLV2 -#include "LV2Plugin.h" +#include "LV2Node.h" #include #endif #ifdef HAVE_LADSPA -#include "LADSPAPlugin.h" +#include "LADSPANode.h" #endif #ifdef HAVE_DSSI -#include "DSSIPlugin.h" +#include "DSSINode.h" #endif using std::string; @@ -352,14 +352,13 @@ NodeFactory::load_lv2_plugin(const string& plug_uri, Node* n = NULL; if (plugin) { - n = new Om::LV2Plugin(node_name, poly, parent, plugin->slv2_plugin(), + n = new Om::LV2Node(plugin, node_name, poly, parent, om->audio_driver()->sample_rate(), om->audio_driver()->buffer_size()); - bool success = ((LV2Plugin*)n)->instantiate(); + bool success = ((LV2Node*)n)->instantiate(); if (!success) { delete n; n = NULL; } - n->plugin(plugin); } return n; @@ -528,15 +527,13 @@ NodeFactory::load_dssi_plugin(const string& uri, return NULL; } - n = new DSSIPlugin(name, poly, parent, descriptor, + n = new DSSINode(plugin, name, poly, parent, descriptor, om->audio_driver()->sample_rate(), om->audio_driver()->buffer_size()); - bool success = ((DSSIPlugin*)n)->instantiate(); + bool success = ((DSSINode*)n)->instantiate(); if (!success) { delete n; n = NULL; } - - n->plugin(plugin); return n; } @@ -693,16 +690,14 @@ NodeFactory::load_ladspa_plugin(const string& uri, return NULL; } - n = new LADSPAPlugin(name, poly, parent, descriptor, + n = new LADSPANode(plugin, name, poly, parent, descriptor, om->audio_driver()->sample_rate(), om->audio_driver()->buffer_size()); - bool success = ((LADSPAPlugin*)n)->instantiate(); + bool success = ((LADSPANode*)n)->instantiate(); if (!success) { delete n; n = NULL; } - n->plugin(plugin); - return n; } diff --git a/src/libs/engine/NodeFactory.h b/src/libs/engine/NodeFactory.h index bec300bf..f6a8dbd1 100644 --- a/src/libs/engine/NodeFactory.h +++ b/src/libs/engine/NodeFactory.h @@ -39,7 +39,7 @@ class Plugin; * 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 LADSPAPlugin) are responsible + * The constructor of various Node types (ie LADSPANode) are responsible * for actually creating a Node instance of the plugin. * * \ingroup engine diff --git a/src/libs/engine/Patch.cpp b/src/libs/engine/Patch.cpp index 9e9ca173..1e9aa566 100644 --- a/src/libs/engine/Patch.cpp +++ b/src/libs/engine/Patch.cpp @@ -38,17 +38,15 @@ namespace Om { Patch::Patch(const string& path, size_t poly, Patch* parent, samplerate srate, size_t buffer_size, size_t internal_poly) -: NodeBase(path, poly, parent, srate, buffer_size), +: NodeBase(new Plugin(Plugin::Patch, "Om:Patch"), path, poly, parent, srate, buffer_size), _internal_poly(internal_poly), _process_order(NULL), _process(false) { assert(internal_poly >= 1); - _plugin.type(Plugin::Patch); - _plugin.uri("http://codeson.net/grauph/patch"); _plugin.plug_label("om_patch"); - _plugin.name("Om patch"); + _plugin.name("Om Patch"); //std::cerr << "Creating patch " << _name << ", poly = " << poly // << ", internal poly = " << internal_poly << std::endl; @@ -153,18 +151,6 @@ Patch::run(size_t nframes) } -/** Returns the number of ports. - * - * Needs to override the NodeBase implementation since a Patch's ports are really - * just it's input and output nodes' ports. - */ -size_t -Patch::num_ports() const -{ - return _patch_ports.size(); -} - - #if 0 void Patch::send_creation_messages(ClientInterface* client) const diff --git a/src/libs/engine/Patch.h b/src/libs/engine/Patch.h index 5f2782d5..201912b5 100644 --- a/src/libs/engine/Patch.h +++ b/src/libs/engine/Patch.h @@ -58,8 +58,6 @@ public: void run(size_t nframes); - size_t num_ports() const; - //void send_creation_messages(ClientInterface* client) const; void add_to_store(); @@ -94,21 +92,21 @@ public: void external_ports(Array* pa) { _ports = pa; } Array* build_process_order() const; - inline void build_process_order_recursive(Node* n, Array* order) const; - /** Whether to run this patch's DSP in the audio thread */ + /** Whether to run this patch's DSP bits in the audio thread */ bool process() const { return _process; } void process(bool p); size_t internal_poly() const { return _internal_poly; } const Plugin* plugin() const { return &_plugin; } - void plugin(const Plugin* const) { exit(EXIT_FAILURE); } private: // Prevent copies (undefined) Patch(const Patch&); Patch& operator=(const Patch&); + + inline void build_process_order_recursive(Node* n, Array* order) const; size_t _internal_poly; Array* _process_order; ///< Accessed in audio thread only diff --git a/src/libs/engine/Plugin.h b/src/libs/engine/Plugin.h index d350b1e8..fc7ed7c4 100644 --- a/src/libs/engine/Plugin.h +++ b/src/libs/engine/Plugin.h @@ -46,6 +46,12 @@ class Plugin public: enum Type { LV2, LADSPA, DSSI, Internal, Patch }; + Plugin(Type type, const string& uri) + : m_type(type) + , m_uri(uri) + {} + + // FIXME: remove Plugin() : m_type(Internal), m_lib_path("/Om"), m_id(0), m_library(NULL) { @@ -119,7 +125,7 @@ public: // FIXME: ew #ifdef HAVE_SLV2 - SLV2Plugin* slv2_plugin() { return m_slv2_plugin; } + SLV2Plugin* slv2_plugin() const { return m_slv2_plugin; } void slv2_plugin(const SLV2Plugin* p) { m_slv2_plugin = p; } #endif diff --git a/src/libs/engine/TransportNode.cpp b/src/libs/engine/TransportNode.cpp index 2a67a49a..faa647a2 100644 --- a/src/libs/engine/TransportNode.cpp +++ b/src/libs/engine/TransportNode.cpp @@ -29,9 +29,8 @@ namespace Om { TransportNode::TransportNode(const string& path, size_t poly, Patch* parent, samplerate srate, size_t buffer_size) -: InternalNode(path, 1, parent, srate, buffer_size) +: InternalNode(new Plugin(Plugin::Internal, "Om:TransportNode"), path, 1, parent, srate, buffer_size) { - _num_ports = 0; #if 0 _num_ports = 10; _ports.alloc(_num_ports); @@ -76,7 +75,6 @@ TransportNode::TransportNode(const string& path, size_t poly, Patch* parent, sam // new PortInfo("Bar Tick", AUDIO, OUTPUT, 0, 0, 1), buffer_size); _ports.at(9) = bar_trig_port; #endif - _plugin.type(Plugin::Internal); _plugin.plug_label("transport"); _plugin.name("Om Transport Node (BROKEN)"); } diff --git a/src/libs/engine/events/DSSIConfigureEvent.cpp b/src/libs/engine/events/DSSIConfigureEvent.cpp index 2ade4671..c7bfdb61 100644 --- a/src/libs/engine/events/DSSIConfigureEvent.cpp +++ b/src/libs/engine/events/DSSIConfigureEvent.cpp @@ -41,7 +41,7 @@ DSSIConfigureEvent::pre_process() Node* node = om->object_store()->find_node(m_node_path); if (node != NULL && node->plugin()->type() == Plugin::DSSI) { - m_node = (DSSIPlugin*)node; + m_node = (DSSINode*)node; m_node->configure(m_key, m_val); } diff --git a/src/libs/engine/events/DSSIConfigureEvent.h b/src/libs/engine/events/DSSIConfigureEvent.h index 00b4a134..0e77e217 100644 --- a/src/libs/engine/events/DSSIConfigureEvent.h +++ b/src/libs/engine/events/DSSIConfigureEvent.h @@ -18,7 +18,7 @@ #define DSSICONFIGUREEVENT_H #include "QueuedEvent.h" -#include "DSSIPlugin.h" +#include "DSSINode.h" namespace Om { @@ -37,10 +37,10 @@ public: void post_process(); private: - string m_node_path; - string m_key; - string m_val; - DSSIPlugin* m_node; + string m_node_path; + string m_key; + string m_val; + DSSINode* m_node; }; diff --git a/src/libs/engine/events/DSSIControlEvent.cpp b/src/libs/engine/events/DSSIControlEvent.cpp index ea3e70ac..986fa33c 100644 --- a/src/libs/engine/events/DSSIControlEvent.cpp +++ b/src/libs/engine/events/DSSIControlEvent.cpp @@ -42,7 +42,7 @@ DSSIControlEvent::pre_process() if (node->plugin()->type() != Plugin::DSSI) m_node = NULL; else - m_node = (DSSIPlugin*)node; + m_node = (DSSINode*)node; QueuedEvent::pre_process(); } diff --git a/src/libs/engine/events/DSSIControlEvent.h b/src/libs/engine/events/DSSIControlEvent.h index 30a5279e..33d9ec5e 100644 --- a/src/libs/engine/events/DSSIControlEvent.h +++ b/src/libs/engine/events/DSSIControlEvent.h @@ -18,7 +18,7 @@ #define DSSICONTROLEVENT_H #include "QueuedEvent.h" -#include "DSSIPlugin.h" +#include "DSSINode.h" namespace Om { @@ -39,10 +39,10 @@ public: void post_process(); private: - string m_node_path; - int m_port_num; - float m_val; - DSSIPlugin* m_node; + string m_node_path; + int m_port_num; + float m_val; + DSSINode* m_node; }; diff --git a/src/libs/engine/events/DSSIProgramEvent.cpp b/src/libs/engine/events/DSSIProgramEvent.cpp index eb68ef77..970daef6 100644 --- a/src/libs/engine/events/DSSIProgramEvent.cpp +++ b/src/libs/engine/events/DSSIProgramEvent.cpp @@ -45,7 +45,7 @@ DSSIProgramEvent::pre_process() Node* node = om->object_store()->find_node(m_node_path); if (node != NULL && node->plugin()->type() == Plugin::DSSI) - m_node = (DSSIPlugin*)node; + m_node = (DSSINode*)node; QueuedEvent::pre_process(); } diff --git a/src/libs/engine/events/DSSIProgramEvent.h b/src/libs/engine/events/DSSIProgramEvent.h index 152f3cb1..27f70e41 100644 --- a/src/libs/engine/events/DSSIProgramEvent.h +++ b/src/libs/engine/events/DSSIProgramEvent.h @@ -18,7 +18,7 @@ #define DSSIPROGRAMEVENT_H #include "QueuedEvent.h" -#include "DSSIPlugin.h" +#include "DSSINode.h" namespace Om { @@ -37,10 +37,10 @@ public: void post_process(); private: - string m_node_path; - int m_bank; - int m_program; - DSSIPlugin* m_node; + string m_node_path; + int m_bank; + int m_program; + DSSINode* m_node; }; diff --git a/src/libs/engine/events/DSSIUpdateEvent.cpp b/src/libs/engine/events/DSSIUpdateEvent.cpp index 5650dd63..fb441e67 100644 --- a/src/libs/engine/events/DSSIUpdateEvent.cpp +++ b/src/libs/engine/events/DSSIUpdateEvent.cpp @@ -20,7 +20,7 @@ #include "ObjectStore.h" #include "Om.h" #include "OmApp.h" -#include "DSSIPlugin.h" +#include "DSSINode.h" #include "Plugin.h" using std::cerr; using std::endl; @@ -47,7 +47,7 @@ DSSIUpdateEvent::pre_process() QueuedEvent::pre_process(); return; } else { - m_node = (DSSIPlugin*)node; + m_node = (DSSINode*)node; } QueuedEvent::pre_process(); diff --git a/src/libs/engine/events/DSSIUpdateEvent.h b/src/libs/engine/events/DSSIUpdateEvent.h index cdd8851e..3cee300f 100644 --- a/src/libs/engine/events/DSSIUpdateEvent.h +++ b/src/libs/engine/events/DSSIUpdateEvent.h @@ -24,7 +24,7 @@ using std::string; namespace Om { -class DSSIPlugin; +class DSSINode; /** A DSSI "update" responder for a DSSI plugin/node. @@ -43,9 +43,9 @@ public: void post_process(); private: - string m_path; - string m_url; - DSSIPlugin* m_node; + string m_path; + string m_url; + DSSINode* m_node; }; -- cgit v1.2.1