Got the audio flowing
git-svn-id: http://svn.drobilla.net/lad@70 a436a847-0d15-0410-975c-d299462d15a1
This commit is contained in:
parent
1c22ed9ea1
commit
53e98ec221
|
@ -180,7 +180,7 @@ Buffer<T>::copy(const Buffer<T>* src, size_t start_sample, size_t end_sample)
|
|||
assert(src->data() != NULL);
|
||||
assert(m_data != NULL);
|
||||
|
||||
const T* const src_data = src->data();
|
||||
register const T* const src_data = src->data();
|
||||
|
||||
for (size_t i=start_sample; i <= end_sample; ++i)
|
||||
m_data[i] = src_data[i];
|
||||
|
@ -205,7 +205,7 @@ Buffer<T>::accumulate(const Buffer<T>* const src, size_t start_sample, size_t en
|
|||
assert(src->data() != NULL);
|
||||
assert(m_data != NULL);
|
||||
|
||||
const T* const src_data = src->data();
|
||||
register const T* const src_data = src->data();
|
||||
|
||||
for (size_t i=start_sample; i <= end_sample; ++i)
|
||||
m_data[i] += src_data[i];
|
||||
|
@ -267,8 +267,30 @@ Buffer<sample>::prepare(samplecount nframes)
|
|||
}
|
||||
|
||||
|
||||
////// DriverBuffer ////////
|
||||
template<>
|
||||
void
|
||||
Buffer<MidiMessage>::prepare(samplecount nframes)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
/** Set the buffer (data) used.
|
||||
*
|
||||
* This is only to be used by Drivers (to provide zero-copy processing).
|
||||
*/
|
||||
template<typename T>
|
||||
void
|
||||
Buffer<T>::set_data(T* data)
|
||||
{
|
||||
assert(!m_is_joined);
|
||||
m_data = data;
|
||||
}
|
||||
template void Buffer<sample>::set_data(sample* data);
|
||||
template void Buffer<MidiMessage>::set_data(MidiMessage* data);
|
||||
|
||||
|
||||
////// DriverBuffer ////////
|
||||
#if 0
|
||||
template <typename T>
|
||||
DriverBuffer<T>::DriverBuffer(size_t size)
|
||||
: Buffer<T>(size)
|
||||
|
@ -293,6 +315,6 @@ DriverBuffer<T>::set_data(T* data)
|
|||
}
|
||||
template void DriverBuffer<sample>::set_data(sample* data);
|
||||
template void DriverBuffer<MidiMessage>::set_data(MidiMessage* data);
|
||||
|
||||
#endif
|
||||
|
||||
} // namespace Om
|
||||
|
|
|
@ -40,6 +40,9 @@ public:
|
|||
void join(Buffer* buf);
|
||||
void unjoin();
|
||||
|
||||
/** For driver use only!! */
|
||||
void set_data(T* data);
|
||||
|
||||
inline T& value_at(size_t offset) { assert(offset < m_size); return m_data[offset]; }
|
||||
|
||||
void prepare(samplecount nframes);
|
||||
|
@ -78,7 +81,7 @@ class DriverBuffer : public Buffer<T>
|
|||
public:
|
||||
DriverBuffer(size_t size);
|
||||
|
||||
void set_data(T* data);
|
||||
|
||||
|
||||
private:
|
||||
using Buffer<T>::m_data;
|
||||
|
|
|
@ -31,7 +31,6 @@ namespace Om {
|
|||
Connection::Connection(Port* const src_port, Port* const dst_port)
|
||||
: m_src_port(src_port),
|
||||
m_dst_port(dst_port),
|
||||
m_is_poly_to_mono( (src_port->parent_node()->poly() > dst_port->parent_node()->poly()) ),
|
||||
m_pending_disconnection(false)
|
||||
{
|
||||
assert(src_port != NULL);
|
||||
|
|
|
@ -56,7 +56,6 @@ protected:
|
|||
|
||||
Port* const m_src_port;
|
||||
Port* const m_dst_port;
|
||||
bool m_is_poly_to_mono;
|
||||
bool m_pending_disconnection;
|
||||
};
|
||||
|
||||
|
|
|
@ -1,84 +0,0 @@
|
|||
/* This file is part of Om. Copyright (C) 2005 Dave Robillard.
|
||||
*
|
||||
* Om is free software; you can redistribute it and/or modify it under the
|
||||
* terms of the GNU General Public License as published by the Free Software
|
||||
* Foundation; either version 2 of the License, or (at your option) any later
|
||||
* version.
|
||||
*
|
||||
* Om is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#ifndef DSSIPLUGIN_H
|
||||
#define DSSIPLUGIN_H
|
||||
|
||||
#include <dssi.h>
|
||||
#include <lo/lo.h>
|
||||
#include "LADSPAPlugin.h"
|
||||
|
||||
namespace Om {
|
||||
|
||||
class MidiMessage;
|
||||
template <typename T> class InputPort;
|
||||
|
||||
|
||||
/** An instance of a DSSI plugin.
|
||||
*/
|
||||
class DSSIPlugin : public LADSPAPlugin
|
||||
{
|
||||
public:
|
||||
DSSIPlugin(const string& name, uint poly, Patch* parent, DSSI_Descriptor* descriptor, samplerate srate, size_t buffer_size);
|
||||
~DSSIPlugin();
|
||||
|
||||
void activate();
|
||||
|
||||
void set_ui_url(const string& url);
|
||||
void send_update();
|
||||
|
||||
void set_control(uint port_num, sample val);
|
||||
void configure(const string& key, const string& val);
|
||||
void program(int bank, int program);
|
||||
|
||||
void run(size_t nframes);
|
||||
|
||||
const Plugin* const plugin() const { return m_plugin; }
|
||||
void plugin(const Plugin* const pi) { m_plugin = pi; }
|
||||
|
||||
private:
|
||||
// Prevent copies
|
||||
DSSIPlugin(const DSSIPlugin& copy) : LADSPAPlugin(copy) { exit(EXIT_FAILURE); }
|
||||
DSSIPlugin& operator=(const DSSIPlugin& copy) { exit(EXIT_FAILURE); }
|
||||
|
||||
// DSSI GUI messages
|
||||
void send_control(int port_num, float value);
|
||||
void send_program(int bank, int value);
|
||||
void send_configure(const string& key, const string& val);
|
||||
void send_show();
|
||||
void send_hide();
|
||||
void send_quit();
|
||||
|
||||
string m_ui_url;
|
||||
string m_ui_base_path;
|
||||
lo_address m_ui_addr;
|
||||
|
||||
// Current values
|
||||
int m_bank;
|
||||
int m_program;
|
||||
map<string, string> m_configures;
|
||||
|
||||
DSSI_Descriptor* m_dssi_descriptor;
|
||||
|
||||
InputPort<MidiMessage>* m_midi_in_port;
|
||||
};
|
||||
|
||||
|
||||
} // namespace Om
|
||||
|
||||
|
||||
#endif // DSSIPLUGIN_H
|
||||
|
|
@ -49,7 +49,8 @@ public:
|
|||
: _symbol(symbol)
|
||||
{}
|
||||
|
||||
const char* const uri() const { return type_uris[_symbol]; }
|
||||
const char* const uri() const { return type_uris[_symbol]; }
|
||||
const Symbol& symbol() const { return _symbol; }
|
||||
|
||||
inline bool operator==(const Symbol& symbol) const { return (_symbol == symbol); }
|
||||
inline bool operator!=(const Symbol& symbol) const { return (_symbol != symbol); }
|
||||
|
|
|
@ -37,6 +37,7 @@ DuplexPort<T>::DuplexPort(Node* parent, const string& name, size_t index, size_t
|
|||
, OutputPort<T>(parent, name, index, poly, type, buffer_size)
|
||||
, _is_output(is_output)
|
||||
{
|
||||
assert(TypedPort<T>::_parent == parent);
|
||||
}
|
||||
template DuplexPort<sample>::DuplexPort(Node* parent, const string& name, size_t index, size_t poly, DataType type, size_t buffer_size, bool is_output);
|
||||
template DuplexPort<MidiMessage>::DuplexPort(Node* parent, const string& name, size_t index, size_t poly, DataType type, size_t buffer_size, bool is_output);
|
||||
|
|
|
@ -48,8 +48,8 @@ public:
|
|||
: _parent(parent), _name(name)
|
||||
{
|
||||
assert(parent == NULL || _name.length() > 0);
|
||||
assert(parent == NULL || _name.find("/") == string::npos);
|
||||
assert(((string)path()).find("//") == string::npos);
|
||||
assert(_name.find("/") == string::npos);
|
||||
assert(path().find("//") == string::npos);
|
||||
}
|
||||
|
||||
virtual ~GraphObject() {}
|
||||
|
|
|
@ -235,12 +235,14 @@ InputPort<sample>::process(samplecount nframes)
|
|||
m_buffers.at(0)->join((*m_connections.begin())->buffer(0));
|
||||
do_mixdown = false;
|
||||
}
|
||||
update_buffers();
|
||||
} else {
|
||||
do_mixdown = false;
|
||||
}
|
||||
update_buffers();
|
||||
}
|
||||
|
||||
//cerr << path() << " mixing: " << do_mixdown << endl;
|
||||
|
||||
if (!do_mixdown) {
|
||||
assert(m_buffers.at(0)->data() == (*m_connections.begin())->buffer(0)->data());
|
||||
return;
|
||||
|
@ -250,13 +252,14 @@ InputPort<sample>::process(samplecount nframes)
|
|||
assert(!m_is_tied || m_buffers.at(0)->data() == m_tied_port->buffer(0)->data());*/
|
||||
|
||||
for (size_t voice=0; voice < _poly; ++voice) {
|
||||
// Copy first connection
|
||||
m_buffers.at(voice)->copy((*m_connections.begin())->buffer(voice), 0, _buffer_size-1);
|
||||
|
||||
// Accumulate the rest
|
||||
if (m_connections.size() > 1) {
|
||||
// Copy first connection
|
||||
|
||||
TypedConnectionListIterator c = m_connections.begin();
|
||||
|
||||
// Add all other connections
|
||||
|
||||
for (++c; c != m_connections.end(); ++c)
|
||||
m_buffers.at(voice)->accumulate((*c)->buffer(voice), 0, _buffer_size-1);
|
||||
}
|
||||
|
@ -271,7 +274,7 @@ InputPort<sample>::process(samplecount nframes)
|
|||
template <>
|
||||
void
|
||||
InputPort<MidiMessage>::process(samplecount nframes)
|
||||
{
|
||||
{
|
||||
//assert(!m_is_tied || m_tied_port != NULL);
|
||||
|
||||
const size_t num_ins = m_connections.size();
|
||||
|
|
|
@ -51,6 +51,7 @@ JackAudioPort::JackAudioPort(JackAudioDriver* driver, DuplexPort<sample>* patch_
|
|||
m_driver(driver),
|
||||
m_jack_port(NULL),
|
||||
m_jack_buffer(NULL),
|
||||
//m_jack_buffer(NULL),
|
||||
m_patch_port(patch_port)
|
||||
{
|
||||
//assert(patch_port->tied_port() != NULL);
|
||||
|
@ -61,7 +62,7 @@ JackAudioPort::JackAudioPort(JackAudioDriver* driver, DuplexPort<sample>* patch_
|
|||
(patch_port->is_input()) ? JackPortIsInput : JackPortIsOutput,
|
||||
0);
|
||||
|
||||
m_jack_buffer = new DriverBuffer<jack_sample_t>(driver->buffer_size());
|
||||
//m_jack_buffer = new DriverBuffer<jack_sample_t>(driver->buffer_size());
|
||||
|
||||
patch_port->fixed_buffers(true);
|
||||
}
|
||||
|
@ -89,22 +90,32 @@ JackAudioPort::remove_from_driver()
|
|||
void
|
||||
JackAudioPort::prepare_buffer(jack_nframes_t nframes)
|
||||
{
|
||||
// Technically this doesn't need to be done every time for output ports
|
||||
m_jack_buffer->set_data((jack_default_audio_sample_t*)
|
||||
// FIXME: Technically this doesn't need to be done every time for output ports
|
||||
/*m_jack_buffer->set_data((jack_default_audio_sample_t*)
|
||||
jack_port_get_buffer(m_jack_port, nframes));
|
||||
|
||||
m_patch_port->buffer(0)->join(m_jack_buffer);
|
||||
*/
|
||||
jack_sample_t* jack_buf = (jack_sample_t*)jack_port_get_buffer(m_jack_port, nframes);
|
||||
|
||||
if (jack_buf != m_jack_buffer) {
|
||||
//cerr << "Jack buffer: " << jack_buf << endl;
|
||||
m_patch_port->buffer(0)->set_data(jack_buf);
|
||||
m_jack_buffer = jack_buf;
|
||||
}
|
||||
|
||||
//assert(m_patch_port->tied_port() != NULL);
|
||||
|
||||
// FIXME: fixed_buffers switch on/off thing can be removed once this shit
|
||||
// FIXME: fixed_buffers switch on/off thing can be removed once this
|
||||
// gets figured out and assertions can go away
|
||||
m_patch_port->fixed_buffers(false);
|
||||
m_patch_port->buffer(0)->join(m_jack_buffer);
|
||||
//m_patch_port->fixed_buffers(false);
|
||||
//m_patch_port->buffer(0)->join(m_jack_buffer);
|
||||
//m_patch_port->tied_port()->buffer(0)->join(m_jack_buffer);
|
||||
|
||||
m_patch_port->fixed_buffers(true);
|
||||
//m_patch_port->fixed_buffers(true);
|
||||
|
||||
//assert(m_patch_port->buffer(0)->data() == m_patch_port->tied_port()->buffer(0)->data());
|
||||
assert(m_patch_port->buffer(0)->data() == m_jack_buffer->data());
|
||||
assert(m_patch_port->buffer(0)->data() == jack_buf);
|
||||
}
|
||||
|
||||
|
||||
|
@ -329,7 +340,7 @@ JackAudioDriver::m_process_cb(jack_nframes_t nframes)
|
|||
// Run root patch
|
||||
assert(m_root_patch != NULL);
|
||||
m_root_patch->process(nframes);
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -49,8 +49,8 @@ public:
|
|||
void prepare_buffer(jack_nframes_t nframes);
|
||||
|
||||
jack_port_t* jack_port() const { return m_jack_port; }
|
||||
DriverBuffer<sample>* buffer() const { return m_jack_buffer; }
|
||||
void jack_buffer(jack_sample_t* s) { m_jack_buffer->set_data(s); }
|
||||
//DriverBuffer<sample>* buffer() const { return m_jack_buffer; }
|
||||
//void jack_buffer(jack_sample_t* s) { m_jack_buffer->set_data(s); }
|
||||
DuplexPort<sample>* patch_port() const { return m_patch_port; }
|
||||
|
||||
private:
|
||||
|
@ -60,7 +60,8 @@ private:
|
|||
|
||||
JackAudioDriver* m_driver;
|
||||
jack_port_t* m_jack_port;
|
||||
DriverBuffer<sample>* m_jack_buffer;
|
||||
jack_sample_t* m_jack_buffer; ///< Cached for output ports
|
||||
//DriverBuffer<sample>* m_jack_buffer;
|
||||
DuplexPort<sample>* m_patch_port;
|
||||
};
|
||||
|
||||
|
|
|
@ -185,9 +185,8 @@ LADSPANode::set_port_buffer(size_t voice, size_t port_num, void* buf)
|
|||
assert(voice < _poly);
|
||||
|
||||
// Could be a MIDI port after this
|
||||
if (port_num < _descriptor->PortCount) {
|
||||
if (port_num < _descriptor->PortCount)
|
||||
_descriptor->connect_port(_instances[voice], port_num, (sample*)buf);
|
||||
}
|
||||
}
|
||||
|
||||
#if 0
|
||||
|
|
|
@ -136,10 +136,10 @@ private:
|
|||
List(const List& copy);
|
||||
List& operator=(const List& copy);
|
||||
|
||||
ListNode<T>* m_head;
|
||||
ListNode<T>* m_tail;
|
||||
ListNode<T>* m_head;
|
||||
ListNode<T>* m_tail;
|
||||
size_t m_size;
|
||||
iterator m_end_iter;
|
||||
iterator m_end_iter;
|
||||
const_iterator m_const_end_iter;
|
||||
};
|
||||
|
||||
|
|
|
@ -348,14 +348,14 @@ Patch::remove_port(const Port* port)
|
|||
Array<Node*>*
|
||||
Patch::build_process_order() const
|
||||
{
|
||||
Node* node = NULL;
|
||||
Array<Node*>* const process_order = new Array<Node*>(_nodes.size());
|
||||
|
||||
// FIXME: tweak algorithm so it just ends up like this and save the iteration?
|
||||
for (List<Node*>::const_iterator i = _nodes.begin(); i != _nodes.end(); ++i)
|
||||
(*i)->traversed(false);
|
||||
|
||||
// Traverse backwards starting at outputs
|
||||
for (List<Port*>::const_iterator p = _output_ports.begin(); p != _output_ports.end(); ++p) {
|
||||
//for (List<Port*>::const_iterator p = _output_ports.begin(); p != _output_ports.end(); ++p) {
|
||||
|
||||
/*const Port* const port = (*p);
|
||||
for (List<Connection*>::const_iterator c = port->connections().begin();
|
||||
|
@ -366,17 +366,32 @@ Patch::build_process_order() const
|
|||
assert(connection->src_port()->parent_node());
|
||||
build_process_order_recursive(connection->src_port()->parent_node(), process_order);
|
||||
}*/
|
||||
}
|
||||
//}
|
||||
|
||||
|
||||
// Add any (disjoint) nodes that weren't hit by the traversal
|
||||
for (List<Node*>::const_iterator i = _nodes.begin(); i != _nodes.end(); ++i) {
|
||||
/*for (List<Node*>::const_iterator i = _nodes.begin(); i != _nodes.end(); ++i) {
|
||||
node = (*i);
|
||||
if ( ! node->traversed()) {
|
||||
process_order->push_back(*i);
|
||||
node->traversed(true);
|
||||
}
|
||||
}*/
|
||||
|
||||
for (List<Node*>::const_iterator i = _nodes.begin(); i != _nodes.end(); ++i) {
|
||||
Node* const node = (*i);
|
||||
// Either a sink or connected to our output ports:
|
||||
if ( (!node->traversed()) && node->dependants()->size() == 0)
|
||||
build_process_order_recursive(node, process_order);
|
||||
}
|
||||
|
||||
cerr << "----------------------------------------\n";
|
||||
for (size_t i=0; i < process_order->size(); ++i) {
|
||||
assert(process_order->at(i));
|
||||
cerr << process_order->at(i)->path() << endl;
|
||||
}
|
||||
cerr << "----------------------------------------\n";
|
||||
|
||||
assert(process_order->size() == _nodes.size());
|
||||
|
||||
return process_order;
|
||||
|
|
|
@ -34,15 +34,20 @@ template <typename T>
|
|||
TypedConnection<T>::TypedConnection(OutputPort<T>* const src_port, InputPort<T>* const dst_port)
|
||||
: Connection(src_port, dst_port),
|
||||
m_local_buffer(NULL),
|
||||
m_is_poly_to_mono( (src_port->parent_node()->poly() > dst_port->parent_node()->poly()) ),
|
||||
m_must_mix(true),
|
||||
m_buffer_size(src_port->buffer_size()),
|
||||
m_pending_disconnection(false)
|
||||
{
|
||||
assert((src_port->parent_node()->poly() == dst_port->parent_node()->poly())
|
||||
|| (src_port->parent_node()->poly() == 1 || dst_port->parent_node()->poly() == 1));
|
||||
|
||||
if (m_is_poly_to_mono) // Poly -> Mono connection, need a buffer to mix in to
|
||||
if (src_port->poly() == dst_port->poly())
|
||||
m_must_mix = false;
|
||||
else // Poly -> Mono connection, need a buffer to mix into
|
||||
m_local_buffer = new Buffer<T>(m_buffer_size);
|
||||
|
||||
//cerr << "Connection " << src_port->path() << " -> " << dst_port->path()
|
||||
// << "\t mixing: " << m_must_mix << endl;
|
||||
}
|
||||
template TypedConnection<sample>::TypedConnection(OutputPort<sample>* const src_port, InputPort<sample>* const dst_port);
|
||||
template TypedConnection<MidiMessage>::TypedConnection(OutputPort<MidiMessage>* const src_port, InputPort<MidiMessage>* const dst_port);
|
||||
|
@ -71,7 +76,10 @@ TypedConnection<sample>::process(samplecount nframes)
|
|||
* would avoid having to mix multiple times. Probably not a very common
|
||||
* case, but it would be faster anyway. */
|
||||
|
||||
if (m_is_poly_to_mono) {
|
||||
if (m_must_mix) {
|
||||
//cerr << "Mixing " << src_port()->buffer(0)->data()
|
||||
// << " -> " << m_local_buffer->data() << endl;
|
||||
|
||||
m_local_buffer->copy(src_port()->buffer(0), 0, m_buffer_size-1);
|
||||
|
||||
// Mix all the source's voices down into local buffer starting at the second
|
||||
|
|
|
@ -61,7 +61,7 @@ private:
|
|||
TypedConnection& operator=(const TypedConnection&);
|
||||
|
||||
Buffer<T>* m_local_buffer; ///< Only used for poly->mono connections
|
||||
bool m_is_poly_to_mono;
|
||||
bool m_must_mix;
|
||||
size_t m_buffer_size;
|
||||
bool m_pending_disconnection;
|
||||
};
|
||||
|
@ -73,7 +73,7 @@ TypedConnection<sample>::buffer(size_t voice) const
|
|||
{
|
||||
TypedPort<sample>* const src_port = (TypedPort<sample>*)m_src_port;
|
||||
|
||||
if (m_is_poly_to_mono) {
|
||||
if (m_must_mix) {
|
||||
return m_local_buffer;
|
||||
} else {
|
||||
if (src_port->poly() == 1)
|
||||
|
|
|
@ -98,21 +98,14 @@ template void TypedPort<sample>::allocate_buffers();
|
|||
template void TypedPort<MidiMessage>::allocate_buffers();
|
||||
|
||||
|
||||
/*
|
||||
template<>
|
||||
template <typename T>
|
||||
void
|
||||
TypedPort<sample>::process(samplecount nframes)
|
||||
TypedPort<T>::process(samplecount nframes)
|
||||
{
|
||||
for (size_t i=0; i < _poly; ++i)
|
||||
m_buffers.at(i)->prepare(nframes);
|
||||
}
|
||||
|
||||
template<>
|
||||
void
|
||||
TypedPort<MidiMessage>::process(samplecount nframes)
|
||||
{
|
||||
}
|
||||
*/
|
||||
|
||||
template<typename T>
|
||||
void
|
||||
|
|
|
@ -49,7 +49,7 @@ public:
|
|||
|
||||
Buffer<T>* buffer(size_t voice) const { return m_buffers.at(voice); }
|
||||
|
||||
virtual void process(samplecount nframes) {}
|
||||
virtual void process(samplecount nframes);
|
||||
virtual void clear_buffers();
|
||||
|
||||
//TypedPort* tied_port() const { return m_tied_port; }
|
||||
|
|
|
@ -29,7 +29,10 @@
|
|||
#include "util/Path.h"
|
||||
#include "Port.h"
|
||||
#include "AudioDriver.h"
|
||||
#include "MidiDriver.h"
|
||||
#include "List.h"
|
||||
#include "Driver.h"
|
||||
#include "DuplexPort.h"
|
||||
|
||||
namespace Om {
|
||||
|
||||
|
@ -41,7 +44,8 @@ AddPortEvent::AddPortEvent(CountedPtr<Responder> responder, const string& path,
|
|||
_is_output(is_output),
|
||||
_data_type(DataType::UNKNOWN),
|
||||
_patch(NULL),
|
||||
_port(NULL),
|
||||
_patch_port(NULL),
|
||||
_driver_port(NULL),
|
||||
_succeeded(true)
|
||||
{
|
||||
string type_str;
|
||||
|
@ -52,11 +56,6 @@ AddPortEvent::AddPortEvent(CountedPtr<Responder> responder, const string& path,
|
|||
}
|
||||
|
||||
|
||||
AddPortEvent::~AddPortEvent()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
AddPortEvent::pre_process()
|
||||
{
|
||||
|
@ -65,6 +64,8 @@ AddPortEvent::pre_process()
|
|||
return;
|
||||
}
|
||||
|
||||
// FIXME: this is just a mess :/
|
||||
|
||||
_patch = om->object_store()->find_patch(_path.parent());
|
||||
|
||||
if (_patch != NULL) {
|
||||
|
@ -74,15 +75,24 @@ AddPortEvent::pre_process()
|
|||
if (_type == "AUDIO" || _type == "MIDI")
|
||||
buffer_size = om->audio_driver()->buffer_size();
|
||||
|
||||
_port = _patch->create_port(_path.name(), _data_type, buffer_size, _is_output);
|
||||
if (_port) {
|
||||
_patch_port = _patch->create_port(_path.name(), _data_type, buffer_size, _is_output);
|
||||
if (_patch_port) {
|
||||
if (_is_output)
|
||||
_patch->add_output(new ListNode<Port*>(_port));
|
||||
_patch->add_output(new ListNode<Port*>(_patch_port));
|
||||
else
|
||||
_patch->add_input(new ListNode<Port*>(_port));
|
||||
_patch->add_input(new ListNode<Port*>(_patch_port));
|
||||
_ports_array = new Array<Port*>(_patch->num_ports() + 1, _patch->external_ports());
|
||||
_ports_array->at(_patch->num_ports()) = _port;
|
||||
om->object_store()->add(_port);
|
||||
_ports_array->at(_patch->num_ports()) = _patch_port;
|
||||
om->object_store()->add(_patch_port);
|
||||
|
||||
if (!_patch->parent()) {
|
||||
if (_type == "AUDIO")
|
||||
_driver_port = om->audio_driver()->create_port(
|
||||
dynamic_cast<DuplexPort<sample>*>(_patch_port));
|
||||
else if (_type == "MIDI")
|
||||
_driver_port = om->midi_driver()->create_port(
|
||||
dynamic_cast<DuplexPort<MidiMessage>*>(_patch_port));
|
||||
}
|
||||
}
|
||||
}
|
||||
QueuedEvent::pre_process();
|
||||
|
@ -94,11 +104,14 @@ AddPortEvent::execute(samplecount offset)
|
|||
{
|
||||
QueuedEvent::execute(offset);
|
||||
|
||||
if (_port) {
|
||||
if (_patch_port) {
|
||||
om->maid()->push(_patch->external_ports());
|
||||
//_patch->add_port(_port);
|
||||
_patch->external_ports(_ports_array);
|
||||
}
|
||||
|
||||
if (_driver_port)
|
||||
_driver_port->add_to_driver();
|
||||
}
|
||||
|
||||
|
||||
|
@ -110,7 +123,7 @@ AddPortEvent::post_process()
|
|||
m_responder->respond_error(msg);
|
||||
} else {
|
||||
m_responder->respond_ok();
|
||||
om->client_broadcaster()->send_port(_port);
|
||||
om->client_broadcaster()->send_port(_patch_port);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -31,6 +31,7 @@ namespace Om {
|
|||
class Patch;
|
||||
class Port;
|
||||
class Plugin;
|
||||
class DriverPort;
|
||||
|
||||
|
||||
/** An event to add a Port to a Patch.
|
||||
|
@ -41,7 +42,6 @@ class AddPortEvent : public QueuedEvent
|
|||
{
|
||||
public:
|
||||
AddPortEvent(CountedPtr<Responder> responder, const string& path, const string& type, bool is_output);
|
||||
~AddPortEvent();
|
||||
|
||||
void pre_process();
|
||||
void execute(samplecount offset);
|
||||
|
@ -53,18 +53,10 @@ private:
|
|||
bool _is_output;
|
||||
DataType _data_type;
|
||||
Patch* _patch;
|
||||
Port* _port;
|
||||
Array<Port*>* _ports_array; // New (external) ports array for Patch
|
||||
Port* _patch_port;
|
||||
Array<Port*>* _ports_array; ///< New (external) ports array for Patch
|
||||
DriverPort* _driver_port; ///< Driver (eg Jack) port if this is a toplevel port
|
||||
bool _succeeded;
|
||||
/*
|
||||
string m_patch_name;
|
||||
Path m_path;
|
||||
Plugin* m_plugin;
|
||||
bool m_poly;
|
||||
Patch* m_patch;
|
||||
Node* m_node;
|
||||
Array<Node*>* m_process_order; // Patch's new process order
|
||||
bool m_node_already_exists;*/
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -212,8 +212,12 @@ TypedConnectionEvent<T>::pre_process()
|
|||
m_port_listnode = new ListNode<TypedConnection<T>*>(m_connection);
|
||||
m_patch_listnode = new ListNode<Connection*>(m_connection);
|
||||
|
||||
dst_node->providers()->push_back(new ListNode<Node*>(src_node));
|
||||
src_node->dependants()->push_back(new ListNode<Node*>(dst_node));
|
||||
// Need to be careful about patch port connections here and adding a node's
|
||||
// parent as a dependant/provider...
|
||||
if (src_node->parent() == dst_node->parent()) {
|
||||
dst_node->providers()->push_back(new ListNode<Node*>(src_node));
|
||||
src_node->dependants()->push_back(new ListNode<Node*>(dst_node));
|
||||
}
|
||||
|
||||
if (m_patch->process())
|
||||
m_process_order = m_patch->build_process_order();
|
||||
|
|
Loading…
Reference in New Issue