diff options
author | David Robillard <d@drobilla.net> | 2006-06-18 08:06:14 +0000 |
---|---|---|
committer | David Robillard <d@drobilla.net> | 2006-06-18 08:06:14 +0000 |
commit | 172a0119ee0a0bb6d50836c70936907c3eb71c9e (patch) | |
tree | cbcc56285b033bb9857b9be85f5f9be193b6f38f /src | |
parent | e6f42fd640dcbad6b2e39cc85bdf307d197278b0 (diff) | |
download | ingen-172a0119ee0a0bb6d50836c70936907c3eb71c9e.tar.gz ingen-172a0119ee0a0bb6d50836c70936907c3eb71c9e.tar.bz2 ingen-172a0119ee0a0bb6d50836c70936907c3eb71c9e.zip |
More work on new ports implementation;
lots of mass renaming and code removal.
git-svn-id: http://svn.drobilla.net/lad/grauph@52 a436a847-0d15-0410-975c-d299462d15a1
Diffstat (limited to 'src')
71 files changed, 1041 insertions, 1467 deletions
diff --git a/src/common/interface/EngineInterface.h b/src/common/interface/EngineInterface.h index c290a921..3c7084bc 100644 --- a/src/common/interface/EngineInterface.h +++ b/src/common/interface/EngineInterface.h @@ -55,6 +55,10 @@ public: virtual void create_patch(const string& path, uint32_t poly) = 0; + virtual void create_port(const string& path, + const string& data_type, + bool direction) = 0; + virtual void create_node(const string& path, const string& plugin_type, const string& plugin_uri, diff --git a/src/common/util/Makefile.am b/src/common/util/Makefile.am index b835dfde..dfa7ce2d 100644 --- a/src/common/util/Makefile.am +++ b/src/common/util/Makefile.am @@ -2,5 +2,4 @@ EXTRA_DIST = \ CountedPtr.h \ Path.h \ Queue.h \ - Semaphore.h \ - types.h + Semaphore.h diff --git a/src/libs/client/OSCEngineInterface.cpp b/src/libs/client/OSCEngineInterface.cpp index 5ac598f1..9c6c9299 100644 --- a/src/libs/client/OSCEngineInterface.cpp +++ b/src/libs/client/OSCEngineInterface.cpp @@ -113,6 +113,20 @@ OSCEngineInterface::create_patch(const string& path, void +OSCEngineInterface::create_port(const string& path, + const string& data_type, + bool direction) +{ + assert(_engine_addr); + lo_send(_engine_addr, "/om/synth/create_port", "issi", + next_id(), + path.c_str(), + data_type.c_str(), + (direction ? 1 : 0)); +} + + +void OSCEngineInterface::create_node(const string& path, const string& plugin_type, const string& plugin_uri, diff --git a/src/libs/client/OSCEngineInterface.h b/src/libs/client/OSCEngineInterface.h index 63157da1..89263e01 100644 --- a/src/libs/client/OSCEngineInterface.h +++ b/src/libs/client/OSCEngineInterface.h @@ -71,6 +71,10 @@ public: void create_patch(const string& path, uint32_t poly); + void create_port(const string& path, + const string& data_type, + bool direction); + void create_node(const string& path, const string& plugin_type, const string& plugin_uri, diff --git a/src/libs/engine/AlsaMidiDriver.cpp b/src/libs/engine/AlsaMidiDriver.cpp index decd2471..84910638 100644 --- a/src/libs/engine/AlsaMidiDriver.cpp +++ b/src/libs/engine/AlsaMidiDriver.cpp @@ -24,7 +24,6 @@ #include "OmApp.h" #include "Maid.h" #include "AudioDriver.h" -#include "PortInfo.h" #include "MidiMessage.h" #include "PortBase.h" #ifdef HAVE_LASH diff --git a/src/libs/engine/Array.h b/src/libs/engine/Array.h index 6b56ecc5..6ec51b89 100644 --- a/src/libs/engine/Array.h +++ b/src/libs/engine/Array.h @@ -46,10 +46,12 @@ public: Array(size_t size, const Array<T>* contents) : m_size(size), m_top(size+1) { m_elems = new T[size]; - if (size <= contents->size()) - memcpy(m_elems, contents->m_elems, size * sizeof(T)); - else - memcpy(m_elems, contents->m_elems, contents->size() * sizeof(T)); + if (contents) { + if (size <= contents->size()) + memcpy(m_elems, contents->m_elems, size * sizeof(T)); + else + memcpy(m_elems, contents->m_elems, contents->size() * sizeof(T)); + } } ~Array() { diff --git a/src/libs/engine/AudioInputNode.cpp b/src/libs/engine/AudioInputNode.cpp deleted file mode 100644 index 8a3594cb..00000000 --- a/src/libs/engine/AudioInputNode.cpp +++ /dev/null @@ -1,49 +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 "AudioInputNode.h" -#include "InputPort.h" -#include "OutputPort.h" -#include "Plugin.h" -#include "PortInfo.h" -#include "Patch.h" - -namespace Om { - - -AudioInputNode::AudioInputNode(const string& path, size_t poly, Patch* parent, samplerate srate, size_t buffer_size) -: BridgeNode<sample>(path, poly, parent, srate, buffer_size) -{ - OutputPort<sample>* internal_port = new OutputPort<sample>(this, "in", 0, m_poly, - new PortInfo("in", AUDIO, OUTPUT), m_buffer_size); - InputPort<sample>* external_port = new InputPort<sample>(parent, m_name, 0, m_poly, - new PortInfo(m_name, AUDIO, INPUT), m_buffer_size); - external_port->tie(internal_port); - m_external_port = external_port; - internal_port->set_value(0, 0); - - m_num_ports = 1; - m_ports.alloc(m_num_ports); - m_ports.at(0) = internal_port; - - m_plugin.type(Plugin::Internal); - m_plugin.plug_label("audio_input"); - m_plugin.name("Om Patch Audio Input Node"); -} - - -} // namespace Om - diff --git a/src/libs/engine/AudioInputNode.h b/src/libs/engine/AudioInputNode.h deleted file mode 100644 index 894ec082..00000000 --- a/src/libs/engine/AudioInputNode.h +++ /dev/null @@ -1,45 +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 AUDIOINPUTNODE_H -#define AUDIOINPUTNODE_H - -#include <string> -#include "util/types.h" -#include "BridgeNode.h" - -using std::string; - -namespace Om { - -class Patch; -template <typename T> class InputPort; - - -/** Audio input BridgeNode. - * - * \ingroup engine - */ -class AudioInputNode : public BridgeNode<sample> -{ -public: - AudioInputNode(const string& path, size_t poly, Patch* parent, samplerate srate, size_t buffer_size); -}; - - -} // namespace Om - -#endif // AUDIOINPUTNODE_H diff --git a/src/libs/engine/AudioOutputNode.cpp b/src/libs/engine/AudioOutputNode.cpp deleted file mode 100644 index d9a925f8..00000000 --- a/src/libs/engine/AudioOutputNode.cpp +++ /dev/null @@ -1,50 +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 "AudioOutputNode.h" -#include "InputPort.h" -#include "OutputPort.h" -#include "Plugin.h" -#include "Patch.h" -#include "PortInfo.h" -#include <cassert> - -namespace Om { - - -AudioOutputNode::AudioOutputNode(const string& path, size_t poly, Patch* parent, samplerate srate, size_t buffer_size) -: BridgeNode<sample>(path, poly, parent, srate, buffer_size) -{ - OutputPort<sample>* external_port = new OutputPort<sample>(parent, m_name, 0, m_poly, - new PortInfo(m_name, AUDIO, OUTPUT), m_buffer_size); - InputPort<sample>* internal_port = new InputPort<sample>(this, "out", 0, m_poly, - new PortInfo("out", AUDIO, INPUT), m_buffer_size); - internal_port->tie(external_port); - m_external_port = external_port; - internal_port->set_value(0, 0); - - m_num_ports = 1; - m_ports.alloc(m_num_ports); - m_ports.at(0) = internal_port; - - m_plugin.type(Plugin::Internal); - m_plugin.plug_label("audio_output"); - m_plugin.name("Om Patch Audio Output Node"); -} - - -} // namespace Om - diff --git a/src/libs/engine/AudioOutputNode.h b/src/libs/engine/AudioOutputNode.h deleted file mode 100644 index 6399cfc6..00000000 --- a/src/libs/engine/AudioOutputNode.h +++ /dev/null @@ -1,44 +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 AUDIOOUTPUTNODE_H -#define AUDIOOUTPUTNODE_H - -#include <string> -#include "util/types.h" -#include "BridgeNode.h" - -using std::string; - -namespace Om { - -template <typename T> class OutputPort; - - -/** Audio output BridgeNode. - * - * \ingroup engine - */ -class AudioOutputNode : public BridgeNode<sample> -{ -public: - AudioOutputNode(const string& path, size_t poly, Patch* parent, samplerate srate, size_t buffer_size); -}; - - -} // namespace Om - -#endif // AUDIOOUTPUTNODE_H diff --git a/src/libs/engine/ClientBroadcaster.cpp b/src/libs/engine/ClientBroadcaster.cpp index f8823233..8cff03c6 100644 --- a/src/libs/engine/ClientBroadcaster.cpp +++ b/src/libs/engine/ClientBroadcaster.cpp @@ -25,7 +25,6 @@ #include "util.h" #include "Patch.h" #include "Node.h" -#include "PortInfo.h" #include "Plugin.h" #include "PortBase.h" #include "Connection.h" diff --git a/src/libs/engine/ClientBroadcaster.h b/src/libs/engine/ClientBroadcaster.h index b0a60f57..aa631473 100644 --- a/src/libs/engine/ClientBroadcaster.h +++ b/src/libs/engine/ClientBroadcaster.h @@ -33,7 +33,6 @@ namespace Om { class Node; class Port; -class PortInfo; class Plugin; class Patch; class Connection; diff --git a/src/libs/engine/ControlInputNode.cpp b/src/libs/engine/ControlInputNode.cpp deleted file mode 100644 index d4d83558..00000000 --- a/src/libs/engine/ControlInputNode.cpp +++ /dev/null @@ -1,49 +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 "ControlInputNode.h" -#include "util/types.h" -#include "Patch.h" -#include "OutputPort.h" -#include "InputPort.h" -#include "Plugin.h" -#include "PortInfo.h" - -namespace Om { - - -ControlInputNode::ControlInputNode(const string& path, size_t poly, Patch* parent, samplerate srate, size_t buffer_size) -: BridgeNode<sample>(path, poly, parent, srate, buffer_size) -{ - OutputPort<sample>* internal_port = new OutputPort<sample>(this, "in", 0, m_poly, - new PortInfo("in", CONTROL, OUTPUT), 1); - InputPort<sample>* external_port = new InputPort<sample>(parent, m_name, 0, m_poly, - new PortInfo(m_name, CONTROL, INPUT), 1); - external_port->tie(internal_port); - m_external_port = external_port; - - m_num_ports = 1; - m_ports.alloc(m_num_ports); - m_ports.at(0) = internal_port; - - m_plugin.type(Plugin::Internal); - m_plugin.plug_label("control_input"); - m_plugin.name("Om Patch Control Input Node"); -} - - -} // namespace Om - diff --git a/src/libs/engine/ControlInputNode.h b/src/libs/engine/ControlInputNode.h deleted file mode 100644 index 0be82af0..00000000 --- a/src/libs/engine/ControlInputNode.h +++ /dev/null @@ -1,44 +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 CONTROLINPUTNODE_H -#define CONTROLINPUTNODE_H - -#include <string> -#include "util/types.h" -#include "BridgeNode.h" - -using std::string; - -namespace Om { - -template <typename T> class InputPort; - - -/** Control input BridgeNode. - * - * \ingroup engine - */ -class ControlInputNode : public BridgeNode<sample> -{ -public: - ControlInputNode(const string& path, size_t poly, Patch* parent, samplerate srate, size_t buffer_size); -}; - - -} // namespace Om - -#endif // CONTROLINPUTNODE_H diff --git a/src/libs/engine/ControlOutputNode.cpp b/src/libs/engine/ControlOutputNode.cpp deleted file mode 100644 index 7e1f3e2a..00000000 --- a/src/libs/engine/ControlOutputNode.cpp +++ /dev/null @@ -1,48 +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 "ControlOutputNode.h" -#include "InputPort.h" -#include "OutputPort.h" -#include "PortInfo.h" -#include "Plugin.h" -#include "Patch.h" - -namespace Om { - - -ControlOutputNode::ControlOutputNode(const string& path, size_t poly, Patch* parent, samplerate srate, size_t buffer_size) -: BridgeNode<sample>(path, poly, parent, srate, buffer_size) -{ - OutputPort<sample>* external_port = new OutputPort<sample>(parent, m_name, 0, m_poly, - new PortInfo(m_name, CONTROL, OUTPUT), 1); - InputPort<sample>* internal_port = new InputPort<sample>(this, "out", 0, m_poly, - new PortInfo("out", CONTROL, INPUT), 1); - internal_port->tie(external_port); - m_external_port = external_port; - - m_num_ports = 1; - m_ports.alloc(m_num_ports); - m_ports.at(0) = internal_port; - - m_plugin.type(Plugin::Internal); - m_plugin.plug_label("control_output"); - m_plugin.name("Om Patch Control Output Node"); -} - - -} // namespace Om - diff --git a/src/libs/engine/ControlOutputNode.h b/src/libs/engine/ControlOutputNode.h deleted file mode 100644 index 64fd9ce6..00000000 --- a/src/libs/engine/ControlOutputNode.h +++ /dev/null @@ -1,45 +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 CONTROLOUTPUTNODE_H -#define CONTROLOUTPUTNODE_H - -#include <string> -#include "util/types.h" -#include "BridgeNode.h" - -using std::string; - -namespace Om { - -class Port; -template <typename T> class OutputPort; - - -/** Control output BridgeNode. - * - * \ingroup engine - */ -class ControlOutputNode : public BridgeNode<sample> -{ -public: - ControlOutputNode(const string& path, size_t poly, Patch* parent, samplerate srate, size_t buffer_size); -}; - - -} // namespace Om - -#endif // CONTROLOUTPUTNODE_H diff --git a/src/libs/engine/DSSIPlugin.cpp b/src/libs/engine/DSSIPlugin.cpp index e8525b7b..ade48d82 100644 --- a/src/libs/engine/DSSIPlugin.cpp +++ b/src/libs/engine/DSSIPlugin.cpp @@ -22,7 +22,6 @@ #include "ClientBroadcaster.h" #include "interface/ClientInterface.h" #include "InputPort.h" -#include "PortInfo.h" using namespace std; @@ -31,28 +30,28 @@ 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), - m_dssi_descriptor(descriptor), - m_ui_addr(NULL), - m_bank(-1), - m_program(-1), - m_midi_in_port(NULL), - m_alsa_events(new snd_seq_event_t[m_buffer_size]), - m_alsa_encoder(NULL) + _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) { if (has_midi_input()) - m_num_ports = descriptor->LADSPA_Plugin->PortCount + 1; + _num_ports = descriptor->LADSPA_Plugin->PortCount + 1; - snd_midi_event_new(3, &m_alsa_encoder); + snd_midi_event_new(3, &_alsa_encoder); } DSSIPlugin::~DSSIPlugin() { - if (m_ui_addr != NULL) - lo_address_free(m_ui_addr); + if (_ui_addr != NULL) + lo_address_free(_ui_addr); - snd_midi_event_free(m_alsa_encoder); - delete [] m_alsa_events; + snd_midi_event_free(_alsa_encoder); + delete [] _alsa_events; } @@ -67,12 +66,11 @@ DSSIPlugin::instantiate() return false; if (has_midi_input()) { - assert(m_num_ports == m_descriptor->PortCount + 1); - assert(m_ports.size() == m_descriptor->PortCount + 1); + assert(_num_ports == _descriptor->PortCount + 1); + assert(_ports->size() == _descriptor->PortCount + 1); - m_midi_in_port = new InputPort<MidiMessage>(this, "MIDI In", m_num_ports-1, 1, - new PortInfo("MIDI In", MIDI, INPUT), m_buffer_size); - m_ports.at(m_num_ports-1) = m_midi_in_port; + _midi_in_port = new InputPort<MidiMessage>(this, "MIDI In", _num_ports-1, 1, DataType::MIDI, _buffer_size); + _ports->at(_num_ports-1) = _midi_in_port; } return true; @@ -87,38 +85,38 @@ DSSIPlugin::activate() update_programs(false); set_default_program(); - snd_midi_event_reset_encode(m_alsa_encoder); + snd_midi_event_reset_encode(_alsa_encoder); } void DSSIPlugin::set_ui_url(const string& url) { - if (m_ui_addr != NULL) - lo_address_free(m_ui_addr); + if (_ui_addr != NULL) + lo_address_free(_ui_addr); - m_ui_url = url; - m_ui_addr = lo_address_new_from_url(url.c_str()); + _ui_url = url; + _ui_addr = lo_address_new_from_url(url.c_str()); char* base_path = lo_url_get_path(url.c_str()); - m_ui_base_path = base_path; + _ui_base_path = base_path; free(base_path); - cerr << "Set UI base path to " << m_ui_base_path << endl; + cerr << "Set UI base path to " << _ui_base_path << endl; } void DSSIPlugin::set_control(size_t port_num, sample val) { - assert(port_num < m_descriptor->PortCount); - ((PortBase<sample>*)m_ports.at(port_num))->set_value(val, 0); + assert(port_num < _descriptor->PortCount); + ((PortBase<sample>*)_ports->at(port_num))->set_value(val, 0); } void DSSIPlugin::configure(const string& key, const string& val) { - m_dssi_descriptor->configure(m_instances[0], key.c_str(), val.c_str()); - m_configures[key] = val; + _dssi_descriptor->configure(_instances[0], key.c_str(), val.c_str()); + _configures[key] = val; update_programs(true); } @@ -126,11 +124,11 @@ DSSIPlugin::configure(const string& key, const string& val) void DSSIPlugin::program(int bank, int program) { - if (m_dssi_descriptor->select_program) - m_dssi_descriptor->select_program(m_instances[0], bank, program); + if (_dssi_descriptor->select_program) + _dssi_descriptor->select_program(_instances[0], bank, program); - m_bank = bank; - m_program = program; + _bank = bank; + _program = program; } @@ -138,18 +136,18 @@ void DSSIPlugin::convert_events() { assert(has_midi_input()); - assert(m_midi_in_port != NULL); + assert(_midi_in_port != NULL); - Buffer<MidiMessage>& buffer = *m_midi_in_port->buffer(0); - m_encoded_events = 0; + Buffer<MidiMessage>& buffer = *_midi_in_port->buffer(0); + _encoded_events = 0; for (size_t i = 0; i < buffer.filled_size(); ++i) { - snd_midi_event_encode(m_alsa_encoder, buffer.value_at(i).buffer, + snd_midi_event_encode(_alsa_encoder, buffer.value_at(i).buffer, buffer.value_at(i).size, - &m_alsa_events[m_encoded_events]); - m_alsa_events[m_encoded_events].time.tick = buffer.value_at(i).time; - if (m_alsa_events[m_encoded_events].type != SND_SEQ_EVENT_NONE) - ++m_encoded_events; + &_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; } } @@ -157,7 +155,7 @@ DSSIPlugin::convert_events() bool DSSIPlugin::has_midi_input() const { - return (m_dssi_descriptor->run_synth || m_dssi_descriptor->run_multiple_synths); + return (_dssi_descriptor->run_synth || _dssi_descriptor->run_multiple_synths); } @@ -166,16 +164,16 @@ DSSIPlugin::run(size_t nframes) { NodeBase::run(nframes); - if (m_dssi_descriptor->run_synth) { + if (_dssi_descriptor->run_synth) { convert_events(); - m_dssi_descriptor->run_synth(m_instances[0], nframes, - m_alsa_events, m_encoded_events); - } else if (m_dssi_descriptor->run_multiple_synths) { + _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] = { m_alsa_events }; - long unsigned events_sizes[1] = { m_encoded_events }; - m_dssi_descriptor->run_multiple_synths(1, m_instances, nframes, + 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); @@ -186,48 +184,48 @@ DSSIPlugin::run(size_t nframes) void DSSIPlugin::send_control(int port_num, float value) { - string path = m_ui_base_path + "/control"; - lo_send(m_ui_addr, path.c_str(), "if", port_num, 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 = m_ui_base_path + "/program"; - lo_send(m_ui_addr, path.c_str(), "ii", bank, 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 = m_ui_base_path + "/configure"; - lo_send(m_ui_addr, path.c_str(), "ss", key.c_str(), val.c_str()); + 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 = m_ui_base_path + "/show"; - lo_send(m_ui_addr, path.c_str(), NULL); + string path = _ui_base_path + "/show"; + lo_send(_ui_addr, path.c_str(), NULL); } void DSSIPlugin::send_hide() { - string path = m_ui_base_path + "/hide"; - lo_send(m_ui_addr, path.c_str(), NULL); + string path = _ui_base_path + "/hide"; + lo_send(_ui_addr, path.c_str(), NULL); } void DSSIPlugin::send_quit() { - string path = m_ui_base_path + "/quit"; - lo_send(m_ui_addr, path.c_str(), NULL); + string path = _ui_base_path + "/quit"; + lo_send(_ui_addr, path.c_str(), NULL); } @@ -235,16 +233,16 @@ void DSSIPlugin::send_update() { // send "configure"s - for (map<string, string>::iterator i = m_configures.begin(); i != m_configures.end(); ++i) + for (map<string, string>::iterator i = _configures.begin(); i != _configures.end(); ++i) send_configure((*i).first, (*i).second); // send "program" - send_program(m_bank, m_program); + send_program(_bank, _program); // send "control"s - for (size_t i=0; i < m_ports.size(); ++i) - if (m_ports[i]->port_info()->is_control()) - send_control(m_ports[i]->num(), ((PortBase<sample>*)m_ports[i])->buffer(0)->value_at(0)); + 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<sample>*)_ports->at(i))->buffer(0)->value_at(0)); // send "show" FIXME: not to spec send_show(); @@ -258,25 +256,25 @@ DSSIPlugin::update_programs(bool send_events) set<pair<int, int> > to_be_deleted; map<int, Bank>::const_iterator iter; Bank::const_iterator iter2; - for (iter = m_banks.begin(); iter != m_banks.end(); ++iter) { + 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 (m_dssi_descriptor->get_program) { + if (_dssi_descriptor->get_program) { for (int i = 0; true; ++i) { const DSSI_Program_Descriptor* descriptor = - m_dssi_descriptor->get_program(m_instances[0], i); + _dssi_descriptor->get_program(_instances[0], i); if (!descriptor) break; - iter = m_banks.find(descriptor->Bank); - if (iter == m_banks.end() || + 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) { - m_banks[descriptor->Bank][descriptor->Program] = descriptor->Name; + _banks[descriptor->Bank][descriptor->Program] = descriptor->Name; if (send_events) { om->client_broadcaster()->send_program_add(path(), descriptor->Bank, descriptor->Program, @@ -291,11 +289,11 @@ DSSIPlugin::update_programs(bool send_events) set<pair<int, int> >::const_iterator set_iter; for (set_iter = to_be_deleted.begin(); set_iter != to_be_deleted.end(); ++set_iter) { - m_banks[set_iter->first].erase(set_iter->second); + _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 (m_banks[set_iter->first].size() == 0) - m_banks.erase(set_iter->first); + if (_banks[set_iter->first].size() == 0) + _banks.erase(set_iter->first); } return true; @@ -305,8 +303,8 @@ DSSIPlugin::update_programs(bool send_events) void DSSIPlugin::set_default_program() { - map<int, Bank>::const_iterator iter = m_banks.begin(); - if (iter != m_banks.end()) { + map<int, Bank>::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); @@ -317,7 +315,7 @@ DSSIPlugin::set_default_program() const map<int, DSSIPlugin::Bank>& DSSIPlugin::get_programs() const { - return m_banks; + return _banks; } diff --git a/src/libs/engine/DSSIPlugin.h b/src/libs/engine/DSSIPlugin.h index d546a8fe..30afd9d2 100644 --- a/src/libs/engine/DSSIPlugin.h +++ b/src/libs/engine/DSSIPlugin.h @@ -61,8 +61,8 @@ public: //void send_creation_messages(ClientInterface* client) const; - const Plugin* plugin() const { return m_plugin; } - void plugin(const Plugin* const pi) { m_plugin = pi; } + const Plugin* plugin() const { return _plugin; } + void plugin(const Plugin* const pi) { _plugin = pi; } private: // Prevent copies (undefined) @@ -83,22 +83,22 @@ private: void convert_events(); - DSSI_Descriptor* m_dssi_descriptor; + DSSI_Descriptor* _dssi_descriptor; - string m_ui_url; - string m_ui_base_path; - lo_address m_ui_addr; + string _ui_url; + string _ui_base_path; + lo_address _ui_addr; // Current values - int m_bank; - int m_program; - map<string, string> m_configures; - map<int, Bank> m_banks; - - InputPort<MidiMessage>* m_midi_in_port; - snd_seq_event_t* m_alsa_events; - unsigned long m_encoded_events; - snd_midi_event_t* m_alsa_encoder; + int _bank; + int _program; + map<string, string> _configures; + map<int, Bank> _banks; + + InputPort<MidiMessage>* _midi_in_port; + snd_seq_event_t* _alsa_events; + unsigned long _encoded_events; + snd_midi_event_t* _alsa_encoder; }; diff --git a/src/libs/engine/DataType.h b/src/libs/engine/DataType.h new file mode 100644 index 00000000..acb6990b --- /dev/null +++ b/src/libs/engine/DataType.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 DATATYPE_H +#define DATATYPE_H + +namespace Om +{ + + +/** A data type that can be stored in a Port. + * + * Eventually the goal is to be able to just have to create a new one of these + * to have Om support a new data type. + */ +class DataType { +public: + + enum Symbol { + UNKNOWN = 0, + FLOAT = 1, + MIDI = 2 + }; + + DataType(const string& uri) + : _symbol(UNKNOWN) + { + if (uri== type_uris[MIDI]) { + _symbol = MIDI; + } else if (uri == type_uris[FLOAT]) { + _symbol = FLOAT; + } + } + + DataType(Symbol symbol) + : _symbol(symbol) + {} + + const char* const uri() const { return type_uris[_symbol]; } + + inline bool operator==(const Symbol& symbol) const { return (_symbol == symbol); } + inline bool operator!=(const Symbol& symbol) const { return (_symbol != symbol); } + inline bool operator==(const DataType& type) const { return (_symbol == type._symbol); } + inline bool operator!=(const DataType& type) const { return (_symbol != type._symbol); } +private: + Symbol _symbol; + + // Defined in Port.cpp for no good reason + static const char* const type_uris[3]; +}; + + + +} // namespace Om + +#endif // DATATYPE_H diff --git a/src/libs/engine/InputPort.cpp b/src/libs/engine/InputPort.cpp index 3837da1b..4392277a 100644 --- a/src/libs/engine/InputPort.cpp +++ b/src/libs/engine/InputPort.cpp @@ -20,7 +20,6 @@ #include <cassert> #include "ConnectionBase.h" #include "OutputPort.h" -#include "PortInfo.h" #include "Node.h" #include "Om.h" #include "util.h" @@ -32,13 +31,12 @@ namespace Om { template <typename T> -InputPort<T>::InputPort(Node* node, const string& name, size_t index, size_t poly, PortInfo* port_info, size_t buffer_size) -: PortBase<T>(node, name, index, poly, port_info, buffer_size) +InputPort<T>::InputPort(Node* parent, const string& name, size_t index, size_t poly, DataType type, size_t buffer_size) +: PortBase<T>(parent, name, index, poly, type, buffer_size) { - assert(port_info->is_input() && !port_info->is_output()); } -template InputPort<sample>::InputPort(Node* node, const string& name, size_t index, size_t poly, PortInfo* port_info, size_t buffer_size); -template InputPort<MidiMessage>::InputPort(Node* node, const string& name, size_t index, size_t poly, PortInfo* port_info, size_t buffer_size); +template InputPort<sample>::InputPort(Node* parent, const string& name, size_t index, size_t poly, DataType type, size_t buffer_size); +template InputPort<MidiMessage>::InputPort(Node* parent, const string& name, size_t index, size_t poly, DataType type, size_t buffer_size); /** Add a connection. Realtime safe. @@ -59,7 +57,7 @@ InputPort<T>::add_connection(ListNode<ConnectionBase<T>*>* const c) if (modify_buffers) { if (m_connections.size() == 1) { // Use buffer directly to avoid copying - for (size_t i=0; i < m_poly; ++i) { + for (size_t i=0; i < _poly; ++i) { m_buffers.at(i)->join(c->elem()->buffer(i)); if (m_is_tied) m_tied_port->buffer(i)->join(m_buffers.at(i)); @@ -68,7 +66,7 @@ InputPort<T>::add_connection(ListNode<ConnectionBase<T>*>* const c) } else if (m_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 (size_t i=0; i < m_poly; ++i) { + for (size_t i=0; i < _poly; ++i) { m_buffers.at(i)->unjoin(); if (m_is_tied) m_tied_port->buffer(i)->join(m_buffers.at(i)); @@ -109,7 +107,7 @@ InputPort<T>::remove_connection(const OutputPort<T>* const src_port) exit(EXIT_FAILURE); } else { if (m_connections.size() == 0) { - for (size_t i=0; i < m_poly; ++i) { + for (size_t i=0; i < _poly; ++i) { // Use a local buffer if (modify_buffers && m_buffers.at(i)->is_joined()) m_buffers.at(i)->unjoin(); @@ -119,7 +117,7 @@ InputPort<T>::remove_connection(const OutputPort<T>* const src_port) } } else if (modify_buffers && m_connections.size() == 1) { // Share a buffer - for (size_t i=0; i < m_poly; ++i) { + for (size_t i=0; i < _poly; ++i) { m_buffers.at(i)->join((*m_connections.begin())->buffer(i)); if (m_is_tied) m_tied_port->buffer(i)->join(m_buffers.at(i)); @@ -150,8 +148,8 @@ template <typename T> void InputPort<T>::update_buffers() { - for (size_t i=0; i < m_poly; ++i) - InputPort<T>::parent_node()->set_port_buffer(i, m_index, m_buffers.at(i)->data()); + for (size_t i=0; i < _poly; ++i) + InputPort<T>::parent_node()->set_port_buffer(i, _index, m_buffers.at(i)->data()); } template void InputPort<sample>::update_buffers(); template void InputPort<MidiMessage>::update_buffers(); @@ -189,9 +187,9 @@ InputPort<T>::tie(OutputPort<T>* const port) assert(m_tied_port == NULL); if (Port::parent_node() != NULL) { - assert(m_poly == port->poly()); + assert(_poly == port->poly()); - for (size_t i=0; i < m_poly; ++i) + for (size_t i=0; i < _poly; ++i) port->buffer(i)->join(m_buffers.at(i)); } m_is_tied = true; @@ -250,8 +248,8 @@ InputPort<sample>::prepare_buffers(size_t nframes) assert(!m_is_tied || m_tied_port != NULL); assert(!m_is_tied || m_buffers.at(0)->data() == m_tied_port->buffer(0)->data()); - for (size_t voice=0; voice < m_poly; ++voice) { - m_buffers.at(voice)->copy((*m_connections.begin())->buffer(voice), 0, m_buffer_size-1); + for (size_t voice=0; voice < _poly; ++voice) { + m_buffers.at(voice)->copy((*m_connections.begin())->buffer(voice), 0, _buffer_size-1); if (m_connections.size() > 1) { // Copy first connection @@ -259,7 +257,7 @@ InputPort<sample>::prepare_buffers(size_t nframes) // Add all other connections for (++c; c != m_connections.end(); ++c) - m_buffers.at(voice)->accumulate((*c)->buffer(voice), 0, m_buffer_size-1); + m_buffers.at(voice)->accumulate((*c)->buffer(voice), 0, _buffer_size-1); } } } @@ -281,7 +279,7 @@ InputPort<MidiMessage>::prepare_buffers(size_t nframes) assert(num_ins == 0 || num_ins == 1); typedef List<ConnectionBase<MidiMessage>*>::iterator ConnectionBaseListIterator; - assert(m_poly == 1); + assert(_poly == 1); for (ConnectionBaseListIterator c = m_connections.begin(); c != m_connections.end(); ++c) (*c)->prepare_buffers(); @@ -315,7 +313,7 @@ InputPort<MidiMessage>::prepare_buffers(size_t nframes) // Get valid buffer size from inbound connections, unless a port on a top-level // patch (which will be fed by the MidiDriver) - if (m_parent->parent() != NULL) { + if (_parent->parent() != NULL) { if (num_ins == 1) { m_buffers.at(0)->filled_size( (*m_connections.begin())->src_port()->buffer(0)->filled_size()); diff --git a/src/libs/engine/InputPort.h b/src/libs/engine/InputPort.h index 0e5d9d68..79f03329 100644 --- a/src/libs/engine/InputPort.h +++ b/src/libs/engine/InputPort.h @@ -47,12 +47,14 @@ template <typename T> class InputPort : public PortBase<T> { public: - InputPort(Node* node, const string& name, size_t index, size_t poly, PortInfo* port_info, size_t buffer_size); + InputPort(Node* parent, const string& name, size_t index, size_t poly, DataType type, size_t buffer_size); virtual ~InputPort() {} void add_connection(ListNode<ConnectionBase<T>*>* const c); ListNode<ConnectionBase<T>*>* remove_connection(const OutputPort<T>* const src_port); + const List<ConnectionBase<T>*>& connections() { return m_connections; } + void prepare_buffers(size_t nframes); void tie(OutputPort<T>* const port); @@ -60,6 +62,9 @@ public: bool is_connected() const { return (m_connections.size() > 0); } bool is_connected_to(const OutputPort<T>* const port) const; + bool is_input() const { return true; } + bool is_output() const { return false; } + private: // Prevent copies (Undefined) InputPort<T>(const InputPort<T>& copy); @@ -73,9 +78,9 @@ private: using PortBase<T>::m_is_tied; using PortBase<T>::m_tied_port; using PortBase<T>::m_buffers; - using PortBase<T>::m_poly; - using PortBase<T>::m_index; - using PortBase<T>::m_buffer_size; + using PortBase<T>::_poly; + using PortBase<T>::_index; + using PortBase<T>::_buffer_size; using PortBase<T>::m_fixed_buffers; }; diff --git a/src/libs/engine/InternalNode.h b/src/libs/engine/InternalNode.h index fea2d3ad..14a4bc95 100644 --- a/src/libs/engine/InternalNode.h +++ b/src/libs/engine/InternalNode.h @@ -35,24 +35,24 @@ 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), - m_is_added(false) + _is_added(false) { - m_plugin.lib_path("/Om"); + _plugin.lib_path("/Om"); } virtual ~InternalNode() {} - virtual void deactivate() { if (m_is_added) remove_from_patch(); NodeBase::deactivate(); } + virtual void deactivate() { if (_is_added) remove_from_patch(); NodeBase::deactivate(); } virtual void run(size_t nframes) { NodeBase::run(nframes); } - virtual void add_to_patch() { assert(!m_is_added); m_is_added = true; } - virtual void remove_from_patch() { assert(m_is_added); m_is_added = false; } + virtual void add_to_patch() { assert(!_is_added); _is_added = true; } + virtual void remove_from_patch() { assert(_is_added); _is_added = false; } //virtual void send_creation_messages(ClientInterface* client) const //{ NodeBase::send_creation_messages(client); } - virtual const Plugin* plugin() const { return &m_plugin; } + virtual const Plugin* plugin() const { return &_plugin; } virtual void plugin(const Plugin* const) { exit(EXIT_FAILURE); } protected: @@ -60,8 +60,8 @@ protected: InternalNode(const InternalNode&); InternalNode& operator=(const InternalNode&); - Plugin m_plugin; - bool m_is_added; + Plugin _plugin; + bool _is_added; }; diff --git a/src/libs/engine/JackAudioDriver.cpp b/src/libs/engine/JackAudioDriver.cpp index 0f5e3b1a..5f871ef7 100644 --- a/src/libs/engine/JackAudioDriver.cpp +++ b/src/libs/engine/JackAudioDriver.cpp @@ -30,7 +30,6 @@ #include "Node.h" #include "Patch.h" #include "Port.h" -#include "PortInfo.h" #include "MidiDriver.h" #include "List.h" #include "PortBase.h" @@ -59,7 +58,7 @@ JackAudioPort::JackAudioPort(JackAudioDriver* driver, PortBase<sample>* patch_po m_jack_port = jack_port_register(m_driver->jack_client(), patch_port->path().c_str(), JACK_DEFAULT_AUDIO_TYPE, - (patch_port->port_info()->is_input()) ? JackPortIsInput : JackPortIsOutput, + (patch_port->is_input()) ? JackPortIsInput : JackPortIsOutput, 0); m_jack_buffer = new DriverBuffer<jack_sample_t>(driver->buffer_size()); diff --git a/src/libs/engine/JackMidiDriver.cpp b/src/libs/engine/JackMidiDriver.cpp index 40054b8a..79f7005b 100644 --- a/src/libs/engine/JackMidiDriver.cpp +++ b/src/libs/engine/JackMidiDriver.cpp @@ -25,8 +25,6 @@ #include "OmApp.h" #include "Maid.h" #include "AudioDriver.h" -#include "MidiInputNode.h" -#include "PortInfo.h" #include "MidiMessage.h" #include "PortBase.h" #ifdef HAVE_LASH @@ -50,7 +48,7 @@ JackMidiPort::JackMidiPort(JackMidiDriver* driver, PortBase<MidiMessage>* patch_ m_jack_port = jack_port_register(m_driver->jack_client(), patch_port->path().c_str(), JACK_DEFAULT_MIDI_TYPE, - (patch_port->port_info()->is_input()) ? JackPortIsInput : JackPortIsOutput, + (patch_port->is_input()) ? JackPortIsInput : JackPortIsOutput, 0); patch_port->buffer(0)->clear(); @@ -180,7 +178,7 @@ JackMidiDriver::prepare_block(const samplecount block_start, const samplecount b void JackMidiDriver::add_port(JackMidiPort* port) { - if (port->patch_port()->port_info()->is_input()) + if (port->patch_port()->is_input()) m_in_ports.push_back(port); else m_out_ports.push_back(port); @@ -198,7 +196,7 @@ JackMidiDriver::add_port(JackMidiPort* port) JackMidiPort* JackMidiDriver::remove_port(JackMidiPort* port) { - if (port->patch_port()->port_info()->is_input()) { + if (port->patch_port()->is_input()) { for (List<JackMidiPort*>::iterator i = m_in_ports.begin(); i != m_in_ports.end(); ++i) if ((*i) == (JackMidiPort*)port) return m_in_ports.remove(i)->elem(); diff --git a/src/libs/engine/LADSPAPlugin.cpp b/src/libs/engine/LADSPAPlugin.cpp index ddeb0be4..1c2b397e 100644 --- a/src/libs/engine/LADSPAPlugin.cpp +++ b/src/libs/engine/LADSPAPlugin.cpp @@ -23,7 +23,6 @@ #include <cmath> #include "InputPort.h" #include "OutputPort.h" -#include "PortInfo.h" #include "Plugin.h" namespace Om { @@ -36,14 +35,14 @@ namespace Om { */ 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), - m_descriptor(descriptor), - m_instances(NULL) + _descriptor(descriptor), + _instances(NULL) { - assert(m_descriptor != NULL); + assert(_descriptor != NULL); // Note that this may be changed by an overriding DSSIPlugin - // ie do not assume m_ports is all LADSPA plugin ports - m_num_ports = m_descriptor->PortCount; + // ie do not assume _ports is all LADSPA plugin ports + _num_ports = _descriptor->PortCount; } @@ -58,15 +57,15 @@ LADSPAPlugin::LADSPAPlugin(const string& path, size_t poly, Patch* parent, const bool LADSPAPlugin::instantiate() { - m_ports.alloc(m_num_ports); + _ports = new Array<Port*>(_num_ports); - m_instances = new LADSPA_Handle[m_poly]; + _instances = new LADSPA_Handle[_poly]; size_t port_buffer_size = 0; - for (size_t i=0; i < m_poly; ++i) { - m_instances[i] = m_descriptor->instantiate(m_descriptor, m_srate); - if (m_instances[i] == NULL) { + 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; } @@ -77,15 +76,15 @@ LADSPAPlugin::instantiate() Port* port = NULL; - for (size_t j=0; j < m_descriptor->PortCount; ++j) { - port_name = m_descriptor->PortNames[j]; + 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 < m_descriptor->PortCount; ++k) { - assert(m_descriptor->PortNames[k] != NULL); - if (k != j && port_name == m_descriptor->PortNames[k]) { // clash - if (LADSPA_IS_PORT_CONTROL(m_descriptor->PortDescriptors[j])) + 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)"; @@ -97,34 +96,32 @@ LADSPAPlugin::instantiate() port_path = path() + "/" + port_name; - if (LADSPA_IS_PORT_CONTROL(m_descriptor->PortDescriptors[j])) + if (LADSPA_IS_PORT_CONTROL(_descriptor->PortDescriptors[j])) port_buffer_size = 1; - else if (LADSPA_IS_PORT_AUDIO(m_descriptor->PortDescriptors[j])) - port_buffer_size = m_buffer_size; + else if (LADSPA_IS_PORT_AUDIO(_descriptor->PortDescriptors[j])) + port_buffer_size = _buffer_size; - assert (LADSPA_IS_PORT_INPUT(m_descriptor->PortDescriptors[j]) - || LADSPA_IS_PORT_OUTPUT(m_descriptor->PortDescriptors[j])); - - if (LADSPA_IS_PORT_INPUT(m_descriptor->PortDescriptors[j])) { - port = new InputPort<sample>(this, port_name, j, m_poly, - new PortInfo(port_path, m_descriptor->PortDescriptors[j], - m_descriptor->PortRangeHints[j].HintDescriptor), port_buffer_size); - m_ports.at(j) = port; - } else if (LADSPA_IS_PORT_OUTPUT(m_descriptor->PortDescriptors[j])) { - port = new OutputPort<sample>(this, port_name, j, m_poly, - new PortInfo(port_path, m_descriptor->PortDescriptors[j], - m_descriptor->PortRangeHints[j].HintDescriptor), port_buffer_size); - m_ports.at(j) = port; + 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<sample>(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<sample>(this, port_name, j, _poly, DataType::FLOAT, port_buffer_size); + _ports->at(j) = port; } - assert(m_ports.at(j) != NULL); + assert(_ports->at(j) != NULL); - PortInfo* pi = port->port_info(); + /*PortInfo* pi = port->port_info(); get_port_vals(j, pi); + */ + float default_val = 0.; // FIXME // Set default control val - if (pi->is_control()) - ((PortBase<sample>*)port)->set_value(pi->default_val(), 0); + if (port->buffer_size() == 1) + ((PortBase<sample>*)port)->set_value(default_val, 0); else ((PortBase<sample>*)port)->set_value(0.0f, 0); } @@ -135,10 +132,10 @@ LADSPAPlugin::instantiate() LADSPAPlugin::~LADSPAPlugin() { - for (size_t i=0; i < m_poly; ++i) - m_descriptor->cleanup(m_instances[i]); + for (size_t i=0; i < _poly; ++i) + _descriptor->cleanup(_instances[i]); - delete[] m_instances; + delete[] _instances; } @@ -149,17 +146,17 @@ LADSPAPlugin::activate() PortBase<sample>* port = NULL; - for (size_t i=0; i < m_poly; ++i) { - for (unsigned long j=0; j < m_descriptor->PortCount; ++j) { - port = static_cast<PortBase<sample>*>(m_ports.at(j)); - set_port_buffer(i, j, ((PortBase<sample>*)m_ports.at(j))->buffer(i)->data()); - if (port->port_info()->is_control()) - port->set_value(port->port_info()->default_val(), 0); - else if (port->port_info()->is_audio()) + for (size_t i=0; i < _poly; ++i) { + for (unsigned long j=0; j < _descriptor->PortCount; ++j) { + port = static_cast<PortBase<sample>*>(_ports->at(j)); + set_port_buffer(i, j, ((PortBase<sample>*)_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 (m_descriptor->activate != NULL) - m_descriptor->activate(m_instances[i]); + if (_descriptor->activate != NULL) + _descriptor->activate(_instances[i]); } } @@ -169,9 +166,9 @@ LADSPAPlugin::deactivate() { NodeBase::deactivate(); - for (size_t i=0; i < m_poly; ++i) - if (m_descriptor->deactivate != NULL) - m_descriptor->deactivate(m_instances[i]); + for (size_t i=0; i < _poly; ++i) + if (_descriptor->deactivate != NULL) + _descriptor->deactivate(_instances[i]); } @@ -179,23 +176,23 @@ void LADSPAPlugin::run(size_t nframes) { NodeBase::run(nframes); // mixes down input ports - for (size_t i=0; i < m_poly; ++i) - m_descriptor->run(m_instances[i], nframes); + 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 < m_poly); + assert(voice < _poly); // Could be a MIDI port after this - if (port_num < m_descriptor->PortCount) { - m_descriptor->connect_port(m_instances[voice], port_num, (sample*)buf); + 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) @@ -203,15 +200,15 @@ 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 = m_descriptor->PortRangeHints[port_index].HintDescriptor; + 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 = m_descriptor->PortRangeHints[port_index].UpperBound * m_srate; - lower = m_descriptor->PortRangeHints[port_index].LowerBound * m_srate; + upper = _descriptor->PortRangeHints[port_index].UpperBound * _srate; + lower = _descriptor->PortRangeHints[port_index].LowerBound * _srate; } else { - upper = m_descriptor->PortRangeHints[port_index].UpperBound; - lower = m_descriptor->PortRangeHints[port_index].LowerBound; + upper = _descriptor->PortRangeHints[port_index].UpperBound; + lower = _descriptor->PortRangeHints[port_index].LowerBound; } if (LADSPA_IS_HINT_LOGARITHMIC(hint_descriptor)) { @@ -268,7 +265,7 @@ LADSPAPlugin::get_port_vals(ulong port_index, PortInfo* info) 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 index dc1ba5e1..e91b6a36 100644 --- a/src/libs/engine/LADSPAPlugin.h +++ b/src/libs/engine/LADSPAPlugin.h @@ -25,8 +25,6 @@ namespace Om { -class PortInfo; - /** An instance of a LADSPA plugin. * @@ -47,20 +45,20 @@ public: void set_port_buffer(size_t voice, size_t port_num, void* buf); - const Plugin* plugin() const { return m_plugin; } - void plugin(const Plugin* const pi) { m_plugin = pi; } + 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); + //void get_port_vals(ulong port_index, PortInfo* info); - const LADSPA_Descriptor* m_descriptor; - LADSPA_Handle* m_instances; + const LADSPA_Descriptor* _descriptor; + LADSPA_Handle* _instances; - const Plugin* m_plugin; + const Plugin* _plugin; }; diff --git a/src/libs/engine/LV2Plugin.cpp b/src/libs/engine/LV2Plugin.cpp index 4cb7348d..660bf962 100644 --- a/src/libs/engine/LV2Plugin.cpp +++ b/src/libs/engine/LV2Plugin.cpp @@ -22,7 +22,6 @@ #include <cmath> #include "InputPort.h" #include "OutputPort.h" -#include "PortInfo.h" #include "Plugin.h" namespace Om { @@ -40,14 +39,14 @@ LV2Plugin::LV2Plugin(const string& name, samplerate srate, size_t buffer_size) : NodeBase(name, poly, parent, srate, buffer_size), - m_lv2_plugin(plugin), - m_instances(NULL) + _lv2_plugin(plugin), + _instances(NULL) { - assert(m_lv2_plugin); + assert(_lv2_plugin); // Note that this may be changed by an overriding DSSIPlugin - // ie do not assume m_ports is all LV2 plugin ports - m_num_ports = slv2_plugin_get_num_ports(m_lv2_plugin); + // ie do not assume _ports is all LV2 plugin ports + _num_ports = slv2_plugin_get_num_ports(_lv2_plugin); } @@ -62,15 +61,15 @@ LV2Plugin::LV2Plugin(const string& name, bool LV2Plugin::instantiate() { - m_ports.alloc(m_num_ports); + _ports->alloc(_num_ports); - m_instances = new SLV2Instance*[m_poly]; + _instances = new SLV2Instance*[_poly]; size_t port_buffer_size = 0; - for (size_t i=0; i < m_poly; ++i) { - m_instances[i] = slv2_plugin_instantiate(m_lv2_plugin, m_srate, NULL); - if (m_instances[i] == NULL) { + 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; } @@ -81,9 +80,9 @@ LV2Plugin::instantiate() Port* port = NULL; - for (size_t j=0; j < m_num_ports; ++j) { + 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(m_lv2_plugin, j); + port_name = (char*)slv2_port_get_symbol(_lv2_plugin, j); assert(port_name.find("/") == string::npos); @@ -91,7 +90,7 @@ LV2Plugin::instantiate() // Assumes there is only the 4 classes - SLV2PortClass port_class = slv2_port_get_class(m_lv2_plugin, j); + 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 @@ -100,31 +99,26 @@ LV2Plugin::instantiate() if (is_control) port_buffer_size = 1; else - port_buffer_size = m_buffer_size; - - PortType type = is_control ? CONTROL : AUDIO; - PortDirection direction = is_input ? INPUT : OUTPUT; + port_buffer_size = _buffer_size; if (is_input) { - port = new InputPort<sample>(this, port_name, j, m_poly, - new PortInfo(port_path, type, direction), port_buffer_size); - m_ports.at(j) = port; + port = new InputPort<sample>(this, port_name, j, _poly, DataType::FLOAT, port_buffer_size); + _ports->at(j) = port; } else /* output */ { - port = new OutputPort<sample>(this, port_name, j, m_poly, - new PortInfo(port_path, type, direction), port_buffer_size); - m_ports.at(j) = port; + port = new OutputPort<sample>(this, port_name, j, _poly, DataType::FLOAT, port_buffer_size); + _ports->at(j) = port; } - assert(m_ports.at(j) != NULL); + assert(_ports->at(j) != NULL); - PortInfo* pi = port->port_info(); - get_port_vals(j, pi); + //PortInfo* pi = port->port_info(); + //get_port_vals(j, pi); // Set default control val - if (pi->is_control()) + /*if (pi->is_control()) ((PortBase<sample>*)port)->set_value(pi->default_val(), 0); else - ((PortBase<sample>*)port)->set_value(0.0f, 0); + ((PortBase<sample>*)port)->set_value(0.0f, 0);*/ } return true; } @@ -132,10 +126,10 @@ LV2Plugin::instantiate() LV2Plugin::~LV2Plugin() { - for (size_t i=0; i < m_poly; ++i) - slv2_instance_free(m_instances[i]); + for (size_t i=0; i < _poly; ++i) + slv2_instance_free(_instances[i]); - delete[] m_instances; + delete[] _instances; } @@ -146,16 +140,16 @@ LV2Plugin::activate() PortBase<sample>* port = NULL; - for (size_t i=0; i < m_poly; ++i) { - for (unsigned long j=0; j < m_num_ports; ++j) { - port = static_cast<PortBase<sample>*>(m_ports.at(j)); - set_port_buffer(i, j, ((PortBase<sample>*)m_ports.at(j))->buffer(i)->data()); - if (port->port_info()->is_control()) - port->set_value(port->port_info()->default_val(), 0); - else if (port->port_info()->is_audio()) - port->set_value(0.0f, 0); + for (size_t i=0; i < _poly; ++i) { + for (unsigned long j=0; j < _num_ports; ++j) { + port = static_cast<PortBase<sample>*>(_ports->at(j)); + set_port_buffer(i, j, ((PortBase<sample>*)_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(m_instances[i]); + slv2_instance_activate(_instances[i]); } } @@ -165,8 +159,8 @@ LV2Plugin::deactivate() { NodeBase::deactivate(); - for (size_t i=0; i < m_poly; ++i) - slv2_instance_deactivate(m_instances[i]); + for (size_t i=0; i < _poly; ++i) + slv2_instance_deactivate(_instances[i]); } @@ -174,40 +168,40 @@ void LV2Plugin::run(size_t nframes) { NodeBase::run(nframes); // mixes down input ports - for (size_t i=0; i < m_poly; ++i) - slv2_instance_run(m_instances[i], nframes); + 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 < m_poly); + assert(voice < _poly); // Could be a MIDI port after this - if (port_num < m_num_ports) { - slv2_instance_connect_port(m_instances[voice], port_num, buf); + 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) { -#if 0 LV2_Data upper = 0.0f; LV2_Data lower = 0.0f; LV2_Data normal = 0.0f; - LV2_PortRangeHintDescriptor hint_descriptor = m_descriptor->PortRangeHints[port_index].HintDescriptor; + 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 = m_descriptor->PortRangeHints[port_index].UpperBound * m_srate; - lower = m_descriptor->PortRangeHints[port_index].LowerBound * m_srate; + upper = _descriptor->PortRangeHints[port_index].UpperBound * _srate; + lower = _descriptor->PortRangeHints[port_index].LowerBound * _srate; } else { - upper = m_descriptor->PortRangeHints[port_index].UpperBound; - lower = m_descriptor->PortRangeHints[port_index].LowerBound; + upper = _descriptor->PortRangeHints[port_index].UpperBound; + lower = _descriptor->PortRangeHints[port_index].LowerBound; } if (LV2_IS_HINT_LOGARITHMIC(hint_descriptor)) { @@ -263,8 +257,8 @@ LV2Plugin::get_port_vals(ulong port_index, PortInfo* info) info->min_val(lower); info->default_val(normal); info->max_val(upper); -#endif } +#endif } // namespace Om diff --git a/src/libs/engine/LV2Plugin.h b/src/libs/engine/LV2Plugin.h index c3d3038a..5e19b6c4 100644 --- a/src/libs/engine/LV2Plugin.h +++ b/src/libs/engine/LV2Plugin.h @@ -25,8 +25,6 @@ namespace Om { -class PortInfo; - /** An instance of a LV2 plugin. * @@ -53,20 +51,20 @@ public: void set_port_buffer(size_t voice, size_t port_num, void* buf); - const Plugin* plugin() const { return m_om_plugin; } - void plugin(const Plugin* const p) { m_om_plugin = p; } + 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); + //void get_port_vals(ulong port_index, PortInfo* info); - const SLV2Plugin* m_lv2_plugin; - SLV2Instance** m_instances; + const SLV2Plugin* _lv2_plugin; + SLV2Instance** _instances; - const Plugin* m_om_plugin; + const Plugin* _om_plugin; }; diff --git a/src/libs/engine/Makefile.am b/src/libs/engine/Makefile.am index 6f0c023d..8a01b21e 100644 --- a/src/libs/engine/Makefile.am +++ b/src/libs/engine/Makefile.am @@ -10,6 +10,7 @@ noinst_LTLIBRARIES = libom.la libom_la_SOURCES = \ util.h \ tuning.h \ + DataType.h \ Node.h \ NodeBase.h \ NodeBase.cpp \ @@ -53,20 +54,6 @@ libom_la_SOURCES = \ MidiTriggerNode.cpp \ MidiControlNode.h \ MidiControlNode.cpp \ - BridgeNode.h \ - BridgeNode.cpp \ - ControlInputNode.h \ - ControlInputNode.cpp \ - ControlOutputNode.h \ - ControlOutputNode.cpp \ - AudioInputNode.h \ - AudioInputNode.cpp \ - AudioOutputNode.h \ - AudioOutputNode.cpp \ - MidiInputNode.h \ - MidiInputNode.cpp \ - MidiOutputNode.h \ - MidiOutputNode.cpp \ Event.h \ Event.cpp \ QueuedEvent.h \ @@ -81,7 +68,6 @@ libom_la_SOURCES = \ MaidObject.h \ Tree.h \ ClientRecord.h \ - PortInfo.h \ PluginLibrary.h \ Plugin.h \ Array.h \ @@ -136,6 +122,8 @@ libom_la_SOURCES = \ events/DisconnectPortEvent.cpp \ events/DestroyEvent.h \ events/DestroyEvent.cpp \ + events/AddPortEvent.h \ + events/AddPortEvent.cpp \ events/AddNodeEvent.h \ events/AddNodeEvent.cpp \ events/SetMetadataEvent.h \ @@ -161,7 +149,22 @@ libom_la_SOURCES = \ events/RenameEvent.h \ events/RenameEvent.cpp \ events/MidiLearnEvent.h \ - events/MidiLearnEvent.cpp + events/MidiLearnEvent.cpp \ + types.h +# BridgeNode.h +# BridgeNode.cpp +# ControlInputNode.h +# ControlInputNode.cpp +# ControlOutputNode.h +# ControlOutputNode.cpp +# AudioInputNode.h +# AudioInputNode.cpp +# AudioOutputNode.h +# AudioOutputNode.cpp +# MidiInputNode.h +# MidiInputNode.cpp +# MidiOutputNode.h +# MidiOutputNode.cpp if WITH_JACK_MIDI libom_la_SOURCES += \ diff --git a/src/libs/engine/MidiControlNode.cpp b/src/libs/engine/MidiControlNode.cpp index 2116c828..0ce45136 100644 --- a/src/libs/engine/MidiControlNode.cpp +++ b/src/libs/engine/MidiControlNode.cpp @@ -22,7 +22,6 @@ #include "MidiLearnEvent.h" #include "InputPort.h" #include "OutputPort.h" -#include "PortInfo.h" #include "Plugin.h" #include "util.h" #include "midi.h" @@ -33,41 +32,35 @@ 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), - m_learning(false) + _learning(false) { - m_num_ports = 7; - m_ports.alloc(m_num_ports); + _num_ports = 7; + _ports = new Array<Port*>(_num_ports); - m_midi_in_port = new InputPort<MidiMessage>(this, "MIDI In", 0, 1, - new PortInfo("MIDI In", MIDI, INPUT), m_buffer_size); - m_ports.at(0) = m_midi_in_port; + _midi_in_port = new InputPort<MidiMessage>(this, "MIDI In", 0, 1, DataType::MIDI, _buffer_size); + _ports->at(0) = _midi_in_port; - m_param_port = new InputPort<sample>(this, "Controller Number", 1, 1, - new PortInfo("Controller Number", CONTROL, INPUT, INTEGER, 60, 0, 127), 1); - m_ports.at(1) = m_param_port; - m_log_port = new InputPort<sample>(this, "Logarithmic", 2, 1, - new PortInfo("Logarithmic", CONTROL, INPUT, TOGGLE, 0, 0, 1), 1); - m_ports.at(2) = m_log_port; + _param_port = new InputPort<sample>(this, "Controller Number", 1, 1, DataType::FLOAT, 1); + _ports->at(1) = _param_port; + + _log_port = new InputPort<sample>(this, "Logarithmic", 2, 1, DataType::FLOAT, 1); + _ports->at(2) = _log_port; - m_min_port = new InputPort<sample>(this, "Min", 3, 1, - new PortInfo("Min", CONTROL, INPUT, NONE, 0, 0, 65535), 1); - m_ports.at(3) = m_min_port; + _min_port = new InputPort<sample>(this, "Min", 3, 1, DataType::FLOAT, 1); + _ports->at(3) = _min_port; - m_max_port = new InputPort<sample>(this, "Max", 4, 1, - new PortInfo("Max", CONTROL, INPUT, NONE, 1, 0, 65535), 1); - m_ports.at(4) = m_max_port; + _max_port = new InputPort<sample>(this, "Max", 4, 1, DataType::FLOAT, 1); + _ports->at(4) = _max_port; - m_audio_port = new OutputPort<sample>(this, "Out (AR)", 5, 1, - new PortInfo("Out (AR)", AUDIO, OUTPUT, 0, 0, 1), m_buffer_size); - m_ports.at(5) = m_audio_port; + _audio_port = new OutputPort<sample>(this, "Out (AR)", 5, 1, DataType::FLOAT, _buffer_size); + _ports->at(5) = _audio_port; - m_control_port = new OutputPort<sample>(this, "Out (CR)", 6, 1, - new PortInfo("Out (CR)", CONTROL, OUTPUT, 0, 0, 1), 1); - m_ports.at(6) = m_control_port; + _control_port = new OutputPort<sample>(this, "Out (CR)", 6, 1, DataType::FLOAT, 1); + _ports->at(6) = _control_port; - m_plugin.type(Plugin::Internal); - m_plugin.plug_label("midi_control_in"); - m_plugin.name("Om Control Node (MIDI)"); + _plugin.type(Plugin::Internal); + _plugin.plug_label("midi_control_in"); + _plugin.name("Om Control Node (MIDI)"); } @@ -78,8 +71,8 @@ MidiControlNode::run(size_t nframes) MidiMessage ev; - for (size_t i=0; i < m_midi_in_port->buffer(0)->filled_size(); ++i) { - ev = m_midi_in_port->buffer(0)->value_at(i); + for (size_t i=0; i < _midi_in_port->buffer(0)->filled_size(); ++i) { + ev = _midi_in_port->buffer(0)->value_at(i); if ((ev.buffer[0] & 0xF0) == MIDI_CMD_CONTROL) control(ev.buffer[1], ev.buffer[2], ev.time); @@ -90,41 +83,41 @@ MidiControlNode::run(size_t nframes) void MidiControlNode::control(uchar control_num, uchar val, samplecount offset) { - assert(offset < m_buffer_size); + assert(offset < _buffer_size); sample scaled_value; const sample nval = (val / 127.0f); // normalized [0, 1] - if (m_learning) { - assert(m_learn_event != NULL); - m_param_port->set_value(control_num, offset); - assert(m_param_port->buffer(0)->value_at(0) == control_num); - m_learn_event->set_value(control_num); - m_learn_event->execute(offset); - om->post_processor()->push(m_learn_event); + if (_learning) { + 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); + om->post_processor()->push(_learn_event); om->post_processor()->signal(); - m_learning = false; - m_learn_event = NULL; + _learning = false; + _learn_event = NULL; } - if (m_log_port->buffer(0)->value_at(0) > 0.0f) { + if (_log_port->buffer(0)->value_at(0) > 0.0f) { // haaaaack, stupid negatives and logarithms sample log_offset = 0; - if (m_min_port->buffer(0)->value_at(0) < 0) - log_offset = fabs(m_min_port->buffer(0)->value_at(0)); - const sample min = log(m_min_port->buffer(0)->value_at(0)+1+log_offset); - const sample max = log(m_max_port->buffer(0)->value_at(0)+1+log_offset); + if (_min_port->buffer(0)->value_at(0) < 0) + log_offset = fabs(_min_port->buffer(0)->value_at(0)); + const sample min = log(_min_port->buffer(0)->value_at(0)+1+log_offset); + const sample max = log(_max_port->buffer(0)->value_at(0)+1+log_offset); scaled_value = expf(nval * (max - min) + min) - 1 - log_offset; } else { - const sample min = m_min_port->buffer(0)->value_at(0); - const sample max = m_max_port->buffer(0)->value_at(0); + const sample min = _min_port->buffer(0)->value_at(0); + const sample max = _max_port->buffer(0)->value_at(0); scaled_value = ((nval) * (max - min)) + min; } - if (control_num == m_param_port->buffer(0)->value_at(0)) { - m_control_port->set_value(scaled_value, offset); - m_audio_port->set_value(scaled_value, offset); + if (control_num == _param_port->buffer(0)->value_at(0)) { + _control_port->set_value(scaled_value, offset); + _audio_port->set_value(scaled_value, offset); } } diff --git a/src/libs/engine/MidiControlNode.h b/src/libs/engine/MidiControlNode.h index b40e7631..763c67e6 100644 --- a/src/libs/engine/MidiControlNode.h +++ b/src/libs/engine/MidiControlNode.h @@ -46,24 +46,24 @@ public: void control(uchar control_num, uchar val, samplecount offset); - void learn(MidiLearnResponseEvent* ev) { m_learning = true; m_learn_event = ev; } + void learn(MidiLearnResponseEvent* ev) { _learning = true; _learn_event = ev; } private: // Disallow copies (undefined) MidiControlNode(const MidiControlNode& copy); MidiControlNode& operator=(const MidiControlNode&); - bool m_learning; + bool _learning; - InputPort<MidiMessage>* m_midi_in_port; - InputPort<sample>* m_param_port; - InputPort<sample>* m_log_port; - InputPort<sample>* m_min_port; - InputPort<sample>* m_max_port; - OutputPort<sample>* m_control_port; - OutputPort<sample>* m_audio_port; + InputPort<MidiMessage>* _midi_in_port; + InputPort<sample>* _param_port; + InputPort<sample>* _log_port; + InputPort<sample>* _min_port; + InputPort<sample>* _max_port; + OutputPort<sample>* _control_port; + OutputPort<sample>* _audio_port; - MidiLearnResponseEvent* m_learn_event; + MidiLearnResponseEvent* _learn_event; }; diff --git a/src/libs/engine/MidiInputNode.cpp b/src/libs/engine/MidiInputNode.cpp deleted file mode 100644 index 25310807..00000000 --- a/src/libs/engine/MidiInputNode.cpp +++ /dev/null @@ -1,49 +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 "MidiInputNode.h" -#include "InputPort.h" -#include "OutputPort.h" -#include "Plugin.h" -#include "PortInfo.h" -#include "Patch.h" -#include "MidiMessage.h" - -namespace Om { - - -MidiInputNode::MidiInputNode(const string& path, size_t poly, Patch* parent, samplerate srate, size_t buffer_size) -: BridgeNode<MidiMessage>(path, 1, parent, srate, buffer_size) -{ - OutputPort<MidiMessage>* internal_port = new OutputPort<MidiMessage>(this, "in", 0, m_poly, - new PortInfo("in", MIDI, OUTPUT), m_buffer_size); - InputPort<MidiMessage>* external_port = new InputPort<MidiMessage>(parent, m_name, 0, m_poly, - new PortInfo(m_name, MIDI, INPUT), m_buffer_size); - external_port->tie(internal_port); - m_external_port = external_port; - - m_num_ports = 1; - m_ports.alloc(m_num_ports); - m_ports.at(0) = internal_port; - - m_plugin.type(Plugin::Internal); - m_plugin.plug_label("midi_input"); - m_plugin.name("Om Patch MIDI Input Node"); -} - - -} // namespace Om - diff --git a/src/libs/engine/MidiInputNode.h b/src/libs/engine/MidiInputNode.h deleted file mode 100644 index 0986a267..00000000 --- a/src/libs/engine/MidiInputNode.h +++ /dev/null @@ -1,43 +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 MIDIINPUTNODE_H -#define MIDIINPUTNODE_H - -#include <string> -#include "BridgeNode.h" - -using std::string; - -namespace Om { - -class MidiMessage; - - -/** MIDI input BridgeNode. - * - * \ingroup engine - */ -class MidiInputNode : public BridgeNode<MidiMessage> -{ -public: - MidiInputNode(const string& path, size_t poly, Patch* parent, samplerate srate, size_t buffer_size); -}; - - -} // namespace Om - -#endif // MIDIINPUTNODE_H diff --git a/src/libs/engine/MidiNoteNode.cpp b/src/libs/engine/MidiNoteNode.cpp index 9dc32f4a..4c0280bd 100644 --- a/src/libs/engine/MidiNoteNode.cpp +++ b/src/libs/engine/MidiNoteNode.cpp @@ -20,7 +20,6 @@ #include "MidiMessage.h" #include "InputPort.h" #include "OutputPort.h" -#include "PortInfo.h" #include "Plugin.h" #include "Array.h" #include "Om.h" @@ -37,41 +36,40 @@ 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), - m_voices(new Voice[poly]), - m_sustain(false) + _voices(new Voice[poly]), + _sustain(false) { - m_num_ports = 5; - m_ports.alloc(m_num_ports); + _num_ports = 5; + _ports = new Array<Port*>(_num_ports); - m_midi_in_port = new InputPort<MidiMessage>(this, "MIDI In", 0, 1, - new PortInfo("MIDI In", MIDI, INPUT), m_buffer_size); - m_ports.at(0) = m_midi_in_port; + _midi_in_port = new InputPort<MidiMessage>(this, "DataType::MIDI In", 0, 1, DataType::MIDI, _buffer_size); + _ports->at(0) = _midi_in_port; - m_freq_port = new OutputPort<sample>(this, "Frequency", 1, poly, - new PortInfo("Frequency", AUDIO, OUTPUT, 440, 0, 99999), m_buffer_size); - m_ports.at(1) = m_freq_port; + _freq_port = new OutputPort<sample>(this, "Frequency", 1, poly, DataType::FLOAT, _buffer_size); + // new PortInfo("Frequency", AUDIO, OUTPUT, 440, 0, 99999), _buffer_size); + _ports->at(1) = _freq_port; - m_vel_port = new OutputPort<sample>(this, "Velocity", 2, poly, - new PortInfo("Velocity", AUDIO, OUTPUT, 0, 0, 1), m_buffer_size); - m_ports.at(2) = m_vel_port; + _vel_port = new OutputPort<sample>(this, "Velocity", 2, poly, DataType::FLOAT, _buffer_size); + // new PortInfo("Velocity", AUDIO, OUTPUT, 0, 0, 1), _buffer_size); + _ports->at(2) = _vel_port; - m_gate_port = new OutputPort<sample>(this, "Gate", 3, poly, - new PortInfo("Gate", AUDIO, OUTPUT, 0, 0, 1), m_buffer_size); - m_ports.at(3) = m_gate_port; + _gate_port = new OutputPort<sample>(this, "Gate", 3, poly, DataType::FLOAT, _buffer_size); + // new PortInfo("Gate", AUDIO, OUTPUT, 0, 0, 1), _buffer_size); + _ports->at(3) = _gate_port; - m_trig_port = new OutputPort<sample>(this, "Trigger", 4, poly, - new PortInfo("Trigger", AUDIO, OUTPUT, 0, 0, 1), m_buffer_size); - m_ports.at(4) = m_trig_port; + _trig_port = new OutputPort<sample>(this, "Trigger", 4, poly, DataType::FLOAT, _buffer_size); + // new PortInfo("Trigger", AUDIO, OUTPUT, 0, 0, 1), _buffer_size); + _ports->at(4) = _trig_port; - m_plugin.type(Plugin::Internal); - m_plugin.plug_label("note_in"); - m_plugin.name("Om Note Node (MIDI, OSC)"); + _plugin.type(Plugin::Internal); + _plugin.plug_label("note_in"); + _plugin.name("Om Note Node (MIDI, OSC)"); } MidiNoteNode::~MidiNoteNode() { - delete[] m_voices; + delete[] _voices; } @@ -82,8 +80,8 @@ MidiNoteNode::run(size_t nframes) MidiMessage ev; - for (size_t i=0; i < m_midi_in_port->buffer(0)->filled_size(); ++i) { - ev = m_midi_in_port->buffer(0)->value_at(i); + for (size_t i=0; i < _midi_in_port->buffer(0)->filled_size(); ++i) { + ev = _midi_in_port->buffer(0)->value_at(i); switch (ev.buffer[0] & 0xF0) { case MIDI_CMD_NOTE_ON: @@ -123,17 +121,17 @@ MidiNoteNode::note_on(uchar note_num, uchar velocity, samplecount offset) { const jack_nframes_t time_stamp = om->audio_driver()->time_stamp(); - assert(offset < m_buffer_size); + assert(offset < _buffer_size); assert(note_num <= 127); - Key* key = &m_keys[note_num]; + Key* key = &_keys[note_num]; Voice* voice = NULL; size_t voice_num = 0; // Look for free voices - for (size_t i=0; i < m_poly; ++i) { - if (m_voices[i].state == Voice::Voice::FREE) { - voice = &m_voices[i]; + for (size_t i=0; i < _poly; ++i) { + if (_voices[i].state == Voice::Voice::FREE) { + voice = &_voices[i]; voice_num = i; break; } @@ -142,26 +140,26 @@ MidiNoteNode::note_on(uchar note_num, uchar velocity, samplecount offset) // If we didn't find a free one, steal the oldest if (voice == NULL) { voice_num = 0; - voice = &m_voices[0]; - jack_nframes_t oldest_time = m_voices[0].time; - for (size_t i=1; i < m_poly; ++i) { - if (m_voices[i].time < oldest_time) { - voice = &m_voices[i]; + voice = &_voices[0]; + jack_nframes_t oldest_time = _voices[0].time; + for (size_t i=1; i < _poly; ++i) { + if (_voices[i].time < oldest_time) { + voice = &_voices[i]; voice_num = i; oldest_time = voice->time; } } } assert(voice != NULL); - assert(voice == &m_voices[voice_num]); + assert(voice == &_voices[voice_num]); //cerr << "[MidiNoteNode] Note on. Key " << (int)note_num << ", Voice " << voice_num << endl; // Update stolen key, if applicable if (voice->state == Voice::Voice::ACTIVE) { - assert(m_keys[voice->note].voice == voice_num); - assert(m_keys[voice->note].state == Key::ON_ASSIGNED); - m_keys[voice->note].state = Key::Key::ON_UNASSIGNED; + assert(_keys[voice->note].voice == voice_num); + assert(_keys[voice->note].state == Key::ON_ASSIGNED); + _keys[voice->note].state = Key::Key::ON_UNASSIGNED; //cerr << "[MidiNoteNode] Stole voice " << voice_num << endl; } @@ -175,45 +173,45 @@ MidiNoteNode::note_on(uchar note_num, uchar velocity, samplecount offset) voice->note = note_num; voice->time = time_stamp; - assert(m_keys[voice->note].state == Key::Key::ON_ASSIGNED); - assert(m_keys[voice->note].voice == voice_num); + assert(_keys[voice->note].state == Key::Key::ON_ASSIGNED); + assert(_keys[voice->note].voice == voice_num); // one-sample jitter hack to avoid having to deal with trigger sample "next time" - if (offset == (samplecount)(m_buffer_size-1)) + if (offset == (samplecount)(_buffer_size-1)) --offset; - m_freq_port->buffer(voice_num)->set(note_to_freq(note_num), offset); - m_vel_port->buffer(voice_num)->set(velocity/127.0, offset); - m_gate_port->buffer(voice_num)->set(1.0f, offset); + _freq_port->buffer(voice_num)->set(note_to_freq(note_num), offset); + _vel_port->buffer(voice_num)->set(velocity/127.0, offset); + _gate_port->buffer(voice_num)->set(1.0f, offset); // trigger (one sample) - m_trig_port->buffer(voice_num)->set(1.0f, offset, offset); - m_trig_port->buffer(voice_num)->set(0.0f, offset+1); + _trig_port->buffer(voice_num)->set(1.0f, offset, offset); + _trig_port->buffer(voice_num)->set(0.0f, offset+1); assert(key->state == Key::Key::ON_ASSIGNED); assert(voice->state == Voice::Voice::ACTIVE); assert(key->voice == voice_num); - assert(m_voices[key->voice].note == note_num); + assert(_voices[key->voice].note == note_num); } void MidiNoteNode::note_off(uchar note_num, samplecount offset) { - assert(offset < m_buffer_size); + assert(offset < _buffer_size); - Key* key = &m_keys[note_num]; + Key* key = &_keys[note_num]; if (key->state == Key::ON_ASSIGNED) { // Assigned key, turn off voice and key - assert(m_voices[key->voice].state == Voice::ACTIVE); - assert(m_voices[key->voice].note == note_num); + assert(_voices[key->voice].state == Voice::ACTIVE); + assert(_voices[key->voice].note == note_num); key->state = Key::OFF; - if ( ! m_sustain) + if ( ! _sustain) free_voice(key->voice, offset); else - m_voices[key->voice].state = Voice::HOLDING; + _voices[key->voice].state = Voice::HOLDING; } key->state = Key::OFF; @@ -228,31 +226,31 @@ MidiNoteNode::free_voice(size_t voice, samplecount offset) uchar replace_key_num = 0; for (uchar i = 0; i <= 127; ++i) { - if (m_keys[i].state == Key::ON_UNASSIGNED) { - if (replace_key == NULL || m_keys[i].time > replace_key->time) { - replace_key = &m_keys[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(&m_keys[replace_key_num] == replace_key); + 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 - m_freq_port->buffer(voice)->set(note_to_freq(replace_key_num), offset); + _freq_port->buffer(voice)->set(note_to_freq(replace_key_num), offset); replace_key->state = Key::ON_ASSIGNED; replace_key->voice = voice; - m_keys[m_voices[voice].note].state = Key::ON_UNASSIGNED; - m_voices[voice].note = replace_key_num; - m_voices[voice].state = Voice::ACTIVE; + _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; - m_gate_port->buffer(voice)->set(0.0f, offset); - m_voices[voice].state = Voice::FREE; + _gate_port->buffer(voice)->set(0.0f, offset); + _voices[voice].state = Voice::FREE; } } @@ -261,13 +259,13 @@ void MidiNoteNode::all_notes_off(samplecount offset) { //cerr << "Note off starting at sample " << offset << endl; - assert(offset < m_buffer_size); + assert(offset < _buffer_size); // FIXME: set all keys to Key::OFF? - for (size_t i=0; i < m_poly; ++i) { - m_gate_port->buffer(i)->set(0.0f, offset); - m_voices[i].state = Voice::FREE; + for (size_t i=0; i < _poly; ++i) { + _gate_port->buffer(i)->set(0.0f, offset); + _voices[i].state = Voice::FREE; } } @@ -285,17 +283,17 @@ MidiNoteNode::note_to_freq(int num) void MidiNoteNode::sustain_on() { - m_sustain = true; + _sustain = true; } void MidiNoteNode::sustain_off(samplecount offset) { - m_sustain = false; + _sustain = false; - for (size_t i=0; i < m_poly; ++i) - if (m_voices[i].state == Voice::HOLDING) + for (size_t i=0; i < _poly; ++i) + if (_voices[i].state == Voice::HOLDING) free_voice(i, offset); } diff --git a/src/libs/engine/MidiNoteNode.h b/src/libs/engine/MidiNoteNode.h index bf302144..aea3656f 100644 --- a/src/libs/engine/MidiNoteNode.h +++ b/src/libs/engine/MidiNoteNode.h @@ -70,15 +70,15 @@ private: float note_to_freq(int num); void free_voice(size_t voice, samplecount offset); - Voice* m_voices; - Key m_keys[128]; - bool m_sustain; ///< Whether or not hold pedal is depressed + Voice* _voices; + Key _keys[128]; + bool _sustain; ///< Whether or not hold pedal is depressed - InputPort<MidiMessage>* m_midi_in_port; - OutputPort<sample>* m_freq_port; - OutputPort<sample>* m_vel_port; - OutputPort<sample>* m_gate_port; - OutputPort<sample>* m_trig_port; + InputPort<MidiMessage>* _midi_in_port; + OutputPort<sample>* _freq_port; + OutputPort<sample>* _vel_port; + OutputPort<sample>* _gate_port; + OutputPort<sample>* _trig_port; }; diff --git a/src/libs/engine/MidiOutputNode.cpp b/src/libs/engine/MidiOutputNode.cpp deleted file mode 100644 index 33023cc6..00000000 --- a/src/libs/engine/MidiOutputNode.cpp +++ /dev/null @@ -1,49 +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 "MidiOutputNode.h" -#include "InputPort.h" -#include "OutputPort.h" -#include "Plugin.h" -#include "PortInfo.h" -#include "Patch.h" -#include "MidiMessage.h" - -namespace Om { - - -MidiOutputNode::MidiOutputNode(const string& path, size_t poly, Patch* parent, samplerate srate, size_t buffer_size) -: BridgeNode<MidiMessage>(path, 1, parent, srate, buffer_size) -{ - OutputPort<MidiMessage>* external_port = new OutputPort<MidiMessage>(parent, m_name, 0, m_poly, - new PortInfo(m_name, MIDI, OUTPUT), m_buffer_size); - InputPort<MidiMessage>* internal_port = new InputPort<MidiMessage>(this, "out", 0, m_poly, - new PortInfo("out", MIDI, INPUT), m_buffer_size); - internal_port->tie(external_port); - m_external_port = external_port; - - m_num_ports = 1; - m_ports.alloc(m_num_ports); - m_ports.at(0) = internal_port; - - m_plugin.type(Plugin::Internal); - m_plugin.plug_label("midi_output"); - m_plugin.name("Om Patch MIDI Output Node"); -} - - -} // namespace Om - diff --git a/src/libs/engine/MidiOutputNode.h b/src/libs/engine/MidiOutputNode.h deleted file mode 100644 index 06d8a892..00000000 --- a/src/libs/engine/MidiOutputNode.h +++ /dev/null @@ -1,43 +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 MIDIOUTPUTNODE_H -#define MIDIOUTPUTNODE_H - -#include <string> -#include "BridgeNode.h" - -using std::string; - -namespace Om { - -class MidiMessage; - - -/** MIDI output BridgeNode. - * - * \ingroup engine - */ -class MidiOutputNode : public BridgeNode<MidiMessage> -{ -public: - MidiOutputNode(const string& path, size_t poly, Patch* parent, samplerate srate, size_t buffer_size); -}; - - -} // namespace Om - -#endif // MIDIOUTPUTNODE_H diff --git a/src/libs/engine/MidiTriggerNode.cpp b/src/libs/engine/MidiTriggerNode.cpp index 4fda80e7..d658ddc0 100644 --- a/src/libs/engine/MidiTriggerNode.cpp +++ b/src/libs/engine/MidiTriggerNode.cpp @@ -18,7 +18,6 @@ #include <cmath> #include "InputPort.h" #include "OutputPort.h" -#include "PortInfo.h" #include "Plugin.h" #include "util.h" #include "midi.h" @@ -29,32 +28,31 @@ 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) { - m_num_ports = 5; - m_ports.alloc(m_num_ports); + _num_ports = 5; + _ports = new Array<Port*>(5); - m_midi_in_port = new InputPort<MidiMessage>(this, "MIDI In", 0, 1, - new PortInfo("MIDI In", MIDI, INPUT), m_buffer_size); - m_ports.at(0) = m_midi_in_port; + _midi_in_port = new InputPort<MidiMessage>(this, "DataType::MIDI In", 0, 1, DataType::MIDI, _buffer_size); + _ports->at(0) = _midi_in_port; - m_note_port = new InputPort<sample>(this, "Note Number", 1, 1, - new PortInfo("Note Number", CONTROL, INPUT, INTEGER, 60, 0, 127), 1); - m_ports.at(1) = m_note_port; + _note_port = new InputPort<sample>(this, "Note Number", 1, 1, DataType::FLOAT, 1); + // new PortInfo("Note Number", CONTROL, INPUT, INTEGER, 60, 0, 127), 1); + _ports->at(1) = _note_port; - m_gate_port = new OutputPort<sample>(this, "Gate", 2, 1, - new PortInfo("Gate", AUDIO, OUTPUT, 0, 0, 1), m_buffer_size); - m_ports.at(2) = m_gate_port; + _gate_port = new OutputPort<sample>(this, "Gate", 2, 1, DataType::FLOAT, _buffer_size); + // new PortInfo("Gate", AUDIO, OUTPUT, 0, 0, 1), _buffer_size); + _ports->at(2) = _gate_port; - m_trig_port = new OutputPort<sample>(this, "Trigger", 3, 1, - new PortInfo("Trigger", AUDIO, OUTPUT, 0, 0, 1), m_buffer_size); - m_ports.at(3) = m_trig_port; + _trig_port = new OutputPort<sample>(this, "Trigger", 3, 1, DataType::FLOAT, _buffer_size); + // new PortInfo("Trigger", AUDIO, OUTPUT, 0, 0, 1), _buffer_size); + _ports->at(3) = _trig_port; - m_vel_port = new OutputPort<sample>(this, "Velocity", 4, poly, - new PortInfo("Velocity", AUDIO, OUTPUT, 0, 0, 1), m_buffer_size); - m_ports.at(4) = m_vel_port; + _vel_port = new OutputPort<sample>(this, "Velocity", 4, poly, DataType::FLOAT, _buffer_size); + // new PortInfo("Velocity", AUDIO, OUTPUT, 0, 0, 1), _buffer_size); + _ports->at(4) = _vel_port; - m_plugin.type(Plugin::Internal); - m_plugin.plug_label("trigger_in"); - m_plugin.name("Om Trigger Node (MIDI, OSC)"); + _plugin.type(Plugin::Internal); + _plugin.plug_label("trigger_in"); + _plugin.name("Om Trigger Node (MIDI, OSC)"); } @@ -65,8 +63,8 @@ MidiTriggerNode::run(size_t nframes) MidiMessage ev; - for (size_t i=0; i < m_midi_in_port->buffer(0)->filled_size(); ++i) { - ev = m_midi_in_port->buffer(0)->value_at(i); + for (size_t i=0; i < _midi_in_port->buffer(0)->filled_size(); ++i) { + ev = _midi_in_port->buffer(0)->value_at(i); switch (ev.buffer[0] & 0xF0) { case MIDI_CMD_NOTE_ON: @@ -81,7 +79,7 @@ MidiTriggerNode::run(size_t nframes) case MIDI_CMD_CONTROL: if (ev.buffer[1] == MIDI_CTL_ALL_NOTES_OFF || ev.buffer[1] == MIDI_CTL_ALL_SOUNDS_OFF) - m_gate_port->buffer(0)->set(0.0f, ev.time); + _gate_port->buffer(0)->set(0.0f, ev.time); default: break; } @@ -93,19 +91,19 @@ void MidiTriggerNode::note_on(uchar note_num, uchar velocity, samplecount offset) { //std::cerr << "Note on starting at sample " << offset << std::endl; - assert(offset < m_buffer_size); + assert(offset < _buffer_size); - const sample filter_note = m_note_port->buffer(0)->value_at(0); + const sample filter_note = _note_port->buffer(0)->value_at(0); if (filter_note >= 0.0 && filter_note < 127.0 && (note_num == (uchar)filter_note)){ // See comments in MidiNoteNode::note_on (FIXME) - if (offset == (samplecount)(m_buffer_size-1)) + if (offset == (samplecount)(_buffer_size-1)) --offset; - m_gate_port->buffer(0)->set(1.0f, offset); - m_trig_port->buffer(0)->set(1.0f, offset, offset); - m_trig_port->buffer(0)->set(0.0f, offset+1); - m_vel_port->buffer(0)->set(velocity/127.0f, offset); + _gate_port->buffer(0)->set(1.0f, offset); + _trig_port->buffer(0)->set(1.0f, offset, offset); + _trig_port->buffer(0)->set(0.0f, offset+1); + _vel_port->buffer(0)->set(velocity/127.0f, offset); } } @@ -113,10 +111,10 @@ MidiTriggerNode::note_on(uchar note_num, uchar velocity, samplecount offset) void MidiTriggerNode::note_off(uchar note_num, samplecount offset) { - assert(offset < m_buffer_size); + assert(offset < _buffer_size); - if (note_num == lrintf(m_note_port->buffer(0)->value_at(0))) - m_gate_port->buffer(0)->set(0.0f, offset); + if (note_num == lrintf(_note_port->buffer(0)->value_at(0))) + _gate_port->buffer(0)->set(0.0f, offset); } diff --git a/src/libs/engine/MidiTriggerNode.h b/src/libs/engine/MidiTriggerNode.h index 2f91c631..04d347d5 100644 --- a/src/libs/engine/MidiTriggerNode.h +++ b/src/libs/engine/MidiTriggerNode.h @@ -51,11 +51,11 @@ public: void note_off(uchar note_num, samplecount offset); private: - InputPort<MidiMessage>* m_midi_in_port; - InputPort<sample>* m_note_port; - OutputPort<sample>* m_gate_port; - OutputPort<sample>* m_trig_port; - OutputPort<sample>* m_vel_port; + InputPort<MidiMessage>* _midi_in_port; + InputPort<sample>* _note_port; + OutputPort<sample>* _gate_port; + OutputPort<sample>* _trig_port; + OutputPort<sample>* _vel_port; }; diff --git a/src/libs/engine/NodeBase.cpp b/src/libs/engine/NodeBase.cpp index b1628539..4eeada15 100644 --- a/src/libs/engine/NodeBase.cpp +++ b/src/libs/engine/NodeBase.cpp @@ -36,45 +36,46 @@ namespace Om { NodeBase::NodeBase(const string& name, size_t poly, Patch* parent, samplerate srate, size_t buffer_size) : Node(parent, name), - m_poly(poly), - m_srate(srate), - m_buffer_size(buffer_size), - m_activated(false), - m_num_ports(0), - m_traversed(false), - m_providers(new List<Node*>()), - m_dependants(new List<Node*>()) + _poly(poly), + _srate(srate), + _buffer_size(buffer_size), + _activated(false), + _num_ports(0), + _ports(NULL), + _traversed(false), + _providers(new List<Node*>()), + _dependants(new List<Node*>()) { - assert(m_poly > 0); - assert(m_parent == NULL || (m_poly == parent->internal_poly() || m_poly == 1)); + assert(_poly > 0); + assert(_parent == NULL || (_poly == parent->internal_poly() || _poly == 1)); } NodeBase::~NodeBase() { - assert(!m_activated); + assert(!_activated); - delete m_providers; - delete m_dependants; + delete _providers; + delete _dependants; - for (size_t i=0; i < m_ports.size(); ++i) - delete m_ports.at(i); + for (size_t i=0; i < _num_ports; ++i) + delete _ports->at(i); } void NodeBase::activate() { - assert(!m_activated); - m_activated = true; + assert(!_activated); + _activated = true; } void NodeBase::deactivate() { - assert(m_activated); - m_activated = false; + assert(_activated); + _activated = false; } @@ -92,7 +93,7 @@ NodeBase::add_to_store() { om->object_store()->add(this); for (size_t i=0; i < num_ports(); ++i) - om->object_store()->add(m_ports.at(i)); + om->object_store()->add(_ports->at(i)); } @@ -107,10 +108,10 @@ NodeBase::remove_from_store() } // Remove ports - for (size_t i=0; i < m_num_ports; ++i) { - node = om->object_store()->remove(m_ports.at(i)->path()); + 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(m_ports.at(i)->path()) == NULL); + assert(om->object_store()->find(_ports->at(i)->path()) == NULL); delete node; } } @@ -122,11 +123,11 @@ NodeBase::remove_from_store() void NodeBase::run(size_t nframes) { - assert(m_activated); + assert(_activated); // Mix down any ports with multiple inputs Port* p; - for (size_t i=0; i < m_ports.size(); ++i) { - p = m_ports.at(i); + for (size_t i=0; i < _ports->size(); ++i) { + p = _ports->at(i); p->prepare_buffers(nframes); } } @@ -146,11 +147,11 @@ NodeBase::set_path(const Path& new_path) TreeNode<OmObject*>* treenode = NULL; // Reinsert ports - for (size_t i=0; i < m_num_ports; ++i) { - treenode = om->object_store()->remove(old_path +"/"+ m_ports.at(i)->name()); + 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() == m_ports.at(i)); - treenode->key(new_path +"/" + m_ports.at(i)->name()); + assert(treenode->node() == _ports->at(i)); + treenode->key(new_path +"/" + _ports->at(i)->name()); om->object_store()->add(treenode); } diff --git a/src/libs/engine/NodeBase.h b/src/libs/engine/NodeBase.h index 796abbca..c114aa96 100644 --- a/src/libs/engine/NodeBase.h +++ b/src/libs/engine/NodeBase.h @@ -46,7 +46,7 @@ public: virtual void activate(); virtual void deactivate(); - bool activated() { return m_activated; } + bool activated() { return _activated; } virtual void run(size_t nframes); @@ -60,20 +60,20 @@ public: //void send_creation_messages(ClientInterface* client) const; - size_t num_ports() const { return m_num_ports; } - size_t poly() const { return m_poly; } - bool traversed() const { return m_traversed; } - void traversed(bool b) { m_traversed = b; } + size_t num_ports() const { return _num_ports; } + size_t poly() const { return _poly; } + bool traversed() const { return _traversed; } + void traversed(bool b) { _traversed = b; } - const Array<Port*>& ports() const { return m_ports; } - - virtual List<Node*>* providers() { return m_providers; } - virtual void providers(List<Node*>* l) { m_providers = l; } + const Array<Port*>& ports() const { return *_ports; } + + virtual List<Node*>* providers() { return _providers; } + virtual void providers(List<Node*>* l) { _providers = l; } - virtual List<Node*>* dependants() { return m_dependants; } - virtual void dependants(List<Node*>* l) { m_dependants = l; } + virtual List<Node*>* dependants() { return _dependants; } + virtual void dependants(List<Node*>* l) { _dependants = l; } - Patch* parent_patch() const { return (m_parent == NULL) ? NULL : m_parent->as_patch(); } + 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); } @@ -85,18 +85,18 @@ protected: NodeBase(const NodeBase&); NodeBase& operator=(const NodeBase&); - size_t m_poly; + size_t _poly; - samplerate m_srate; - size_t m_buffer_size; - bool m_activated; + samplerate _srate; + size_t _buffer_size; + bool _activated; - size_t m_num_ports; // number of ports PER VOICE - Array<Port*> m_ports; + size_t _num_ports; ///< number of ports PER VOICE + Array<Port*>* _ports; ///< Access in audio thread only - bool m_traversed; - List<Node*>* m_providers; // Nodes connected to this one's input ports - List<Node*>* m_dependants; // Nodes this one's output ports are connected to + bool _traversed; ///< Flag for process order algorithm + List<Node*>* _providers; ///< Nodes connected to this one's input ports + List<Node*>* _dependants; ///< Nodes this one's output ports are connected to }; diff --git a/src/libs/engine/NodeFactory.cpp b/src/libs/engine/NodeFactory.cpp index 176d3f47..9e7128b6 100644 --- a/src/libs/engine/NodeFactory.cpp +++ b/src/libs/engine/NodeFactory.cpp @@ -26,12 +26,14 @@ #include "MidiNoteNode.h" #include "MidiTriggerNode.h" #include "MidiControlNode.h" +#if 0 #include "AudioInputNode.h" #include "AudioOutputNode.h" #include "ControlInputNode.h" #include "ControlOutputNode.h" #include "MidiInputNode.h" #include "MidiOutputNode.h" +#endif #include "TransportNode.h" #include "PluginLibrary.h" #include "Plugin.h" @@ -74,6 +76,7 @@ NodeFactory::NodeFactory() Patch* parent = new Patch("dummy", 1, NULL, 1, 1, 1); Node* n = NULL; +#if 0 n = new AudioInputNode("foo", 1, parent, 1, 1); m_internal_plugins.push_back(new Plugin(n->plugin())); delete n; @@ -92,6 +95,7 @@ NodeFactory::NodeFactory() n = new MidiOutputNode("foo", 1, parent, 1, 1); m_internal_plugins.push_back(new Plugin(n->plugin())); delete n; +#endif n = new MidiNoteNode("foo", 1, parent, 1, 1); m_internal_plugins.push_back(new Plugin(n->plugin())); delete n; @@ -230,7 +234,7 @@ NodeFactory::load_internal_plugin(const string& uri, const string& name, size_t assert(uri.substr(0, 3) == "om:"); string plug_label = uri.substr(3); - +#if 0 if (plug_label == "midi_input") { MidiInputNode* tn = new MidiInputNode(name, 1, parent, om->audio_driver()->sample_rate(), om->audio_driver()->buffer_size()); return tn; @@ -253,7 +257,9 @@ NodeFactory::load_internal_plugin(const string& uri, const string& name, size_t ControlOutputNode* on = new ControlOutputNode(name, poly, parent, om->audio_driver()->sample_rate(), om->audio_driver()->buffer_size()); return on; - } else if (plug_label == "note_in" || plug_label == "midi_note_in") { + } else +#endif + if (plug_label == "note_in" || plug_label == "midi_note_in") { MidiNoteNode* mn = new MidiNoteNode(name, poly, parent, om->audio_driver()->sample_rate(), om->audio_driver()->buffer_size()); return mn; } else if (plug_label == "trigger_in" || plug_label == "midi_trigger_in") { diff --git a/src/libs/engine/NodeFactory.h b/src/libs/engine/NodeFactory.h index ed6a35dc..bec300bf 100644 --- a/src/libs/engine/NodeFactory.h +++ b/src/libs/engine/NodeFactory.h @@ -29,7 +29,6 @@ using std::string; using std::list; namespace Om { class Node; -class PortInfo; class Patch; class PluginLibrary; class Plugin; diff --git a/src/libs/engine/OSCClient.cpp b/src/libs/engine/OSCClient.cpp index 332a2144..e0bc5808 100644 --- a/src/libs/engine/OSCClient.cpp +++ b/src/libs/engine/OSCClient.cpp @@ -25,7 +25,6 @@ #include "util.h" #include "Patch.h" #include "Node.h" -#include "PortInfo.h" #include "Plugin.h" #include "PortBase.h" #include "Connection.h" diff --git a/src/libs/engine/OSCReceiver.cpp b/src/libs/engine/OSCReceiver.cpp index 8edab8b1..47e2f2be 100644 --- a/src/libs/engine/OSCReceiver.cpp +++ b/src/libs/engine/OSCReceiver.cpp @@ -89,6 +89,7 @@ OSCReceiver::OSCReceiver(size_t queue_size, const char* const port) lo_server_thread_add_method(_st, "/om/synth/enable_patch", "is", enable_patch_cb, this); lo_server_thread_add_method(_st, "/om/synth/disable_patch", "is", disable_patch_cb, this); lo_server_thread_add_method(_st, "/om/synth/clear_patch", "is", clear_patch_cb, this); + lo_server_thread_add_method(_st, "/om/synth/create_port", "issi", create_port_cb, this); lo_server_thread_add_method(_st, "/om/synth/create_node", "issssi", create_node_cb, this); lo_server_thread_add_method(_st, "/om/synth/create_node", "isssi", create_node_by_uri_cb, this); lo_server_thread_add_method(_st, "/om/synth/destroy", "is", destroy_cb, this); @@ -461,6 +462,25 @@ OSCReceiver::m_clear_patch_cb(const char* path, const char* types, lo_arg** argv /** \page engine_osc_namespace + * <p> \b /om/synth/create_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) - Data type for port to contain ("AUDIO", "CONTROL", or "MIDI") + * \arg \b direction ("is-output") (integer) - Direction of data flow (Input = 0, Output = 1) </p> \n \n + */ +int +OSCReceiver::m_create_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 int direction = argv[3]->i; + + create_port(port_path, data_type, (direction == 1)); + + return 0; +} + +/** \page engine_osc_namespace * <p> \b /om/synth/create_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) @@ -485,7 +505,7 @@ OSCReceiver::m_create_node_by_uri_cb(const char* path, const char* types, lo_arg /** \page engine_osc_namespace - * <p> \b /om/synth/create_node - Add a node into a given patch (load a plugin by libname, label) + * <p> \b /om/synth/create_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") @@ -493,8 +513,8 @@ OSCReceiver::m_create_node_by_uri_cb(const char* path, const char* types, lo_arg * \arg \b plug-label (string) - Label (ID) of plugin (eg "sine_fcaa") * \arg \b poly (integer-boolean) - Whether node is polyphonic (0 = false, 1 = true) * - * \li This is only here to provide backwards compatibility for old patches that store plugin - * references (particularly LADSPA) as libname, label. + * \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, don't use it. * </p> \n \n */ int diff --git a/src/libs/engine/OSCReceiver.h b/src/libs/engine/OSCReceiver.h index b80c25c3..7926a25c 100644 --- a/src/libs/engine/OSCReceiver.h +++ b/src/libs/engine/OSCReceiver.h @@ -82,6 +82,7 @@ private: LO_HANDLER(engine_deactivate); LO_HANDLER(create_patch); LO_HANDLER(rename); + LO_HANDLER(create_port); LO_HANDLER(create_node); LO_HANDLER(create_node_by_uri); LO_HANDLER(enable_patch); diff --git a/src/libs/engine/ObjectSender.cpp b/src/libs/engine/ObjectSender.cpp index 24191a5d..aec86e53 100644 --- a/src/libs/engine/ObjectSender.cpp +++ b/src/libs/engine/ObjectSender.cpp @@ -22,7 +22,6 @@ #include "Patch.h" #include "Node.h" #include "Port.h" -#include "PortInfo.h" #include "PortBase.h" #include "Connection.h" #include "NodeFactory.h" @@ -60,7 +59,7 @@ ObjectSender::send_patch(ClientInterface* client, const Patch* patch) client->connection((*j)->src_port()->path(), (*j)->dst_port()->path()); // Send port information - for (size_t i=0; i < patch->ports().size(); ++i) { + for (size_t i=0; i < patch->num_ports(); ++i) { Port* const port = patch->ports().at(i); // Send metadata @@ -68,7 +67,8 @@ ObjectSender::send_patch(ClientInterface* client, const Patch* patch) for (map<string, string>::const_iterator i = data.begin(); i != data.end(); ++i) client->metadata_update(port->path(), (*i).first, (*i).second); - if (port->port_info()->is_control()) + // Control port, send value + if (port->type() == DataType::FLOAT && port->buffer_size() == 1) client->control_change(port->path(), ((PortBase<sample>*)port)->buffer(0)->value_at(0)); } @@ -89,6 +89,8 @@ ObjectSender::send_node(ClientInterface* client, const Node* node) // FIXME: hack, these nodes probably shouldn't even exist in the // engine anymore if (const_cast<Node*>(node)->as_port()) { // bridge node if as_port() returns non-NULL + // FIXME: remove this whole thing. shouldn't be any bridge nodes anymore + assert(false); send_port(client, const_cast<Node*>(node)->as_port()); return; } @@ -124,13 +126,11 @@ ObjectSender::send_node(ClientInterface* client, const Node* node) // Send ports for (size_t j=0; j < ports.size(); ++j) { - Port* const port = ports.at(j); - PortInfo* const info = port->port_info(); - + Port* const port = ports.at(j); assert(port); - assert(info); - client->new_port(port->path(), info->type_string(), info->is_output()); + send_port(client, port); + //client->new_port(port->path(), port->type().uri(), port->is_output()); } client->bundle_end(); @@ -145,9 +145,18 @@ ObjectSender::send_node(ClientInterface* client, const Node* node) void ObjectSender::send_port(ClientInterface* client, const Port* port) { - PortInfo* info = port->port_info(); - - client->new_port(port->path(), info->type_string(), info->is_output()); + assert(port); + + // FIXME: temporary compatibility hack + string type = port->type().uri(); + if (port->type() == DataType::FLOAT) { + if (port->buffer_size() == 1) + type = "CONTROL"; + else + type = "AUDIO"; + } + + client->new_port(port->path(), type, port->is_output()); // Send metadata const map<string, string>& data = port->metadata(); diff --git a/src/libs/engine/OmObject.h b/src/libs/engine/OmObject.h index 606a3dba..d2360eed 100644 --- a/src/libs/engine/OmObject.h +++ b/src/libs/engine/OmObject.h @@ -45,10 +45,10 @@ class OmObject : public MaidObject { public: OmObject(OmObject* parent, const string& name) - : m_parent(parent), m_name(name) + : _parent(parent), _name(name) { - assert(parent == NULL || m_name.length() > 0); - assert(parent == NULL || m_name.find("/") == string::npos); + assert(parent == NULL || _name.length() > 0); + assert(parent == NULL || _name.find("/") == string::npos); //assert(((string)path()).find("//") == string::npos); } @@ -59,34 +59,34 @@ public: virtual Node* as_node() { return NULL; } virtual Port* as_port() { return NULL; } - OmObject* parent() const { return m_parent; } + OmObject* parent() const { return _parent; } - inline const string& name() const { return m_name; } + inline const string& name() const { return _name; } virtual void set_path(const Path& new_path) { - m_name = new_path.name(); - assert(m_name.find("/") == string::npos); + _name = new_path.name(); + assert(_name.find("/") == string::npos); } - void set_metadata(const string& key, const string& value) { m_metadata[key] = value; } + void set_metadata(const string& key, const string& value) { _metadata[key] = value; } const string& get_metadata(const string& key) { static const string empty_string = ""; - map<string, string>::iterator i = m_metadata.find(key); - if (i != m_metadata.end()) + map<string, string>::iterator i = _metadata.find(key); + if (i != _metadata.end()) return (*i).second; else return empty_string; } - const map<string, string>& metadata() const { return m_metadata; } + const map<string, string>& metadata() const { return _metadata; } inline const Path path() const { - if (m_parent == NULL) - return Path(string("/").append(m_name)); - else if (m_parent->path() == "/") - return Path(string("/").append(m_name)); + if (_parent == NULL) + return Path(string("/").append(_name)); + else if (_parent->path() == "/") + return Path(string("/").append(_name)); else - return Path(m_parent->path() +"/"+ m_name); + return Path(_parent->path() +"/"+ _name); } /** Patch and Node override this to recursively add their children. */ @@ -98,15 +98,15 @@ public: protected: OmObject() {} - OmObject* m_parent; - string m_name; + OmObject* _parent; + string _name; private: // Prevent copies (undefined) OmObject(const OmObject&); OmObject& operator=(const OmObject& copy); - map<string, string> m_metadata; + map<string, string> _metadata; }; diff --git a/src/libs/engine/OutputPort.cpp b/src/libs/engine/OutputPort.cpp index bf971919..6ebdf966 100644 --- a/src/libs/engine/OutputPort.cpp +++ b/src/libs/engine/OutputPort.cpp @@ -16,19 +16,17 @@ #include "OutputPort.h" #include "InputPort.h" -#include "PortInfo.h" #include <cassert> namespace Om { template<typename T> -OutputPort<T>::OutputPort(Node* node, const string& name, size_t index, size_t poly, PortInfo* port_info, size_t buffer_size) -: PortBase<T>(node, name, index, poly, port_info, buffer_size) +OutputPort<T>::OutputPort(Node* parent, const string& name, size_t index, size_t poly, DataType type, size_t buffer_size) +: PortBase<T>(parent, name, index, poly, type, buffer_size) { - assert(port_info->is_output() && !port_info->is_input()); } -template OutputPort<sample>::OutputPort(Node* node, const string& name, size_t index, size_t poly, PortInfo* port_info, size_t buffer_size); -template OutputPort<MidiMessage>::OutputPort(Node* node, const string& name, size_t index, size_t poly, PortInfo* port_info, size_t buffer_size); +template OutputPort<sample>::OutputPort(Node* parent, const string& name, size_t index, size_t poly, DataType type, size_t buffer_size); +template OutputPort<MidiMessage>::OutputPort(Node* parent, const string& name, size_t index, size_t poly, DataType type, size_t buffer_size); template<typename T> diff --git a/src/libs/engine/OutputPort.h b/src/libs/engine/OutputPort.h index 90488a7f..2546586e 100644 --- a/src/libs/engine/OutputPort.h +++ b/src/libs/engine/OutputPort.h @@ -42,10 +42,13 @@ template <typename T> class OutputPort : public PortBase<T> { public: - OutputPort(Node* node, const string& name, size_t index, size_t poly, PortInfo* port_info, size_t buffer_size); + OutputPort(Node* parent, const string& name, size_t index, size_t poly, DataType type, size_t buffer_size); virtual ~OutputPort() {} void set_tied_port(InputPort<T>* port); + + bool is_input() const { return false; } + bool is_output() const { return true; } private: // Prevent copies (undefined) diff --git a/src/libs/engine/Patch.cpp b/src/libs/engine/Patch.cpp index ce71214e..9e9ca173 100644 --- a/src/libs/engine/Patch.cpp +++ b/src/libs/engine/Patch.cpp @@ -21,7 +21,6 @@ #include "Patch.h" #include "Plugin.h" #include "Port.h" -#include "PortInfo.h" #include "ClientBroadcaster.h" #include "InternalNode.h" #include "Connection.h" @@ -29,6 +28,8 @@ #include "OmApp.h" #include "PortBase.h" #include "ObjectStore.h" +#include "InputPort.h" +#include "OutputPort.h" #include "interface/ClientInterface.h" using std::cerr; using std::cout; using std::endl; @@ -38,38 +39,38 @@ 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), - m_internal_poly(internal_poly), - m_process_order(NULL), - m_process(false) + _internal_poly(internal_poly), + _process_order(NULL), + _process(false) { assert(internal_poly >= 1); - m_plugin.type(Plugin::Patch); - m_plugin.uri("http://codeson.net/grauph/patch"); - m_plugin.plug_label("om_patch"); - m_plugin.name("Om patch"); + _plugin.type(Plugin::Patch); + _plugin.uri("http://codeson.net/grauph/patch"); + _plugin.plug_label("om_patch"); + _plugin.name("Om patch"); - //std::cerr << "Creating patch " << m_name << ", poly = " << poly + //std::cerr << "Creating patch " << _name << ", poly = " << poly // << ", internal poly = " << internal_poly << std::endl; } Patch::~Patch() { - assert(!m_activated); + assert(!_activated); - for (List<Connection*>::iterator i = m_connections.begin(); i != m_connections.end(); ++i) { + for (List<Connection*>::iterator i = _connections.begin(); i != _connections.end(); ++i) { delete (*i); - delete m_connections.remove(i); + delete _connections.remove(i); } - for (List<Node*>::iterator i = m_nodes.begin(); i != m_nodes.end(); ++i) { + for (List<Node*>::iterator i = _nodes.begin(); i != _nodes.end(); ++i) { assert(!(*i)->activated()); delete (*i); - delete m_nodes.remove(i); + delete _nodes.remove(i); } - delete m_process_order; + delete _process_order; } @@ -78,66 +79,77 @@ Patch::activate() { NodeBase::activate(); - for (List<Node*>::iterator i = m_nodes.begin(); i != m_nodes.end(); ++i) + for (List<Node*>::iterator i = _nodes.begin(); i != _nodes.end(); ++i) (*i)->activate(); - assert(m_activated); + assert(_activated); } void Patch::deactivate() { - if (m_activated) { + if (_activated) { NodeBase::deactivate(); - for (List<Node*>::iterator i = m_nodes.begin(); i != m_nodes.end(); ++i) { + for (List<Node*>::iterator i = _nodes.begin(); i != _nodes.end(); ++i) { if ((*i)->activated()) (*i)->deactivate(); assert(!(*i)->activated()); } } - assert(!m_activated); + assert(!_activated); } void -Patch::process(bool b) +Patch::process(bool p) { - if (!b) { + if (!p) { // Write output buffers to 0 - for (List<InternalNode*>::iterator i = m_bridge_nodes.begin(); i != m_bridge_nodes.end(); ++i) { + /*for (List<InternalNode*>::iterator i = _bridge_nodes.begin(); i != _bridge_nodes.end(); ++i) { assert((*i)->as_port() != NULL); if ((*i)->as_port()->port_info()->is_output()) - (*i)->as_port()->clear_buffers(); + (*i)->as_port()->clear_buffers();*/ + for (List<Port*>::iterator i = _patch_ports.begin(); i != _patch_ports.end(); ++i) { + if ((*i)->is_output()) + (*i)->clear_buffers(); } } - m_process = b; + _process = p; } /** Run the patch for the specified number of frames. * - * Calls all Nodes in the order m_process_order specifies. + * Calls all Nodes in the order _process_order specifies. */ inline void Patch::run(size_t nframes) { - if (m_process_order == NULL || !m_process) + if (_process_order == NULL || !_process) return; - // Prepare all ports - for (List<InternalNode*>::iterator i = m_bridge_nodes.begin(); i != m_bridge_nodes.end(); ++i) - (*i)->as_port()->prepare_buffers(nframes); + // FIXME: This is far too slow, too much checking every cycle + + // Prepare input ports for nodes to consume + for (List<Port*>::iterator i = _patch_ports.begin(); i != _patch_ports.end(); ++i) + if ((*i)->is_input()) + (*i)->prepare_buffers(nframes); - // Run all nodes - for (size_t i=0; i < m_process_order->size(); ++i) { + // Run all nodes (consume input ports) + for (size_t i=0; i < _process_order->size(); ++i) { // Could be a gap due to a node removal event (see RemoveNodeEvent.cpp) - // If you're thinking this isn't very nice, you're right. - if (m_process_order->at(i) != NULL) - m_process_order->at(i)->run(nframes); + // Yes, this is ugly + if (_process_order->at(i) != NULL) + _process_order->at(i)->run(nframes); } + + // Prepare output ports (for caller to consume) + for (List<Port*>::iterator i = _patch_ports.begin(); i != _patch_ports.end(); ++i) + if ((*i)->is_output()) + (*i)->prepare_buffers(nframes); } @@ -149,7 +161,7 @@ Patch::run(size_t nframes) size_t Patch::num_ports() const { - return m_bridge_nodes.size(); + return _patch_ports.size(); } @@ -161,7 +173,7 @@ Patch::send_creation_messages(ClientInterface* client) const om->client_broadcaster()->send_patch_to(client, this); - for (List<Node*>::const_iterator j = m_nodes.begin(); j != m_nodes.end(); ++j) { + for (List<Node*>::const_iterator j = _nodes.begin(); j != _nodes.end(); ++j) { Node* node = (*j); Port* port = node->as_port(); // NULL unless a bridge node node->send_creation_messages(client); @@ -174,13 +186,13 @@ Patch::send_creation_messages(ClientInterface* client) const ((PortBase<sample>*)port)->buffer(0)->value_at(0)); } - for (List<Connection*>::const_iterator j = m_connections.begin(); j != m_connections.end(); ++j) { + for (List<Connection*>::const_iterator j = _connections.begin(); j != _connections.end(); ++j) { om->client_broadcaster()->send_connection_to(client, *j); } // Send port information - /*for (size_t i=0; i < m_ports.size(); ++i) { - Port* const port = m_ports.at(i); + /*for (size_t i=0; i < _ports.size(); ++i) { + Port* const port = _ports.at(i); // Send metadata const map<string, string>& data = port->metadata(); @@ -202,7 +214,7 @@ Patch::add_to_store() NodeBase::add_to_store(); // Add nodes - for (List<Node*>::iterator j = m_nodes.begin(); j != m_nodes.end(); ++j) + for (List<Node*>::iterator j = _nodes.begin(); j != _nodes.end(); ++j) (*j)->add_to_store(); } @@ -214,7 +226,7 @@ Patch::remove_from_store() NodeBase::remove_from_store(); // Remove nodes - for (List<Node*>::iterator j = m_nodes.begin(); j != m_nodes.end(); ++j) { + for (List<Node*>::iterator j = _nodes.begin(); j != _nodes.end(); ++j) { (*j)->remove_from_store(); assert(om->object_store()->find((*j)->path()) == NULL); } @@ -230,18 +242,18 @@ Patch::add_node(ListNode<Node*>* ln) assert(ln != NULL); assert(ln->elem() != NULL); assert(ln->elem()->parent_patch() == this); - assert(ln->elem()->poly() == m_internal_poly || ln->elem()->poly() == 1); + assert(ln->elem()->poly() == _internal_poly || ln->elem()->poly() == 1); - m_nodes.push_back(ln); + _nodes.push_back(ln); } ListNode<Node*>* Patch::remove_node(const string& name) { - for (List<Node*>::iterator i = m_nodes.begin(); i != m_nodes.end(); ++i) + for (List<Node*>::iterator i = _nodes.begin(); i != _nodes.end(); ++i) if ((*i)->name() == name) - return m_nodes.remove(i); + return _nodes.remove(i); return NULL; } @@ -254,9 +266,9 @@ Patch::remove_connection(const Port* src_port, const Port* dst_port) { bool found = false; ListNode<Connection*>* connection = NULL; - for (List<Connection*>::iterator i = m_connections.begin(); i != m_connections.end(); ++i) { + for (List<Connection*>::iterator i = _connections.begin(); i != _connections.end(); ++i) { if ((*i)->src_port() == src_port && (*i)->dst_port() == dst_port) { - connection = m_connections.remove(i); + connection = _connections.remove(i); found = true; } } @@ -267,7 +279,7 @@ Patch::remove_connection(const Port* src_port, const Port* dst_port) return connection; } - +#if 0 /** Remove a bridge_node. Realtime safe. */ ListNode<InternalNode*>* @@ -275,9 +287,9 @@ Patch::remove_bridge_node(const InternalNode* node) { bool found = false; ListNode<InternalNode*>* bridge_node = NULL; - for (List<InternalNode*>::iterator i = m_bridge_nodes.begin(); i != m_bridge_nodes.end(); ++i) { + for (List<InternalNode*>::iterator i = _bridge_nodes.begin(); i != _bridge_nodes.end(); ++i) { if ((*i) == node) { - bridge_node = m_bridge_nodes.remove(i); + bridge_node = _bridge_nodes.remove(i); found = true; } } @@ -287,6 +299,46 @@ Patch::remove_bridge_node(const InternalNode* node) return bridge_node; } +#endif + +/** Create a port. Not realtime safe. + */ +Port* +Patch::create_port(const string& name, DataType type, size_t buffer_size, bool is_output) +{ + if (type == DataType::UNKNOWN) { + cerr << "[Patch::create_port] Unknown port type " << type.uri() << endl; + return NULL; + } + + assert( !(type == DataType::UNKNOWN) ); + + if (is_output) + return new OutputPort<MidiMessage>(this, name, 0, _poly, type, buffer_size); + else + return new InputPort<MidiMessage>(this, name, 0, _poly, type, buffer_size); +} + + +/** Remove a port. Realtime safe. + */ +ListNode<Port*>* +Patch::remove_port(const Port* port) +{ + bool found = false; + ListNode<Port*>* ret = NULL; + for (List<Port*>::iterator i = _patch_ports.begin(); i != _patch_ports.end(); ++i) { + if ((*i) == port) { + ret = _patch_ports.remove(i); + found = true; + } + } + + if ( ! found) + cerr << "WARNING: [Patch::remove_port] Port not found !" << endl; + + return ret; +} /** Find the process order for this Patch. @@ -297,30 +349,34 @@ Patch::remove_bridge_node(const InternalNode* node) * NOT actually set the process order, it is returned so it can be inserted * at the beginning of an audio cycle (by various Events). * - * This function is not realtime safe, due to the use of the List<Node*> iterator + * Not realtime safe. */ Array<Node*>* Patch::build_process_order() const { Node* node = NULL; - Array<Node*>* const process_order = new Array<Node*>(m_nodes.size()); + Array<Node*>* const process_order = new Array<Node*>(_nodes.size()); - for (List<Node*>::const_iterator i = m_nodes.begin(); i != m_nodes.end(); ++i) + for (List<Node*>::const_iterator i = _nodes.begin(); i != _nodes.end(); ++i) (*i)->traversed(false); // Traverse backwards starting at outputs - for (List<InternalNode*>::const_iterator i = m_bridge_nodes.begin(); i != m_bridge_nodes.end(); ++i) { - node = (*i); - assert(node->as_port() != NULL); - - // If the output node has been disconnected and has no connections left, don't traverse - // into it so it's not in the process order (and can be removed w/o flaming segfault death) - if (node->as_port()->port_info()->is_output() && node->providers()->size() > 0) - build_process_order_recursive(node, process_order); + for (List<Port*>::const_iterator p = _patch_ports.begin(); p != _patch_ports.end(); ++p) { + /*const Port* const port = (*p); + if (port->port_info()->is_output()) { + for (List<Connection*>::const_iterator c = port->connections().begin(); + c != port->connections().end(); ++c) { + const Connection* const connection = (*c); + assert(connection->dst_port() == port); + assert(connection->src_port()); + assert(connection->src_port()->parent_node()); + build_process_order_recursive(connection->src_port()->parent_node(), process_order); + } + }*/ } - // Add any nodes that weren't hit by the traversal (disjoint nodes) - for (List<Node*>::const_iterator i = m_nodes.begin(); i != m_nodes.end(); ++i) { + // Add any (disjoint) nodes that weren't hit by the traversal + for (List<Node*>::const_iterator i = _nodes.begin(); i != _nodes.end(); ++i) { node = (*i); if ( ! node->traversed()) { process_order->push_back(*i); @@ -328,7 +384,7 @@ Patch::build_process_order() const } } - assert(process_order->size() == m_nodes.size()); + assert(process_order->size() == _nodes.size()); return process_order; } @@ -345,7 +401,7 @@ Patch::set_path(const Path& new_path) const Path old_path = path(); // Update nodes - for (List<Node*>::iterator i = m_nodes.begin(); i != m_nodes.end(); ++i) + for (List<Node*>::iterator i = _nodes.begin(); i != _nodes.end(); ++i) (*i)->set_path(new_path.base_path() + (*i)->name()); // Update self diff --git a/src/libs/engine/Patch.h b/src/libs/engine/Patch.h index e2a1ed48..5f2782d5 100644 --- a/src/libs/engine/Patch.h +++ b/src/libs/engine/Patch.h @@ -22,6 +22,7 @@ #include "NodeBase.h" #include "Plugin.h" #include "List.h" +#include "DataType.h" using std::string; @@ -71,31 +72,37 @@ public: void add_node(ListNode<Node*>* tn); ListNode<Node*>* remove_node(const string& name); - List<Node*>& nodes() { return m_nodes; } - List<Connection*>& connections() { return m_connections; } + List<Node*>& nodes() { return _nodes; } + List<Connection*>& connections() { return _connections; } - const List<Node*>& nodes() const { return m_nodes; } - const List<Connection*>& connections() const { return m_connections; } + const List<Node*>& nodes() const { return _nodes; } + const List<Connection*>& connections() const { return _connections; } - void add_bridge_node(ListNode<InternalNode*>* n) { m_bridge_nodes.push_back(n); } - ListNode<InternalNode*>* remove_bridge_node(const InternalNode* n); + //void add_bridge_node(ListNode<InternalNode*>* n) { _bridge_nodes.push_back(n); } + //ListNode<InternalNode*>* remove_bridge_node(const InternalNode* n); + Port* create_port(const string& name, DataType type, size_t buffer_size, bool is_output); + void add_port(ListNode<Port*>* port) { _patch_ports.push_back(port); } + ListNode<Port*>* remove_port(const Port* p); - void add_connection(ListNode<Connection*>* c) { m_connections.push_back(c); } + void add_connection(ListNode<Connection*>* c) { _connections.push_back(c); } ListNode<Connection*>* remove_connection(const Port* src_port, const Port* dst_port); - Array<Node*>* process_order() { return m_process_order; } - void process_order(Array<Node*>* po) { m_process_order = po; } + Array<Node*>* process_order() { return _process_order; } + void process_order(Array<Node*>* po) { _process_order = po; } + + Array<Port*>* external_ports() { return _ports; } + void external_ports(Array<Port*>* pa) { _ports = pa; } Array<Node*>* build_process_order() const; inline void build_process_order_recursive(Node* n, Array<Node*>* order) const; /** Whether to run this patch's DSP in the audio thread */ - bool process() const { return m_process; } - void process(bool b); + bool process() const { return _process; } + void process(bool p); - size_t internal_poly() const { return m_internal_poly; } + size_t internal_poly() const { return _internal_poly; } - const Plugin* plugin() const { return &m_plugin; } + const Plugin* plugin() const { return &_plugin; } void plugin(const Plugin* const) { exit(EXIT_FAILURE); } private: @@ -103,14 +110,14 @@ private: Patch(const Patch&); Patch& operator=(const Patch&); - size_t m_internal_poly; - Array<Node*>* m_process_order; - List<Connection*> m_connections; - List<InternalNode*> m_bridge_nodes; ///< Inputs and outputs - List<Node*> m_nodes; - bool m_process; + size_t _internal_poly; + Array<Node*>* _process_order; ///< Accessed in audio thread only + List<Connection*> _connections; ///< Accessed in audio thread only + List<Port*> _patch_ports; ///< Accessed in preprocessing thread only + List<Node*> _nodes; ///< Accessed in preprocessing thread only + bool _process; - Plugin m_plugin; + Plugin _plugin; }; diff --git a/src/libs/engine/Port.cpp b/src/libs/engine/Port.cpp index 987d232d..63456873 100644 --- a/src/libs/engine/Port.cpp +++ b/src/libs/engine/Port.cpp @@ -16,22 +16,27 @@ #include "Port.h" #include "Node.h" -#include "PortInfo.h" #include "Om.h" #include "OmApp.h" #include "ObjectStore.h" +#include "DataType.h" namespace Om { -Port::Port(Node* const node, const string& name, size_t index, size_t poly, PortInfo* port_info) + +// Yeah, this shouldn't be here. +const char* const DataType::type_uris[3] = { "UNKNOWN", "FLOAT", "MIDI" }; + + +Port::Port(Node* const node, const string& name, size_t index, size_t poly, DataType type, size_t buffer_size) : OmObject(node, name), - m_index(index), - m_poly(poly), - m_port_info(port_info) + _index(index), + _poly(poly), + _type(type), + _buffer_size(buffer_size) { assert(node != NULL); - assert(port_info != NULL); - assert(m_poly > 0); + assert(_poly > 0); } diff --git a/src/libs/engine/Port.h b/src/libs/engine/Port.h index f51d7382..b6e1f607 100644 --- a/src/libs/engine/Port.h +++ b/src/libs/engine/Port.h @@ -21,13 +21,13 @@ #include <string> #include "util/types.h" #include "OmObject.h" +#include "DataType.h" using std::string; namespace Om { class Node; -class PortInfo; /** A port on a Node. @@ -45,9 +45,6 @@ public: Port* as_port() { return this; } - PortInfo* port_info() const { return m_port_info; } - void port_info(PortInfo* pi) { m_port_info = pi; } - void add_to_store(); void remove_from_store(); @@ -57,21 +54,27 @@ public: /** Empty buffer contents completely (ie silence) */ virtual void clear_buffers() = 0; - Node* parent_node() const { return m_parent->as_node(); } - bool is_sample() const { return false; } - size_t num() const { return m_index; } - size_t poly() const { return m_poly; } + virtual bool is_input() const = 0; + virtual bool is_output() const = 0; + + Node* parent_node() const { return _parent->as_node(); } + bool is_sample() const { return false; } + size_t num() const { return _index; } + size_t poly() const { return _poly; } + DataType type() const { return _type; } + size_t buffer_size() const { return _buffer_size; } protected: - Port(Node* const node, const string& name, size_t index, size_t poly, PortInfo* port_info); + Port(Node* const node, const string& name, size_t index, size_t poly, DataType type, size_t buffer_size); // Prevent copies (undefined) Port(const Port&); Port& operator=(const Port&); - size_t m_index; - size_t m_poly; - PortInfo* m_port_info; + size_t _index; + size_t _poly; + DataType _type; + size_t _buffer_size; }; diff --git a/src/libs/engine/PortBase.cpp b/src/libs/engine/PortBase.cpp index 3d8dbc67..75acede7 100644 --- a/src/libs/engine/PortBase.cpp +++ b/src/libs/engine/PortBase.cpp @@ -22,7 +22,6 @@ #include <sys/mman.h> #include "util.h" #include "Node.h" -#include "PortInfo.h" #include "MidiMessage.h" namespace Om { @@ -31,9 +30,8 @@ namespace Om { /** Constructor for a Port. */ template <typename T> -PortBase<T>::PortBase(Node* node, const string& name, size_t index, size_t poly, PortInfo* port_info, size_t buffer_size) -: Port(node, name, index, poly, port_info), - m_buffer_size(buffer_size), +PortBase<T>::PortBase(Node* parent, const string& name, size_t index, size_t poly, DataType type, size_t buffer_size) +: Port(parent, name, index, poly, type, buffer_size), m_fixed_buffers(false), m_is_tied(false), m_tied_port(NULL) @@ -44,18 +42,16 @@ PortBase<T>::PortBase(Node* node, const string& name, size_t index, size_t poly, assert(m_buffers.size() > 0); } template -PortBase<sample>::PortBase(Node* node, const string& name, size_t index, size_t poly, PortInfo* port_info, size_t buffer_size); +PortBase<sample>::PortBase(Node* parent, const string& name, size_t index, size_t poly, DataType type, size_t buffer_size); template -PortBase<MidiMessage>::PortBase(Node* node, const string& name, size_t index, size_t poly, PortInfo* port_info, size_t buffer_size); +PortBase<MidiMessage>::PortBase(Node* parent, const string& name, size_t index, size_t poly, DataType type, size_t buffer_size); template <typename T> PortBase<T>::~PortBase() { - for (size_t i=0; i < m_poly; ++i) + for (size_t i=0; i < _poly; ++i) delete m_buffers.at(i); - - delete m_port_info; } template PortBase<sample>::~PortBase(); template PortBase<MidiMessage>::~PortBase(); @@ -67,11 +63,11 @@ template<> void PortBase<sample>::set_value(sample val, size_t offset) { - if (m_port_info->is_control()) + if (offset >= _buffer_size) offset = 0; - assert(offset < m_buffer_size); + assert(offset < _buffer_size); - for (size_t v=0; v < m_poly; ++v) + for (size_t v=0; v < _poly; ++v) m_buffers.at(v)->set(val, offset); } @@ -81,9 +77,9 @@ template<> void PortBase<sample>::set_value(size_t voice, sample val, size_t offset) { - if (m_port_info->is_control()) + if (offset >= _buffer_size) offset = 0; - assert(offset < m_buffer_size); + assert(offset < _buffer_size); m_buffers.at(voice)->set(val, offset); } @@ -93,10 +89,10 @@ template <typename T> void PortBase<T>::allocate_buffers() { - m_buffers.alloc(m_poly); + m_buffers.alloc(_poly); - for (size_t i=0; i < m_poly; ++i) - m_buffers.at(i) = new Buffer<T>(m_buffer_size); + for (size_t i=0; i < _poly; ++i) + m_buffers.at(i) = new Buffer<T>(_buffer_size); } template void PortBase<sample>::allocate_buffers(); template void PortBase<MidiMessage>::allocate_buffers(); @@ -106,7 +102,7 @@ template<> void PortBase<sample>::prepare_buffers(size_t nframes) { - for (size_t i=0; i < m_poly; ++i) + for (size_t i=0; i < _poly; ++i) m_buffers.at(i)->prepare(nframes); } @@ -122,7 +118,7 @@ template<typename T> void PortBase<T>::clear_buffers() { - for (size_t i=0; i < m_poly; ++i) + for (size_t i=0; i < _poly; ++i) m_buffers.at(i)->clear(); } template void PortBase<sample>::clear_buffers(); diff --git a/src/libs/engine/PortBase.h b/src/libs/engine/PortBase.h index 9962538e..d4a29941 100644 --- a/src/libs/engine/PortBase.h +++ b/src/libs/engine/PortBase.h @@ -54,15 +54,13 @@ public: PortBase* tied_port() const { return m_tied_port; } void untie() { m_is_tied = false; m_tied_port = NULL; } - - size_t buffer_size() const { return m_buffer_size; } /** Used by drivers to prevent port from changing buffers */ void fixed_buffers(bool b) { m_fixed_buffers = b; } bool fixed_buffers() { return m_fixed_buffers; } protected: - PortBase(Node* const node, const string& name, size_t index, size_t poly, PortInfo* port_info, size_t buffer_size); + PortBase(Node* parent, const string& name, size_t index, size_t poly, DataType type, size_t buffer_size); // Prevent copies (undefined) PortBase(const PortBase<T>& copy); @@ -70,7 +68,6 @@ protected: void allocate_buffers(); - size_t m_buffer_size; bool m_fixed_buffers; bool m_is_tied; PortBase* m_tied_port; diff --git a/src/libs/engine/PortInfo.h b/src/libs/engine/PortInfo.h deleted file mode 100644 index 3fa4215a..00000000 --- a/src/libs/engine/PortInfo.h +++ /dev/null @@ -1,153 +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 PORTINFO_H -#define PORTINFO_H - -#include <cstdlib> -#include <string> -#include <ladspa.h> - -using std::string; - -namespace Om { - - -enum PortType { CONTROL, AUDIO, MIDI }; -enum PortDirection { INPUT = 0, OUTPUT = 1 }; // FIXME: dupe of ClientInterface::PortDirection -enum PortHint { NONE, INTEGER, TOGGLE, LOGARITHMIC }; - - -/** Information about a Port. - * - * I'm not sure this actually has a reason for existing anymore. This is the - * model for a Port, but no other OmObjects need a model, soo.... - * - * \ingroup engine - */ -class PortInfo -{ -public: - PortInfo(const string& port_name, PortType type, PortDirection dir, PortHint hint, float default_val, float min, float max) - : m_name(port_name), - m_type(type), - m_direction(dir), - m_hint(hint), - m_default_val(default_val), - m_min_val(min), - m_max_val(max) - {} - - PortInfo(const string& port_name, PortType type, PortDirection dir, float default_val, float min, float max) - : m_name(port_name), - m_type(type), - m_direction(dir), - m_hint(NONE), - m_default_val(default_val), - m_min_val(min), - m_max_val(max) - {} - - PortInfo(const string& port_name, PortType type, PortDirection dir, PortHint hint = NONE) - : m_name(port_name), - m_type(type), - m_direction(dir), - m_hint(hint), - m_default_val(0.0f), - m_min_val(0.0f), - m_max_val(1.0f) - {} - - PortInfo(const string& port_name, LADSPA_PortDescriptor d, LADSPA_PortRangeHintDescriptor hint) - : m_name(port_name), - m_default_val(1.0f), - m_min_val(0.0f), - m_max_val(1.0f) - { - if (LADSPA_IS_PORT_AUDIO(d)) m_type = AUDIO; - else if (LADSPA_IS_PORT_CONTROL(d)) m_type = CONTROL; - else exit(EXIT_FAILURE); - - if (LADSPA_IS_PORT_INPUT(d)) m_direction = INPUT; - else if (LADSPA_IS_PORT_OUTPUT(d)) m_direction = OUTPUT; - else exit(EXIT_FAILURE); - - if (LADSPA_IS_HINT_TOGGLED(hint)) { - m_hint = TOGGLE; m_min_val = 0; m_max_val = 1; m_default_val = 0; - } else if (LADSPA_IS_HINT_LOGARITHMIC(hint)) - m_hint = LOGARITHMIC; - else if (LADSPA_IS_HINT_INTEGER(hint)) - m_hint = INTEGER; - else - m_hint = NONE; - } - - PortType type() const { return m_type; } - void type(PortType t) { m_type = t; } - float min_val() const { return m_min_val; } - void min_val(float f) { m_min_val = f; } - float default_val() const { return m_default_val; } - void default_val(float f) { m_default_val = f; } - float max_val() const { return m_max_val; } - void max_val(float f) { m_max_val = f; } - PortDirection direction() const { return m_direction; } - - string type_string() { - switch (m_type) { - case CONTROL: return "CONTROL"; break; - case AUDIO: return "AUDIO"; break; - case MIDI: return "MIDI"; break; - default: return "UNKNOWN"; - } - } - string direction_string() { if (m_direction == INPUT) return "INPUT"; else return "OUTPUT"; } - string hint_string() { if (m_hint == INTEGER) return "INTEGER"; - else if (m_hint == LOGARITHMIC) return "LOGARITHMIC"; - else if (m_hint == TOGGLE) return "TOGGLE"; - else return "NONE"; } - - bool is_control() const { return (m_type == CONTROL); } - bool is_audio() const { return (m_type == AUDIO); } - bool is_midi() const { return (m_type == MIDI); } - bool is_input() const { return (m_direction == INPUT); } - bool is_output() const { return (m_direction == OUTPUT); } - - bool is_logarithmic() const { return (m_hint == LOGARITHMIC); } - bool is_integer() const { return (m_hint == INTEGER); } - bool is_toggle() const { return (m_hint == TOGGLE); } - - const string& name() const { return m_name; } - void name(const string& n) { m_name = n; } - -private: - // Prevent copies (undefined) - PortInfo(const PortInfo&); - PortInfo& operator=(const PortInfo&); - - string m_name; - PortType m_type; - PortDirection m_direction; - PortHint m_hint; - float m_default_val; - float m_min_val; - float m_max_val; -}; - - -} // namespace Om - -#endif // PORTINFO_H diff --git a/src/libs/engine/QueuedEngineInterface.cpp b/src/libs/engine/QueuedEngineInterface.cpp index 1b50deb9..7c5b91ed 100644 --- a/src/libs/engine/QueuedEngineInterface.cpp +++ b/src/libs/engine/QueuedEngineInterface.cpp @@ -119,6 +119,15 @@ QueuedEngineInterface::create_patch(const string& path, } +void QueuedEngineInterface::create_port(const string& path, + const string& data_type, + bool direction) +{ + AddPortEvent* ev = new AddPortEvent(_responder, path, data_type, direction); + push(ev); +} + + void QueuedEngineInterface::create_node(const string& path, const string& plugin_type, diff --git a/src/libs/engine/QueuedEngineInterface.h b/src/libs/engine/QueuedEngineInterface.h index cc9c575f..93649283 100644 --- a/src/libs/engine/QueuedEngineInterface.h +++ b/src/libs/engine/QueuedEngineInterface.h @@ -78,6 +78,10 @@ public: virtual void create_patch(const string& path, uint32_t poly); + virtual void create_port(const string& path, + const string& data_type, + bool direction); + virtual void create_node(const string& path, const string& plugin_type, const string& plugin_uri, diff --git a/src/libs/engine/TransportNode.cpp b/src/libs/engine/TransportNode.cpp index f5183d56..2a67a49a 100644 --- a/src/libs/engine/TransportNode.cpp +++ b/src/libs/engine/TransportNode.cpp @@ -24,7 +24,6 @@ #include "util.h" #include "Om.h" #include "OmApp.h" -#include "PortInfo.h" namespace Om { @@ -32,52 +31,54 @@ 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) { - m_num_ports = 10; - m_ports.alloc(m_num_ports); + _num_ports = 0; +#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); - m_ports.at(0) = spb_port; + // 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); - m_ports.at(1) = bpb_port; + // 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); - m_ports.at(2) = bar_port; +// 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); - m_ports.at(3) = beat_port; + // 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); - m_ports.at(4) = frame_port; + // 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); - m_ports.at(5) = hour_port; + // 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); - m_ports.at(6) = minute_port; + // 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); - m_ports.at(7) = second_port; + // 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); - m_ports.at(8) = trg_port; + // 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); - m_ports.at(9) = bar_trig_port; - - m_plugin.type(Plugin::Internal); - m_plugin.plug_label("transport"); - m_plugin.name("Om Transport Node (BROKEN)"); + // 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.h b/src/libs/engine/events.h index f1bc5f58..cfb44ec8 100644 --- a/src/libs/engine/events.h +++ b/src/libs/engine/events.h @@ -28,6 +28,7 @@ #include "SetPortValueQueuedEvent.h" #include "ConnectionEvent.h" #include "DisconnectionEvent.h" +#include "AddPortEvent.h" #include "AddNodeEvent.h" #include "CreatePatchEvent.h" #include "DestroyEvent.h" diff --git a/src/libs/engine/events/ConnectionEvent.cpp b/src/libs/engine/events/ConnectionEvent.cpp index fe3b991e..fcfa3bbc 100644 --- a/src/libs/engine/events/ConnectionEvent.cpp +++ b/src/libs/engine/events/ConnectionEvent.cpp @@ -25,7 +25,6 @@ #include "Patch.h" #include "ClientBroadcaster.h" #include "Port.h" -#include "PortInfo.h" #include "Maid.h" #include "ObjectStore.h" #include "util/Path.h" @@ -82,16 +81,16 @@ ConnectionEvent::pre_process() return; } - if (port1->port_info()->type() != port2->port_info()->type()) { + if (port1->type() != port2->type()) { m_error = TYPE_MISMATCH; QueuedEvent::pre_process(); return; } - if (port1->port_info()->is_output() && port2->port_info()->is_input()) { + if (port1->is_output() && port2->is_input()) { m_src_port = port1; m_dst_port = port2; - } else if (port2->port_info()->is_output() && port1->port_info()->is_input()) { + } else if (port2->is_output() && port1->is_input()) { m_src_port = port2; m_dst_port = port1; } else { @@ -101,11 +100,11 @@ ConnectionEvent::pre_process() } // Create the typed event to actually do the work - const PortType type = port1->port_info()->type(); - if (type == AUDIO || type == CONTROL) { + const DataType type = port1->type(); + if (type == DataType::FLOAT) { m_typed_event = new TypedConnectionEvent<sample>(m_responder, (OutputPort<sample>*)m_src_port, (InputPort<sample>*)m_dst_port); - } else if (type == MIDI) { + } else if (type == DataType::MIDI) { m_typed_event = new TypedConnectionEvent<MidiMessage>(m_responder, (OutputPort<MidiMessage>*)m_src_port, (InputPort<MidiMessage>*)m_dst_port); } else { diff --git a/src/libs/engine/events/DisconnectionEvent.cpp b/src/libs/engine/events/DisconnectionEvent.cpp index e7d06eab..0a3a4f7b 100644 --- a/src/libs/engine/events/DisconnectionEvent.cpp +++ b/src/libs/engine/events/DisconnectionEvent.cpp @@ -25,7 +25,6 @@ #include "Patch.h" #include "ClientBroadcaster.h" #include "Port.h" -#include "PortInfo.h" #include "Maid.h" #include "ObjectStore.h" #include "util/Path.h" @@ -62,9 +61,9 @@ DisconnectionEvent::DisconnectionEvent(CountedPtr<Responder> responder, Port* co m_typed_event(NULL), m_error(NO_ERROR) { - assert(src_port->port_info()->is_output()); - assert(dst_port->port_info()->is_input()); - assert(src_port->port_info()->type() == dst_port->port_info()->type()); + 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()); } @@ -102,16 +101,16 @@ DisconnectionEvent::pre_process() return; } - if (port1->port_info()->type() != port2->port_info()->type()) { + if (port1->type() != port2->type()) { m_error = TYPE_MISMATCH; QueuedEvent::pre_process(); return; } - if (port1->port_info()->is_output() && port2->port_info()->is_input()) { + if (port1->is_output() && port2->is_input()) { m_src_port = port1; m_dst_port = port2; - } else if (port2->port_info()->is_output() && port1->port_info()->is_input()) { + } else if (port2->is_output() && port1->is_input()) { m_src_port = port2; m_dst_port = port1; } else { @@ -122,11 +121,11 @@ DisconnectionEvent::pre_process() } // Create the typed event to actually do the work - const PortType type = m_src_port->port_info()->type(); - if (type == AUDIO || type == CONTROL) { + const DataType type = m_src_port->type(); + if (type == DataType::FLOAT) { m_typed_event = new TypedDisconnectionEvent<sample>(m_responder, (OutputPort<sample>*)m_src_port, (InputPort<sample>*)m_dst_port); - } else if (type == MIDI) { + } else if (type == DataType::MIDI) { m_typed_event = new TypedDisconnectionEvent<MidiMessage>(m_responder, (OutputPort<MidiMessage>*)m_src_port, (InputPort<MidiMessage>*)m_dst_port); } else { diff --git a/src/libs/engine/events/RequestPortValueEvent.cpp b/src/libs/engine/events/RequestPortValueEvent.cpp index e4d3985e..cd578460 100644 --- a/src/libs/engine/events/RequestPortValueEvent.cpp +++ b/src/libs/engine/events/RequestPortValueEvent.cpp @@ -21,7 +21,6 @@ #include "OmApp.h" #include "interface/ClientInterface.h" #include "PortBase.h" -#include "PortInfo.h" #include "ObjectStore.h" #include "ClientBroadcaster.h" @@ -53,7 +52,7 @@ RequestPortValueEvent::pre_process() void RequestPortValueEvent::execute(samplecount offset) { - if (m_port != NULL && m_port->port_info()->is_audio() || m_port->port_info()->is_control()) + if (m_port != NULL && m_port->type() == DataType::FLOAT) m_value = ((PortBase<sample>*)m_port)->buffer(0)->value_at(offset); else m_port = NULL; // triggers error response diff --git a/src/libs/engine/events/SetPortValueEvent.cpp b/src/libs/engine/events/SetPortValueEvent.cpp index 964cd9ca..6ca227e0 100644 --- a/src/libs/engine/events/SetPortValueEvent.cpp +++ b/src/libs/engine/events/SetPortValueEvent.cpp @@ -19,7 +19,6 @@ #include "Om.h" #include "OmApp.h" #include "PortBase.h" -#include "PortInfo.h" #include "ClientBroadcaster.h" #include "Node.h" #include "ObjectStore.h" @@ -59,7 +58,7 @@ SetPortValueEvent::execute(samplecount offset) if (m_port == NULL) { m_error = PORT_NOT_FOUND; - } else if (!m_port->port_info()->is_audio() && !m_port->port_info()->is_control()) { + } else if (!(m_port->type() == DataType::FLOAT)) { m_error = TYPE_MISMATCH; } else { if (m_voice_num == -1) @@ -83,7 +82,7 @@ SetPortValueEvent::post_process() // Send patch port control change, if this is a bridge port Port* parent_port = m_port->parent_node()->as_port(); if (parent_port != NULL) { - assert(parent_port->port_info()->is_control() || parent_port->port_info()->is_audio()); + assert(parent_port->type() == DataType::FLOAT); om->client_broadcaster()->send_control_change(parent_port->path(), m_val); } diff --git a/src/libs/engine/events/SetPortValueQueuedEvent.cpp b/src/libs/engine/events/SetPortValueQueuedEvent.cpp index e73c0486..b935beb9 100644 --- a/src/libs/engine/events/SetPortValueQueuedEvent.cpp +++ b/src/libs/engine/events/SetPortValueQueuedEvent.cpp @@ -19,7 +19,6 @@ #include "Om.h" #include "OmApp.h" #include "PortBase.h" -#include "PortInfo.h" #include "ClientBroadcaster.h" #include "Plugin.h" #include "Node.h" @@ -60,7 +59,7 @@ SetPortValueQueuedEvent::pre_process() if (m_port == NULL) { m_error = PORT_NOT_FOUND; - } else if (!m_port->port_info()->is_audio() && !m_port->port_info()->is_control()) { + } else if ( !(m_port->type() == DataType::FLOAT) ) { m_error = TYPE_MISMATCH; } @@ -95,7 +94,7 @@ SetPortValueQueuedEvent::post_process() // Send patch port control change, if this is a bridge port Port* parent_port = m_port->parent_node()->as_port(); if (parent_port != NULL) { - assert(parent_port->port_info()->is_control() || parent_port->port_info()->is_audio()); + assert(parent_port->type() == DataType::FLOAT); om->client_broadcaster()->send_control_change(parent_port->path(), m_val); } diff --git a/src/common/util/types.h b/src/libs/engine/types.h index d0ca5a0b..d0ca5a0b 100644 --- a/src/common/util/types.h +++ b/src/libs/engine/types.h diff --git a/src/progs/gtk/OmFlowCanvas.cpp b/src/progs/gtk/OmFlowCanvas.cpp index 863ba014..4920dc59 100644 --- a/src/progs/gtk/OmFlowCanvas.cpp +++ b/src/progs/gtk/OmFlowCanvas.cpp @@ -51,16 +51,39 @@ OmFlowCanvas::OmFlowCanvas(PatchController* controller, int width, int height) Glib::RefPtr<Gnome::Glade::Xml> xml = GladeFactory::new_glade_reference(); xml->get_widget("canvas_menu", m_menu); + xml->get_widget("canvas_menu_add_audio_input", m_menu_add_audio_input); + xml->get_widget("canvas_menu_add_audio_output", m_menu_add_audio_output); + xml->get_widget("canvas_menu_add_control_input", m_menu_add_control_input); + xml->get_widget("canvas_menu_add_control_output", m_menu_add_control_output); + xml->get_widget("canvas_menu_add_midi_input", m_menu_add_midi_input); + xml->get_widget("canvas_menu_add_midi_output", m_menu_add_midi_output); xml->get_widget("canvas_menu_load_plugin", m_menu_load_plugin); xml->get_widget("canvas_menu_load_patch", m_menu_load_patch); xml->get_widget("canvas_menu_new_patch", m_menu_new_patch); - m_menu_load_plugin->signal_activate().connect( - sigc::mem_fun<void>(this, &OmFlowCanvas::menu_load_plugin)); - m_menu_load_patch->signal_activate().connect( - sigc::mem_fun<void>(this, &OmFlowCanvas::menu_load_patch)); - m_menu_new_patch->signal_activate().connect( - sigc::mem_fun<void>(this, &OmFlowCanvas::menu_new_patch)); + // Add port menu items + m_menu_add_audio_input->signal_activate().connect( + sigc::bind(sigc::mem_fun(this, &OmFlowCanvas::menu_add_port), + "audio_input", "AUDIO", false)); + m_menu_add_audio_output->signal_activate().connect( + sigc::bind(sigc::mem_fun(this, &OmFlowCanvas::menu_add_port), + "audio_output", "AUDIO", true)); + m_menu_add_control_input->signal_activate().connect( + sigc::bind(sigc::mem_fun(this, &OmFlowCanvas::menu_add_port), + "control_input", "CONTROL", false)); + m_menu_add_control_output->signal_activate().connect( + sigc::bind(sigc::mem_fun(this, &OmFlowCanvas::menu_add_port), + "control_output", "CONTROL", true)); + m_menu_add_midi_input->signal_activate().connect( + sigc::bind(sigc::mem_fun(this, &OmFlowCanvas::menu_add_port), + "midi_input", "MIDI", false)); + m_menu_add_midi_output->signal_activate().connect( + sigc::bind(sigc::mem_fun(this, &OmFlowCanvas::menu_add_port), + "midi_output", "MIDI", true)); + + m_menu_load_plugin->signal_activate().connect(sigc::mem_fun(this, &OmFlowCanvas::menu_load_plugin)); + m_menu_load_patch->signal_activate().connect(sigc::mem_fun(this, &OmFlowCanvas::menu_load_patch)); + m_menu_new_patch->signal_activate().connect(sigc::mem_fun(this, &OmFlowCanvas::menu_new_patch)); } @@ -150,6 +173,67 @@ OmFlowCanvas::destroy_selected() void +OmFlowCanvas::menu_add_port(const string& name, const string& type, bool is_output) +{ + const Path& path = m_patch_controller->path().base_path() + name; + Controller::instance().create_port(path, type, is_output); + + char temp_buf[16]; + snprintf(temp_buf, 16, "%d", m_last_click_x); + Controller::instance().set_metadata(path, "module-x", temp_buf); + snprintf(temp_buf, 16, "%d", m_last_click_y); + Controller::instance().set_metadata(path, "module-y", temp_buf); +} +/* +void +OmFlowCanvas::menu_add_audio_input() +{ + string name = "audio_in"; + Controller::instance().create_port(m_patch_controller->path().base_path() + name, "AUDIO", false); +} + + +void +OmFlowCanvas::menu_add_audio_output() +{ + string name = "audio_out"; + Controller::instance().create_port(m_patch_controller->path().base_path() + name, "AUDIO", true); +} + + +void +OmFlowCanvas::menu_add_control_input() +{ + string name = "control_in"; + Controller::instance().create_port(m_patch_controller->path().base_path() + name, "CONTROL", false); +} + + +void +OmFlowCanvas::menu_add_control_output() +{ + string name = "control_out"; + Controller::instance().create_port(m_patch_controller->path().base_path() + name, "CONTROL", true); +} + + +void +OmFlowCanvas::menu_add_midi_input() +{ + string name = "midi_in"; + Controller::instance().create_port(m_patch_controller->path().base_path() + name, "MIDI", false); +} + + +void +OmFlowCanvas::menu_add_midi_output() +{ + string name = "midi_out"; + Controller::instance().create_port(m_patch_controller->path().base_path() + name, "MIDI", true); +} +*/ + +void OmFlowCanvas::menu_load_plugin() { m_patch_controller->window()->load_plugin_window()->set_next_module_location( diff --git a/src/progs/gtk/OmFlowCanvas.h b/src/progs/gtk/OmFlowCanvas.h index 1871de80..c645d43f 100644 --- a/src/progs/gtk/OmFlowCanvas.h +++ b/src/progs/gtk/OmFlowCanvas.h @@ -52,16 +52,29 @@ public: void show_menu(GdkEvent* event) { m_menu->popup(event->button.button, event->button.time); } +private: + void menu_add_port(const string& name, const string& type, bool is_output); + /*void menu_add_audio_input(); + void menu_add_audio_output(); + void menu_add_control_input(); + void menu_add_control_output(); + void menu_add_midi_input(); + void menu_add_midi_output();*/ void menu_load_plugin(); void menu_new_patch(); void menu_load_patch(); -private: PatchController* m_patch_controller; int m_last_click_x; int m_last_click_y; Gtk::Menu* m_menu; + Gtk::MenuItem* m_menu_add_audio_input; + Gtk::MenuItem* m_menu_add_audio_output; + Gtk::MenuItem* m_menu_add_control_input; + Gtk::MenuItem* m_menu_add_control_output; + Gtk::MenuItem* m_menu_add_midi_input; + Gtk::MenuItem* m_menu_add_midi_output; Gtk::MenuItem* m_menu_load_plugin; Gtk::MenuItem* m_menu_load_patch; Gtk::MenuItem* m_menu_new_patch; diff --git a/src/progs/gtk/PatchController.h b/src/progs/gtk/PatchController.h index 04bc82a8..4dde58e3 100644 --- a/src/progs/gtk/PatchController.h +++ b/src/progs/gtk/PatchController.h @@ -94,8 +94,8 @@ public: PatchWindow* window() const { return m_window; } void window(PatchWindow* pw) { m_window = pw; } - inline string name() const { return m_model->name(); } - inline const string& path() const { return m_model->path(); } + inline string name() const { return m_model->name(); } + inline const Path& path() const { return m_model->path(); } void set_path(const Path& new_path); diff --git a/src/progs/gtk/PortController.cpp b/src/progs/gtk/PortController.cpp index cdae49f7..a33a2122 100644 --- a/src/progs/gtk/PortController.cpp +++ b/src/progs/gtk/PortController.cpp @@ -101,6 +101,18 @@ PortController::metadata_update(const string& key, const string& value) m_control_panel->set_range_max(m_model->path(), atof(value.c_str())); } + if (m_module != NULL) { + if (key == "module-x") { + float x = atof(value.c_str()); + //if (x > 0 && x < m_canvas->width()) + m_module->move_to(x, m_module->property_y().get_value()); + } else if (key == "module-y") { + float y = atof(value.c_str()); + //if (y > 0 && y < m_canvas->height()) + m_module->move_to(m_module->property_x().get_value(), y); + } + } + GtkObjectController::metadata_update(key, value); } |