Remove internal ports.
git-svn-id: svn://localhost/ardour2/branches/3.0@4525 d708f5d6-7413-0410-9779-e7cbd77b26cf
This commit is contained in:
parent
fe4e98a729
commit
d469cc3e3a
|
@ -92,7 +92,6 @@ gain.cc
|
|||
gdither.cc
|
||||
globals.cc
|
||||
import.cc
|
||||
internal_send.cc
|
||||
io.cc
|
||||
io_processor.cc
|
||||
jack_slave.cc
|
||||
|
|
|
@ -29,8 +29,8 @@ namespace ARDOUR {
|
|||
class AudioPort : public Port
|
||||
{
|
||||
public:
|
||||
~AudioPort();
|
||||
|
||||
~AudioPort ();
|
||||
|
||||
DataType type () const {
|
||||
return DataType::AUDIO;
|
||||
}
|
||||
|
@ -44,23 +44,14 @@ class AudioPort : public Port
|
|||
|
||||
AudioBuffer& get_audio_buffer (nframes_t, nframes_t);
|
||||
|
||||
void reset ();
|
||||
|
||||
protected:
|
||||
friend class AudioEngine;
|
||||
|
||||
AudioPort (std::string const &, Flags, bool, nframes_t);
|
||||
AudioPort (std::string const &, Flags);
|
||||
|
||||
bool using_internal_data() const;
|
||||
void use_internal_data ();
|
||||
void use_external_data ();
|
||||
|
||||
private:
|
||||
void mixdown (nframes_t, nframes_t, bool);
|
||||
|
||||
bool _has_been_mixed_down;
|
||||
bool _buffer_data_set;
|
||||
AudioBuffer* _buffer;
|
||||
bool _internal_buffer;
|
||||
};
|
||||
|
||||
} // namespace ARDOUR
|
||||
|
|
|
@ -73,10 +73,6 @@ class AudioTrack : public Track
|
|||
int deprecated_use_diskstream_connections ();
|
||||
void set_state_part_two ();
|
||||
void set_state_part_three ();
|
||||
|
||||
void catch_up_on_busses (ARDOUR::RouteList&);
|
||||
void add_internal_send (boost::shared_ptr<ARDOUR::Route>);
|
||||
|
||||
};
|
||||
|
||||
} // namespace ARDOUR
|
||||
|
|
|
@ -120,8 +120,8 @@ class AudioEngine : public sigc::trackable
|
|||
virtual const char *what() const throw() { return "could not connect to engine backend"; }
|
||||
};
|
||||
|
||||
Port *register_input_port (DataType, const std::string& portname, bool publish);
|
||||
Port *register_output_port (DataType, const std::string& portname, bool publish);
|
||||
Port *register_input_port (DataType, const std::string& portname);
|
||||
Port *register_output_port (DataType, const std::string& portname);
|
||||
int unregister_port (Port &);
|
||||
|
||||
int connect (const std::string& source, const std::string& destination);
|
||||
|
@ -228,7 +228,7 @@ class AudioEngine : public sigc::trackable
|
|||
|
||||
SerializedRCUManager<Ports> ports;
|
||||
|
||||
Port *register_port (DataType type, const std::string& portname, bool input, bool publish);
|
||||
Port *register_port (DataType type, const std::string& portname, bool input);
|
||||
|
||||
int process_callback (nframes_t nframes);
|
||||
void remove_all_ports ();
|
||||
|
|
|
@ -1,72 +0,0 @@
|
|||
/*
|
||||
Copyright (C) 2009 Paul Davis
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
|
||||
*/
|
||||
|
||||
#ifndef __ardour_internal_send_h__
|
||||
#define __ardour_internal_send_h__
|
||||
|
||||
#include <sigc++/signal.h>
|
||||
#include <string>
|
||||
|
||||
|
||||
#include <pbd/stateful.h>
|
||||
#include <ardour/ardour.h>
|
||||
#include <ardour/audioengine.h>
|
||||
#include <ardour/io_processor.h>
|
||||
|
||||
namespace ARDOUR {
|
||||
|
||||
class InternalSend : public IOProcessor
|
||||
{
|
||||
public:
|
||||
InternalSend (Session&, Placement, boost::shared_ptr<IO> destination);
|
||||
virtual ~InternalSend ();
|
||||
|
||||
ChanCount output_streams() const;
|
||||
ChanCount input_streams () const;
|
||||
|
||||
void run_in_place (BufferSet& bufs, nframes_t start_frame, nframes_t end_frame, nframes_t nframes, nframes_t offset);
|
||||
|
||||
void set_metering (bool yn);
|
||||
|
||||
void activate ();
|
||||
void deactivate ();
|
||||
|
||||
XMLNode& get_state(void);
|
||||
int set_state(const XMLNode& node);
|
||||
|
||||
uint32_t pans_required() const { return _configured_input.n_audio(); }
|
||||
void expect_inputs (const ChanCount&);
|
||||
|
||||
bool can_support_io_configuration (const ChanCount& in, ChanCount& out) const;
|
||||
bool configure_io (ChanCount in, ChanCount out);
|
||||
|
||||
static uint32_t how_many_sends();
|
||||
|
||||
private:
|
||||
boost::shared_ptr<IO> destination;
|
||||
bool _metering;
|
||||
ChanCount expected_inputs;
|
||||
uint32_t bitslot;
|
||||
|
||||
void destination_io_config_changed (IOChange,void*);
|
||||
};
|
||||
|
||||
} // namespace ARDOUR
|
||||
|
||||
#endif /* __ardour_internal_send_h__ */
|
|
@ -77,8 +77,7 @@ class IO : public SessionObject, public AutomatableControls, public Latent
|
|||
IO (Session&, const string& name,
|
||||
int input_min = -1, int input_max = -1,
|
||||
int output_min = -1, int output_max = -1,
|
||||
DataType default_type = DataType::AUDIO,
|
||||
bool public_ports = true);
|
||||
DataType default_type = DataType::AUDIO);
|
||||
|
||||
IO (Session&, const XMLNode&, DataType default_type = DataType::AUDIO);
|
||||
|
||||
|
@ -286,7 +285,6 @@ class IO : public SessionObject, public AutomatableControls, public Latent
|
|||
bool _denormal_protection;
|
||||
XMLNode* deferred_state;
|
||||
DataType _default_type;
|
||||
bool _public_ports;
|
||||
|
||||
virtual void prepare_inputs (nframes_t nframes, nframes_t offset);
|
||||
virtual void flush_outputs (nframes_t nframes, nframes_t offset);
|
||||
|
|
|
@ -47,8 +47,7 @@ class IOProcessor : public Processor
|
|||
public:
|
||||
IOProcessor (Session&, const string& name, Placement,
|
||||
int input_min = -1, int input_max = -1, int output_min = -1, int output_max = -1,
|
||||
ARDOUR::DataType default_type = DataType::AUDIO,
|
||||
bool public_ports = true);
|
||||
ARDOUR::DataType default_type = DataType::AUDIO);
|
||||
IOProcessor (const IOProcessor&);
|
||||
virtual ~IOProcessor ();
|
||||
|
||||
|
|
|
@ -49,11 +49,10 @@ class MidiPort : public Port {
|
|||
protected:
|
||||
friend class AudioEngine;
|
||||
|
||||
MidiPort (const std::string& name, Flags, bool external, nframes_t bufsize);
|
||||
MidiPort (const std::string& name, Flags);
|
||||
|
||||
private:
|
||||
void mixdown (nframes_t, nframes_t, bool);
|
||||
|
||||
|
||||
MidiBuffer* _buffer;
|
||||
bool _has_been_mixed_down;
|
||||
};
|
||||
|
|
|
@ -65,13 +65,7 @@ public:
|
|||
return _flags & IsOutput;
|
||||
}
|
||||
|
||||
/* @return true if this port is visible outside Ardour (via JACK) */
|
||||
bool external () const {
|
||||
return _jack_port != 0;
|
||||
}
|
||||
|
||||
bool connected () const;
|
||||
bool externally_connected () const;
|
||||
int disconnect_all ();
|
||||
int get_connections (std::vector<std::string> &) const;
|
||||
|
||||
|
@ -90,9 +84,8 @@ public:
|
|||
nframes_t total_latency () const;
|
||||
int reestablish ();
|
||||
int reconnect ();
|
||||
void set_latency (nframes_t);
|
||||
void request_monitor_input (bool);
|
||||
void make_external ();
|
||||
void set_latency (nframes_t);
|
||||
|
||||
virtual void reset ();
|
||||
|
||||
|
@ -108,36 +101,26 @@ public:
|
|||
|
||||
protected:
|
||||
|
||||
Port (std::string const &, DataType, Flags, bool);
|
||||
Port (std::string const &, DataType, Flags);
|
||||
|
||||
jack_port_t* _jack_port; ///< JACK port, or 0 if we don't have one
|
||||
std::set<Port*> _connections; ///< internal Ports that we are connected to
|
||||
jack_port_t* _jack_port; ///< JACK port
|
||||
|
||||
static AudioEngine* _engine; ///< the AudioEngine
|
||||
|
||||
virtual bool using_internal_data() const { return false; }
|
||||
virtual void use_internal_data () {}
|
||||
virtual void use_external_data () {}
|
||||
|
||||
void check_buffer_status ();
|
||||
|
||||
private:
|
||||
friend class AudioEngine;
|
||||
|
||||
void recompute_total_latency () const;
|
||||
void do_make_external (DataType);
|
||||
|
||||
/* XXX */
|
||||
bool _last_monitor;
|
||||
nframes_t _latency;
|
||||
|
||||
std::string _name; ///< port short name
|
||||
Flags _flags; ///< flags
|
||||
|
||||
/// list of JACK ports that we are connected to; we only keep this around
|
||||
/// so that we can implement ::reconnect ()
|
||||
std::set<std::string> _named_connections;
|
||||
|
||||
/** ports that we are connected to, kept so that we can
|
||||
reconnect to JACK when required */
|
||||
std::set<std::string> _connections;
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
@ -25,30 +25,15 @@
|
|||
using namespace ARDOUR;
|
||||
using namespace std;
|
||||
|
||||
AudioPort::AudioPort (const std::string& name, Flags flags, bool ext, nframes_t capacity)
|
||||
: Port (name, DataType::AUDIO, flags, ext)
|
||||
, _has_been_mixed_down (false)
|
||||
, _buffer (0)
|
||||
, _internal_buffer (false)
|
||||
AudioPort::AudioPort (const std::string& name, Flags flags)
|
||||
: Port (name, DataType::AUDIO, flags)
|
||||
, _buffer_data_set (false)
|
||||
, _buffer (new AudioBuffer (0))
|
||||
{
|
||||
assert (name.find_first_of (':') == string::npos);
|
||||
|
||||
if (external ()) {
|
||||
|
||||
/* external ports use the external port buffer */
|
||||
_buffer = new AudioBuffer (0);
|
||||
|
||||
} else {
|
||||
|
||||
/* internal ports need their own buffers */
|
||||
_buffer = new AudioBuffer (capacity);
|
||||
}
|
||||
|
||||
check_buffer_status ();
|
||||
|
||||
}
|
||||
|
||||
AudioPort::~AudioPort()
|
||||
AudioPort::~AudioPort ()
|
||||
{
|
||||
delete _buffer;
|
||||
}
|
||||
|
@ -58,20 +43,22 @@ AudioPort::cycle_start (nframes_t nframes, nframes_t offset)
|
|||
{
|
||||
/* caller must hold process lock */
|
||||
|
||||
/* For external (JACK) ports, get_buffer() must only be run
|
||||
on outputs here in cycle_start().
|
||||
/* get_buffer() must only be run on outputs here in cycle_start().
|
||||
|
||||
Inputs must be done in the correct processing order, which
|
||||
requires interleaving with route processing. that will
|
||||
happen when Port::get_buffer() is called.
|
||||
*/
|
||||
|
||||
if (!receives_input() && external ()) {
|
||||
|
||||
if (sends_output() && !_buffer_data_set) {
|
||||
|
||||
_buffer->set_data ((Sample *) jack_port_get_buffer (_jack_port, nframes) + offset, nframes);
|
||||
_buffer_data_set = true;
|
||||
|
||||
}
|
||||
|
||||
if (receives_input()) {
|
||||
_has_been_mixed_down = false;
|
||||
_buffer_data_set = false;
|
||||
} else {
|
||||
_buffer->silence (nframes, offset);
|
||||
}
|
||||
|
@ -82,19 +69,10 @@ AudioPort::get_audio_buffer (nframes_t nframes, nframes_t offset)
|
|||
{
|
||||
/* caller must hold process lock */
|
||||
|
||||
if (receives_input () && !_has_been_mixed_down) {
|
||||
if (receives_input () && !_buffer_data_set) {
|
||||
|
||||
/* external ports use JACK's memory unless otherwise noted */
|
||||
_buffer->set_data ((Sample *) jack_port_get_buffer (_jack_port, nframes) + offset, nframes);
|
||||
|
||||
if (external()) {
|
||||
if (!using_internal_data()) {
|
||||
_buffer->set_data ((Sample *) jack_port_get_buffer (_jack_port, nframes) + offset, nframes);
|
||||
} else {
|
||||
_buffer->silence (nframes, offset);
|
||||
}
|
||||
}
|
||||
|
||||
mixdown (nframes, offset, !external ());
|
||||
}
|
||||
|
||||
return *_buffer;
|
||||
|
@ -103,82 +81,5 @@ AudioPort::get_audio_buffer (nframes_t nframes, nframes_t offset)
|
|||
void
|
||||
AudioPort::cycle_end (nframes_t nframes, nframes_t offset)
|
||||
{
|
||||
_has_been_mixed_down = false;
|
||||
}
|
||||
|
||||
void
|
||||
AudioPort::mixdown (nframes_t cnt, nframes_t offset, bool first_overwrite)
|
||||
{
|
||||
/* note: this is only called for input ports */
|
||||
|
||||
if (_connections.empty()) {
|
||||
|
||||
/* no internal mixing to do, so for internal ports
|
||||
just make sure the buffer is silent.
|
||||
*/
|
||||
|
||||
if (!external()) {
|
||||
_buffer->silence (cnt, offset);
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
set<Port*>::const_iterator p = _connections.begin();
|
||||
|
||||
/* mix in internally-connected ports. if this is an external port
|
||||
then it may already have data present from JACK. in that case, we
|
||||
do not want to overwrite that data, so we skip the initial ::read_from()
|
||||
call and do everything with accumulate_from()
|
||||
*/
|
||||
|
||||
if (!external()) {
|
||||
_buffer->read_from (dynamic_cast<AudioPort*>(*p)->get_audio_buffer (cnt, offset), cnt, offset);
|
||||
++p;
|
||||
|
||||
}
|
||||
|
||||
for (; p != _connections.end (); ++p) {
|
||||
_buffer->accumulate_from (dynamic_cast<AudioPort*>(*p)->get_audio_buffer (cnt, offset), cnt, offset);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
/* XXX horrible heuristic designed to check that we worked the whole buffer.
|
||||
Needs fixing but its a hard problem.
|
||||
*/
|
||||
|
||||
if (cnt && offset == 0) {
|
||||
_has_been_mixed_down = true;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
AudioPort::reset ()
|
||||
{
|
||||
Port::reset ();
|
||||
|
||||
if (_buffer->capacity () != 0) {
|
||||
_buffer->resize (_engine->frames_per_cycle ());
|
||||
_buffer->clear ();
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
AudioPort::using_internal_data () const
|
||||
{
|
||||
return _internal_buffer;
|
||||
}
|
||||
|
||||
void
|
||||
AudioPort::use_internal_data ()
|
||||
{
|
||||
_buffer->replace_data (_buffer->capacity());
|
||||
_internal_buffer = true;
|
||||
}
|
||||
|
||||
void
|
||||
AudioPort::use_external_data ()
|
||||
{
|
||||
_internal_buffer = false;
|
||||
_buffer->drop_data ();
|
||||
_buffer_data_set = false;
|
||||
}
|
||||
|
|
|
@ -40,7 +40,6 @@
|
|||
#include <ardour/utils.h>
|
||||
#include <ardour/buffer_set.h>
|
||||
#include <ardour/audio_buffer.h>
|
||||
#include <ardour/internal_send.h>
|
||||
#include "i18n.h"
|
||||
|
||||
using namespace std;
|
||||
|
@ -66,8 +65,6 @@ AudioTrack::AudioTrack (Session& sess, string name, Route::Flag flag, TrackMode
|
|||
|
||||
_session.add_diskstream (ds);
|
||||
|
||||
_session.RouteAdded.connect (mem_fun (*this, &AudioTrack::catch_up_on_busses));
|
||||
|
||||
set_diskstream (boost::dynamic_pointer_cast<AudioDiskstream> (ds), this);
|
||||
}
|
||||
|
||||
|
@ -75,47 +72,12 @@ AudioTrack::AudioTrack (Session& sess, const XMLNode& node)
|
|||
: Track (sess, node)
|
||||
{
|
||||
_set_state (node, false);
|
||||
|
||||
_session.RouteAdded.connect (mem_fun (*this, &AudioTrack::catch_up_on_busses));
|
||||
}
|
||||
|
||||
AudioTrack::~AudioTrack ()
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
AudioTrack::catch_up_on_busses (RouteList& added)
|
||||
{
|
||||
if (is_hidden()) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (RouteList::iterator x = added.begin(); x != added.end(); ++x) {
|
||||
if (boost::dynamic_pointer_cast<Track>(*x) == 0 && (*x)->default_type() == DataType::AUDIO) {
|
||||
/* Audio bus */
|
||||
if (!(*x)->is_master() && !(*x)->is_control()) {
|
||||
add_internal_send (*x);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
AudioTrack::add_internal_send (boost::shared_ptr<Route> r)
|
||||
{
|
||||
boost::shared_ptr<InternalSend> is (new InternalSend (_session, PreFader, r));
|
||||
|
||||
cerr << name() << " Adding processor\n";
|
||||
|
||||
add_processor (is, 0);
|
||||
|
||||
cerr << "After add, we have " << _processors.size() << endl;
|
||||
|
||||
/* note: if adding failed, the InternalSend will be cleaned up automatically when
|
||||
the shared_ptr goes out of scope.
|
||||
*/
|
||||
}
|
||||
|
||||
int
|
||||
AudioTrack::set_mode (TrackMode m)
|
||||
{
|
||||
|
|
|
@ -576,28 +576,23 @@ AudioEngine::port_registration_failure (const std::string& portname)
|
|||
}
|
||||
|
||||
Port *
|
||||
AudioEngine::register_port (DataType dtype, const string& portname, bool input, bool publish)
|
||||
AudioEngine::register_port (DataType dtype, const string& portname, bool input)
|
||||
{
|
||||
Port* newport = 0;
|
||||
|
||||
/*cerr << "trying to register port with name " << portname << endl;*/
|
||||
try {
|
||||
if (dtype == DataType::AUDIO) {
|
||||
newport = new AudioPort (portname, (input ? Port::IsInput : Port::IsOutput), publish, frames_per_cycle());
|
||||
newport = new AudioPort (portname, (input ? Port::IsInput : Port::IsOutput));
|
||||
} else if (dtype == DataType::MIDI) {
|
||||
newport = new MidiPort (portname, (input ? Port::IsInput : Port::IsOutput), publish, frames_per_cycle());
|
||||
newport = new MidiPort (portname, (input ? Port::IsInput : Port::IsOutput));
|
||||
} else {
|
||||
throw unknown_type();
|
||||
}
|
||||
|
||||
/*cerr << "successfully got port " << portname << " with address " << newport << endl;*/
|
||||
|
||||
RCUWriter<Ports> writer (ports);
|
||||
boost::shared_ptr<Ports> ps = writer.get_copy ();
|
||||
/*cerr << "Address of ports list: " << ps << endl
|
||||
<< "Ports set size before insert: " << ps->size() << endl;*/
|
||||
ps->insert (ps->begin(), newport);
|
||||
/*cerr << "Ports set size after insert: " << ps->size() << endl;*/
|
||||
|
||||
/* writer goes out of scope, forces update */
|
||||
|
||||
|
@ -610,15 +605,15 @@ AudioEngine::register_port (DataType dtype, const string& portname, bool input,
|
|||
}
|
||||
|
||||
Port *
|
||||
AudioEngine::register_input_port (DataType type, const string& portname, bool publish)
|
||||
AudioEngine::register_input_port (DataType type, const string& portname)
|
||||
{
|
||||
return register_port (type, portname, true, publish);
|
||||
return register_port (type, portname, true);
|
||||
}
|
||||
|
||||
Port *
|
||||
AudioEngine::register_output_port (DataType type, const string& portname, bool publish)
|
||||
AudioEngine::register_output_port (DataType type, const string& portname)
|
||||
{
|
||||
return register_port (type, portname, false, publish);
|
||||
return register_port (type, portname, false);
|
||||
}
|
||||
|
||||
int
|
||||
|
|
|
@ -1,213 +0,0 @@
|
|||
/*
|
||||
Copyright (C) 2009 Paul Davis
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
|
||||
*/
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
#include <pbd/xml++.h>
|
||||
|
||||
#include <ardour/internal_send.h>
|
||||
#include <ardour/session.h>
|
||||
#include <ardour/port.h>
|
||||
#include <ardour/audio_port.h>
|
||||
#include <ardour/buffer_set.h>
|
||||
#include <ardour/meter.h>
|
||||
#include <ardour/panner.h>
|
||||
#include <ardour/io.h>
|
||||
|
||||
#include "i18n.h"
|
||||
|
||||
using namespace ARDOUR;
|
||||
using namespace PBD;
|
||||
|
||||
InternalSend::InternalSend (Session& s, Placement p, boost::shared_ptr<IO> dst)
|
||||
: IOProcessor (s, string_compose (_(">%1"), dst->name()), p,
|
||||
-1, -1, -1, -1,
|
||||
DataType::AUDIO, false)
|
||||
, destination (dst)
|
||||
{
|
||||
_metering = false;
|
||||
|
||||
destination->input_changed.connect (mem_fun (*this, &InternalSend::destination_io_config_changed));
|
||||
|
||||
destination_io_config_changed (ConfigurationChanged, this);
|
||||
|
||||
ProcessorCreated (this); /* EMIT SIGNAL */
|
||||
}
|
||||
|
||||
InternalSend::~InternalSend ()
|
||||
{
|
||||
GoingAway ();
|
||||
}
|
||||
|
||||
void
|
||||
InternalSend::destination_io_config_changed (IOChange c, void* src)
|
||||
{
|
||||
if (!(c & ConfigurationChanged)) {
|
||||
return;
|
||||
}
|
||||
|
||||
_io->disconnect_outputs (this);
|
||||
|
||||
_io->ensure_io (ChanCount::ZERO, destination->n_inputs(), false, this);
|
||||
|
||||
PortSet::const_iterator us (_io->outputs().begin());
|
||||
PortSet::const_iterator them (destination->inputs().begin ());
|
||||
|
||||
for (; us != _io->outputs().end() && them != destination->inputs().end(); ++us, ++them) {
|
||||
(const_cast<Port*>(&(*us)))->connect (const_cast<Port*>(&(*them)));
|
||||
}
|
||||
}
|
||||
|
||||
XMLNode&
|
||||
InternalSend::get_state(void)
|
||||
{
|
||||
fatal << X_("InternalSend::get_state() called - should never happen") << endmsg;
|
||||
/*NOTREACHED*/
|
||||
return *(new XMLNode ("foo"));
|
||||
}
|
||||
|
||||
int
|
||||
InternalSend::set_state(const XMLNode& node)
|
||||
{
|
||||
fatal << X_("InternalSend::set_state() called - should never happen") << endmsg;
|
||||
/*NOTREACHED*/
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
InternalSend::run_in_place (BufferSet& bufs, nframes_t start_frame, nframes_t end_frame, nframes_t nframes, nframes_t offset)
|
||||
{
|
||||
if (active()) {
|
||||
|
||||
// we have to copy the input, because IO::deliver_output may alter the buffers
|
||||
// in-place, which a send must never do. otherwise its gain settings will
|
||||
// affect the signal seen later in the parent Route.
|
||||
|
||||
// BufferSet& sendbufs = _session.get_mix_buffers(bufs.count());
|
||||
|
||||
// sendbufs.read_from (bufs, nframes);
|
||||
// assert(sendbufs.count() == bufs.count());
|
||||
|
||||
_io->deliver_output (bufs, start_frame, end_frame, nframes, offset);
|
||||
|
||||
if (_metering) {
|
||||
if (_io->effective_gain() == 0) {
|
||||
_io->peak_meter().reset();
|
||||
} else {
|
||||
_io->peak_meter().run_in_place(_io->output_buffers(), start_frame, end_frame, nframes, offset);
|
||||
}
|
||||
}
|
||||
|
||||
} else {
|
||||
_io->silence (nframes, offset);
|
||||
if (_metering) {
|
||||
_io->peak_meter().reset();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
InternalSend::set_metering (bool yn)
|
||||
{
|
||||
_metering = yn;
|
||||
|
||||
if (!_metering) {
|
||||
/* XXX possible thread hazard here */
|
||||
_io->peak_meter().reset();
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
InternalSend::can_support_io_configuration (const ChanCount& in, ChanCount& out_is_ignored) const
|
||||
{
|
||||
/* number of outputs is fixed (though mutable by changing the I/O configuration
|
||||
of the destination)
|
||||
*/
|
||||
|
||||
cerr << "IS: testing I/O config in=" << in.n_audio() << " out=" << out_is_ignored.n_audio() << endl;
|
||||
|
||||
if (in == _io->n_outputs()) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
bool
|
||||
InternalSend::configure_io (ChanCount in, ChanCount out)
|
||||
{
|
||||
cerr << "Configure IS for in " << in.n_audio() << " out = " << out.n_audio() << endl;
|
||||
|
||||
/* we're transparent no matter what. fight the power. */
|
||||
|
||||
if (out != in) {
|
||||
return false;
|
||||
}
|
||||
|
||||
_io->set_output_maximum (in);
|
||||
_io->set_output_minimum (in);
|
||||
_io->set_input_maximum (ChanCount::ZERO);
|
||||
_io->set_input_minimum (ChanCount::ZERO);
|
||||
|
||||
out = _io->n_outputs();
|
||||
|
||||
Processor::configure_io(in, out);
|
||||
|
||||
_io->reset_panner();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
ChanCount
|
||||
InternalSend::output_streams() const
|
||||
{
|
||||
// this method reflects the idea that from the perspective of the Route's ProcessorList,
|
||||
// a send is just a passthrough. that doesn't match what the Send actually does with its
|
||||
// data, but since what it does is invisible to the Route, it appears to be a passthrough.
|
||||
|
||||
return _io->n_outputs ();
|
||||
}
|
||||
|
||||
ChanCount
|
||||
InternalSend::input_streams() const
|
||||
{
|
||||
return _configured_input;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
InternalSend::expect_inputs (const ChanCount& expected)
|
||||
{
|
||||
if (expected != expected_inputs) {
|
||||
expected_inputs = expected;
|
||||
_io->reset_panner ();
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
InternalSend::activate ()
|
||||
{
|
||||
Processor::activate ();
|
||||
}
|
||||
|
||||
void
|
||||
InternalSend::deactivate ()
|
||||
{
|
||||
Processor::deactivate ();
|
||||
}
|
|
@ -102,13 +102,12 @@ static double direct_gain_to_control (gain_t gain) {
|
|||
*/
|
||||
IO::IO (Session& s, const string& name,
|
||||
int input_min, int input_max, int output_min, int output_max,
|
||||
DataType default_type, bool public_ports)
|
||||
DataType default_type)
|
||||
: SessionObject(s, name),
|
||||
AutomatableControls (s),
|
||||
_output_buffers (new BufferSet()),
|
||||
_active(true),
|
||||
_default_type (default_type),
|
||||
_public_ports (public_ports),
|
||||
_input_minimum (ChanCount::ZERO),
|
||||
_input_maximum (ChanCount::INFINITE),
|
||||
_output_minimum (ChanCount::ZERO),
|
||||
|
@ -166,7 +165,6 @@ IO::IO (Session& s, const XMLNode& node, DataType dt)
|
|||
_default_type (dt)
|
||||
{
|
||||
_meter = new PeakMeter (_session);
|
||||
_public_ports = true; // XXX get this from node
|
||||
_panner = 0;
|
||||
deferred_state = 0;
|
||||
no_panner_reset = false;
|
||||
|
@ -644,7 +642,7 @@ IO::add_output_port (string destination, void* src, DataType type)
|
|||
|
||||
string portname = build_legal_port_name (type, false);
|
||||
|
||||
if ((our_port = _session.engine().register_output_port (type, portname, _public_ports)) == 0) {
|
||||
if ((our_port = _session.engine().register_output_port (type, portname)) == 0) {
|
||||
error << string_compose(_("IO: cannot register output port %1"), portname) << endmsg;
|
||||
return -1;
|
||||
}
|
||||
|
@ -748,7 +746,7 @@ IO::add_input_port (string source, void* src, DataType type)
|
|||
|
||||
string portname = build_legal_port_name (type, true);
|
||||
|
||||
if ((our_port = _session.engine().register_input_port (type, portname, _public_ports)) == 0) {
|
||||
if ((our_port = _session.engine().register_input_port (type, portname)) == 0) {
|
||||
error << string_compose(_("IO: cannot register input port %1"), portname) << endmsg;
|
||||
return -1;
|
||||
}
|
||||
|
@ -850,7 +848,7 @@ IO::ensure_inputs_locked (ChanCount count, bool clear, void* src)
|
|||
|
||||
try {
|
||||
|
||||
if ((input_port = _session.engine().register_input_port (*t, portname, _public_ports)) == 0) {
|
||||
if ((input_port = _session.engine().register_input_port (*t, portname)) == 0) {
|
||||
error << string_compose(_("IO: cannot register input port %1"), portname) << endmsg;
|
||||
return -1;
|
||||
}
|
||||
|
@ -948,7 +946,7 @@ IO::ensure_io (ChanCount in, ChanCount out, bool clear, void* src)
|
|||
string portname = build_legal_port_name (*t, true);
|
||||
|
||||
try {
|
||||
if ((port = _session.engine().register_input_port (*t, portname, _public_ports)) == 0) {
|
||||
if ((port = _session.engine().register_input_port (*t, portname)) == 0) {
|
||||
error << string_compose(_("IO: cannot register input port %1"), portname) << endmsg;
|
||||
return -1;
|
||||
}
|
||||
|
@ -972,7 +970,7 @@ IO::ensure_io (ChanCount in, ChanCount out, bool clear, void* src)
|
|||
string portname = build_legal_port_name (*t, false);
|
||||
|
||||
try {
|
||||
if ((port = _session.engine().register_output_port (*t, portname, _public_ports)) == 0) {
|
||||
if ((port = _session.engine().register_output_port (*t, portname)) == 0) {
|
||||
error << string_compose(_("IO: cannot register output port %1"), portname) << endmsg;
|
||||
return -1;
|
||||
}
|
||||
|
@ -1087,7 +1085,7 @@ IO::ensure_outputs_locked (ChanCount count, bool clear, void* src)
|
|||
|
||||
string portname = build_legal_port_name (*t, false);
|
||||
|
||||
if ((output_port = _session.engine().register_output_port (*t, portname, _public_ports)) == 0) {
|
||||
if ((output_port = _session.engine().register_output_port (*t, portname)) == 0) {
|
||||
error << string_compose(_("IO: cannot register output port %1"), portname) << endmsg;
|
||||
return -1;
|
||||
}
|
||||
|
|
|
@ -46,10 +46,9 @@ using namespace PBD;
|
|||
IOProcessor::IOProcessor (Session& s, const string& name, Placement p,
|
||||
int input_min, int input_max,
|
||||
int output_min, int output_max,
|
||||
DataType dtype,
|
||||
bool public_ports)
|
||||
DataType dtype)
|
||||
: Processor(s, name, p)
|
||||
, _io (new IO(s, name, input_min, input_max, output_min, output_max, dtype, public_ports))
|
||||
, _io (new IO(s, name, input_min, input_max, output_min, output_max, dtype))
|
||||
{
|
||||
_active = false;
|
||||
_sort_key = 0;
|
||||
|
|
|
@ -25,13 +25,13 @@
|
|||
using namespace ARDOUR;
|
||||
using namespace std;
|
||||
|
||||
MidiPort::MidiPort (const std::string& name, Flags flags, bool ext, nframes_t capacity)
|
||||
: Port (name, DataType::MIDI, flags, ext)
|
||||
MidiPort::MidiPort (const std::string& name, Flags flags)
|
||||
: Port (name, DataType::MIDI, flags)
|
||||
, _has_been_mixed_down (false)
|
||||
{
|
||||
// FIXME: size kludge (see BufferSet::ensure_buffers)
|
||||
// Jack needs to tell us this
|
||||
_buffer = new MidiBuffer (capacity * 32);
|
||||
_buffer = new MidiBuffer (1024 * 32);
|
||||
}
|
||||
|
||||
MidiPort::~MidiPort()
|
||||
|
@ -43,13 +43,11 @@ MidiPort::~MidiPort()
|
|||
void
|
||||
MidiPort::cycle_start (nframes_t nframes, nframes_t offset)
|
||||
{
|
||||
if (external ()) {
|
||||
_buffer->clear ();
|
||||
assert (_buffer->size () == 0);
|
||||
|
||||
if (sends_output ()) {
|
||||
jack_midi_clear_buffer (jack_port_get_buffer (_jack_port, nframes));
|
||||
}
|
||||
_buffer->clear ();
|
||||
assert (_buffer->size () == 0);
|
||||
|
||||
if (sends_output ()) {
|
||||
jack_midi_clear_buffer (jack_port_get_buffer (_jack_port, nframes));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -62,41 +60,26 @@ MidiPort::get_midi_buffer (nframes_t nframes, nframes_t offset)
|
|||
|
||||
if (receives_input ()) {
|
||||
|
||||
if (external ()) {
|
||||
void* jack_buffer = jack_port_get_buffer (_jack_port, nframes);
|
||||
const nframes_t event_count = jack_midi_get_event_count(jack_buffer);
|
||||
|
||||
void* jack_buffer = jack_port_get_buffer (_jack_port, nframes);
|
||||
const nframes_t event_count = jack_midi_get_event_count(jack_buffer);
|
||||
|
||||
assert (event_count < _buffer->capacity());
|
||||
|
||||
jack_midi_event_t ev;
|
||||
|
||||
for (nframes_t i = 0; i < event_count; ++i) {
|
||||
|
||||
jack_midi_event_get (&ev, jack_buffer, i);
|
||||
|
||||
// i guess this should do but i leave it off to test the rest first.
|
||||
//if (ev.time > offset && ev.time < offset+nframes)
|
||||
_buffer->push_back (ev);
|
||||
}
|
||||
|
||||
if (nframes) {
|
||||
_has_been_mixed_down = true;
|
||||
}
|
||||
|
||||
if (!_connections.empty()) {
|
||||
mixdown (nframes, offset, false);
|
||||
}
|
||||
|
||||
} else {
|
||||
assert (event_count < _buffer->capacity());
|
||||
|
||||
if (_connections.empty()) {
|
||||
_buffer->silence (nframes, offset);
|
||||
} else {
|
||||
mixdown (nframes, offset, true);
|
||||
}
|
||||
jack_midi_event_t ev;
|
||||
|
||||
for (nframes_t i = 0; i < event_count; ++i) {
|
||||
|
||||
jack_midi_event_get (&ev, jack_buffer, i);
|
||||
|
||||
// i guess this should do but i leave it off to test the rest first.
|
||||
//if (ev.time > offset && ev.time < offset+nframes)
|
||||
_buffer->push_back (ev);
|
||||
}
|
||||
|
||||
|
||||
if (nframes) {
|
||||
_has_been_mixed_down = true;
|
||||
}
|
||||
|
||||
} else {
|
||||
_buffer->silence (nframes, offset);
|
||||
}
|
||||
|
@ -114,7 +97,7 @@ MidiPort::cycle_end (nframes_t nframes, nframes_t offset)
|
|||
{
|
||||
#if 0
|
||||
|
||||
if (external () && sends_output ()) {
|
||||
if (sends_output ()) {
|
||||
/* FIXME: offset */
|
||||
|
||||
// We're an output - copy events from source buffer to Jack buffer
|
||||
|
@ -142,7 +125,7 @@ MidiPort::flush_buffers (nframes_t nframes, nframes_t offset)
|
|||
{
|
||||
/* FIXME: offset */
|
||||
|
||||
if (external () && sends_output ()) {
|
||||
if (sends_output ()) {
|
||||
|
||||
void* jack_buffer = jack_port_get_buffer (_jack_port, nframes);
|
||||
|
||||
|
@ -158,20 +141,3 @@ MidiPort::flush_buffers (nframes_t nframes, nframes_t offset)
|
|||
}
|
||||
}
|
||||
|
||||
void
|
||||
MidiPort::mixdown (nframes_t cnt, nframes_t offset, bool first_overwrite)
|
||||
{
|
||||
set<Port*>::const_iterator p = _connections.begin();
|
||||
|
||||
if (first_overwrite) {
|
||||
_buffer->read_from ((dynamic_cast<MidiPort*>(*p))->get_midi_buffer (cnt, offset), cnt, offset);
|
||||
++p;
|
||||
}
|
||||
|
||||
// XXX DAVE: this is just a guess
|
||||
|
||||
for (; p != _connections.end(); ++p) {
|
||||
_buffer->merge (*_buffer, (dynamic_cast<MidiPort*>(*p))->get_midi_buffer (cnt, offset));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -31,10 +31,8 @@ using namespace ARDOUR;
|
|||
AudioEngine* Port::_engine = 0;
|
||||
|
||||
/** @param n Port short name */
|
||||
Port::Port (std::string const & n, DataType t, Flags f, bool e)
|
||||
: _jack_port (0)
|
||||
, _last_monitor (false)
|
||||
, _latency (0)
|
||||
Port::Port (std::string const & n, DataType t, Flags f)
|
||||
: _last_monitor (false)
|
||||
, _name (n)
|
||||
, _flags (f)
|
||||
{
|
||||
|
@ -46,91 +44,29 @@ Port::Port (std::string const & n, DataType t, Flags f, bool e)
|
|||
|
||||
assert (_name.find_first_of (':') == std::string::npos);
|
||||
|
||||
if (e) {
|
||||
try {
|
||||
cerr << "NEW PORT " << _name << " ext = " << e << endl;
|
||||
do_make_external (t);
|
||||
}
|
||||
catch (...) {
|
||||
throw failed_constructor ();
|
||||
}
|
||||
if ((_jack_port = jack_port_register (_engine->jack (), _name.c_str (), t.to_jack_type (), _flags, 0)) == 0) {
|
||||
throw failed_constructor ();
|
||||
}
|
||||
}
|
||||
|
||||
/** Port destructor */
|
||||
Port::~Port ()
|
||||
{
|
||||
if (_jack_port) {
|
||||
jack_port_unregister (_engine->jack (), _jack_port);
|
||||
}
|
||||
}
|
||||
|
||||
/** Make this port externally visible by setting it up to use a JACK port.
|
||||
* @param t Data type, so that we can call this method from the constructor.
|
||||
*/
|
||||
void
|
||||
Port::do_make_external (DataType t)
|
||||
{
|
||||
if (_jack_port) {
|
||||
/* already external */
|
||||
return;
|
||||
}
|
||||
|
||||
if ((_jack_port = jack_port_register (_engine->jack (), _name.c_str (), t.to_jack_type (), _flags, 0)) == 0) {
|
||||
throw std::runtime_error ("Could not register JACK port");
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
Port::make_external ()
|
||||
{
|
||||
do_make_external (type ());
|
||||
jack_port_unregister (_engine->jack (), _jack_port);
|
||||
}
|
||||
|
||||
/** @return true if this port is connected to anything */
|
||||
bool
|
||||
Port::connected () const
|
||||
{
|
||||
if (!_connections.empty ()) {
|
||||
/* connected to a Port* */
|
||||
return true;
|
||||
}
|
||||
|
||||
if (_jack_port == 0) {
|
||||
/* not using a JACK port, so can't be connected to anything else */
|
||||
return false;
|
||||
}
|
||||
|
||||
return (jack_port_connected (_jack_port) != 0);
|
||||
}
|
||||
|
||||
/** @return true if this port is connected to anything via an external port */
|
||||
bool
|
||||
Port::externally_connected () const
|
||||
{
|
||||
if (_jack_port == 0) {
|
||||
/* not using a JACK port, so can't be connected to anything else */
|
||||
return false;
|
||||
}
|
||||
|
||||
return (jack_port_connected (_jack_port) != 0);
|
||||
}
|
||||
|
||||
int
|
||||
Port::disconnect_all ()
|
||||
{
|
||||
/* Disconnect from Port* connections */
|
||||
for (std::set<Port*>::iterator i = _connections.begin (); i != _connections.end (); ++i) {
|
||||
(*i)->_connections.erase (this);
|
||||
}
|
||||
|
||||
_connections.clear ();
|
||||
|
||||
/* And JACK connections */
|
||||
jack_port_disconnect (_engine->jack(), _jack_port);
|
||||
_named_connections.clear ();
|
||||
|
||||
check_buffer_status ();
|
||||
_connections.clear ();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -141,22 +77,7 @@ Port::disconnect_all ()
|
|||
bool
|
||||
Port::connected_to (std::string const & o) const
|
||||
{
|
||||
std::string const full = _engine->make_port_name_non_relative (o);
|
||||
std::string const shrt = _engine->make_port_name_non_relative (o);
|
||||
|
||||
if (_jack_port && jack_port_connected_to (_jack_port, full.c_str ())) {
|
||||
/* connected via JACK */
|
||||
return true;
|
||||
}
|
||||
|
||||
for (std::set<Port*>::iterator i = _connections.begin (); i != _connections.end (); ++i) {
|
||||
if ((*i)->name () == shrt) {
|
||||
/* connected internally */
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
return jack_port_connected_to (_jack_port, _engine->make_port_name_non_relative(o).c_str ());
|
||||
}
|
||||
|
||||
/** @param o Filled in with port full names of ports that we are connected to */
|
||||
|
@ -165,24 +86,14 @@ Port::get_connections (std::vector<std::string> & c) const
|
|||
{
|
||||
int n = 0;
|
||||
|
||||
/* JACK connections */
|
||||
if (_jack_port) {
|
||||
const char** jc = jack_port_get_connections (_jack_port);
|
||||
if (jc) {
|
||||
for (int i = 0; jc[i]; ++i) {
|
||||
c.push_back (jc[i]);
|
||||
++n;
|
||||
}
|
||||
const char** jc = jack_port_get_connections (_jack_port);
|
||||
if (jc) {
|
||||
for (int i = 0; jc[i]; ++i) {
|
||||
c.push_back (jc[i]);
|
||||
++n;
|
||||
}
|
||||
}
|
||||
|
||||
/* Internal connections */
|
||||
for (std::set<Port*>::iterator i = _connections.begin (); i != _connections.end (); ++i) {
|
||||
std::string const full = _engine->make_port_name_non_relative ((*i)->name());
|
||||
c.push_back (full);
|
||||
++n;
|
||||
}
|
||||
|
||||
|
||||
return n;
|
||||
}
|
||||
|
||||
|
@ -192,36 +103,19 @@ Port::connect (std::string const & other)
|
|||
/* caller must hold process lock */
|
||||
|
||||
std::string const other_shrt = _engine->make_port_name_non_relative (other);
|
||||
|
||||
Port* p = _engine->get_port_by_name_locked (other_shrt);
|
||||
|
||||
int r;
|
||||
|
||||
if (p && !p->external ()) {
|
||||
/* non-external Ardour port; connect using Port* */
|
||||
r = connect (p);
|
||||
std::string const this_shrt = _engine->make_port_name_non_relative (_name);
|
||||
|
||||
int r = 0;
|
||||
|
||||
if (sends_output ()) {
|
||||
r = jack_connect (_engine->jack (), this_shrt.c_str (), other_shrt.c_str ());
|
||||
} else {
|
||||
/* connect using name */
|
||||
|
||||
/* for this to work, we must be an external port */
|
||||
if (!external ()) {
|
||||
make_external ();
|
||||
}
|
||||
|
||||
std::string const this_shrt = _engine->make_port_name_non_relative (_name);
|
||||
|
||||
if (sends_output ()) {
|
||||
r = jack_connect (_engine->jack (), this_shrt.c_str (), other_shrt.c_str ());
|
||||
} else {
|
||||
r = jack_connect (_engine->jack (), other_shrt.c_str (), this_shrt.c_str());
|
||||
}
|
||||
|
||||
if (r == 0) {
|
||||
_named_connections.insert (other);
|
||||
}
|
||||
r = jack_connect (_engine->jack (), other_shrt.c_str (), this_shrt.c_str());
|
||||
}
|
||||
|
||||
if (r == 0) {
|
||||
_connections.insert (other);
|
||||
}
|
||||
|
||||
check_buffer_status ();
|
||||
|
||||
return r;
|
||||
}
|
||||
|
@ -232,32 +126,21 @@ Port::disconnect (std::string const & other)
|
|||
/* caller must hold process lock */
|
||||
|
||||
std::string const other_shrt = _engine->make_port_name_non_relative (other);
|
||||
std::string const this_shrt = _engine->make_port_name_non_relative (_name);
|
||||
|
||||
int r = 0;
|
||||
|
||||
Port* p = _engine->get_port_by_name_locked (other_shrt);
|
||||
int r;
|
||||
|
||||
if (p && !p->external ()) {
|
||||
/* non-external Ardour port; disconnect using Port* */
|
||||
r = disconnect (p);
|
||||
if (sends_output ()) {
|
||||
r = jack_disconnect (_engine->jack (), this_shrt.c_str (), other_shrt.c_str ());
|
||||
} else {
|
||||
/* disconnect using name */
|
||||
|
||||
std::string const this_shrt = _engine->make_port_name_non_relative (_name);
|
||||
|
||||
if (sends_output ()) {
|
||||
r = jack_disconnect (_engine->jack (), this_shrt.c_str (), other_shrt.c_str ());
|
||||
} else {
|
||||
r = jack_disconnect (_engine->jack (), other_shrt.c_str (), this_shrt.c_str ());
|
||||
}
|
||||
|
||||
if (r == 0) {
|
||||
_named_connections.erase (other);
|
||||
}
|
||||
|
||||
check_buffer_status ();
|
||||
r = jack_disconnect (_engine->jack (), other_shrt.c_str (), this_shrt.c_str ());
|
||||
}
|
||||
|
||||
return r;
|
||||
|
||||
if (r == 0) {
|
||||
_connections.erase (other);
|
||||
}
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
|
||||
|
@ -270,41 +153,13 @@ Port::connected_to (Port* o) const
|
|||
int
|
||||
Port::connect (Port* o)
|
||||
{
|
||||
/* caller must hold process lock */
|
||||
|
||||
if (external () && o->external ()) {
|
||||
/* we're both external; connect using name */
|
||||
return connect (o->name ());
|
||||
}
|
||||
|
||||
/* otherwise connect by Port* */
|
||||
_connections.insert (o);
|
||||
o->_connections.insert (this);
|
||||
|
||||
check_buffer_status ();
|
||||
o->check_buffer_status ();
|
||||
|
||||
return 0;
|
||||
return connect (o->name ());
|
||||
}
|
||||
|
||||
int
|
||||
Port::disconnect (Port* o)
|
||||
{
|
||||
if (external () && o->external ()) {
|
||||
/* we're both external; try disconnecting using name */
|
||||
int const r = disconnect (o->name ());
|
||||
if (r == 0) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
_connections.erase (o);
|
||||
o->_connections.erase (this);
|
||||
|
||||
check_buffer_status ();
|
||||
o->check_buffer_status ();
|
||||
|
||||
return 0;
|
||||
return disconnect (o->name ());
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -316,19 +171,13 @@ Port::set_engine (AudioEngine* e)
|
|||
void
|
||||
Port::ensure_monitor_input (bool yn)
|
||||
{
|
||||
if (_jack_port) {
|
||||
jack_port_ensure_monitor (_jack_port, yn);
|
||||
}
|
||||
jack_port_ensure_monitor (_jack_port, yn);
|
||||
}
|
||||
|
||||
bool
|
||||
Port::monitoring_input () const
|
||||
{
|
||||
if (_jack_port) {
|
||||
return jack_port_monitoring_input (_jack_port);
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
return jack_port_monitoring_input (_jack_port);
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -345,29 +194,19 @@ void
|
|||
Port::recompute_total_latency () const
|
||||
{
|
||||
#ifdef HAVE_JACK_RECOMPUTE_LATENCY
|
||||
if (_jack_port) {
|
||||
jack_recompute_total_latency (_engine->jack (), _jack_port);
|
||||
}
|
||||
jack_recompute_total_latency (_engine->jack (), _jack_port);
|
||||
#endif
|
||||
}
|
||||
|
||||
nframes_t
|
||||
Port::total_latency () const
|
||||
{
|
||||
if (_jack_port) {
|
||||
return jack_port_get_total_latency (_engine->jack (), _jack_port);
|
||||
} else {
|
||||
return _latency;
|
||||
}
|
||||
return jack_port_get_total_latency (_engine->jack (), _jack_port);
|
||||
}
|
||||
|
||||
int
|
||||
Port::reestablish ()
|
||||
{
|
||||
if (!_jack_port) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
_jack_port = jack_port_register (_engine->jack(), _name.c_str(), type().to_jack_type(), _flags, 0);
|
||||
|
||||
if (_jack_port == 0) {
|
||||
|
@ -386,11 +225,7 @@ Port::reconnect ()
|
|||
{
|
||||
/* caller must hold process lock; intended to be used only after reestablish() */
|
||||
|
||||
if (!_jack_port) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
for (std::set<string>::iterator i = _named_connections.begin(); i != _named_connections.end(); ++i) {
|
||||
for (std::set<string>::iterator i = _connections.begin(); i != _connections.end(); ++i) {
|
||||
if (connect (*i)) {
|
||||
return -1;
|
||||
}
|
||||
|
@ -405,63 +240,22 @@ Port::set_name (std::string const & n)
|
|||
{
|
||||
assert (_name.find_first_of (':') == std::string::npos);
|
||||
|
||||
int r = 0;
|
||||
|
||||
if (_jack_port) {
|
||||
r = jack_port_set_name (_jack_port, n.c_str());
|
||||
if (r == 0) {
|
||||
_name = n;
|
||||
}
|
||||
} else {
|
||||
int const r = jack_port_set_name (_jack_port, n.c_str());
|
||||
if (r == 0) {
|
||||
_name = n;
|
||||
}
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
void
|
||||
Port::set_latency (nframes_t n)
|
||||
{
|
||||
_latency = n;
|
||||
}
|
||||
|
||||
void
|
||||
Port::request_monitor_input (bool yn)
|
||||
{
|
||||
if (_jack_port) {
|
||||
jack_port_request_monitor (_jack_port, yn);
|
||||
}
|
||||
jack_port_request_monitor (_jack_port, yn);
|
||||
}
|
||||
|
||||
void
|
||||
Port::check_buffer_status ()
|
||||
Port::set_latency (nframes_t n)
|
||||
{
|
||||
if (external() && receives_input()) {
|
||||
if (!externally_connected()) {
|
||||
if (!_connections.empty()) {
|
||||
|
||||
/* There are no external connections, so the
|
||||
external port buffer will be the silent buffer. We cannot write into it.
|
||||
But we have to write somewhere because there is at least one internal
|
||||
connection that is supplying us with data.
|
||||
*/
|
||||
|
||||
if (!using_internal_data()) {
|
||||
use_internal_data ();
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
/* There are no external connections and no internal ones
|
||||
either, so we can revert to use the externally supplied
|
||||
buffer which will be silent (whatever the semantics of
|
||||
that are for a particular data type.
|
||||
*/
|
||||
|
||||
if (using_internal_data()) {
|
||||
use_external_data ();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
jack_port_set_latency (_jack_port, n);
|
||||
}
|
||||
|
|
|
@ -35,7 +35,6 @@
|
|||
#include <ardour/plugin_insert.h>
|
||||
#include <ardour/port_insert.h>
|
||||
#include <ardour/send.h>
|
||||
#include <ardour/internal_send.h>
|
||||
#include <ardour/session.h>
|
||||
#include <ardour/utils.h>
|
||||
#include <ardour/configuration.h>
|
||||
|
@ -1608,8 +1607,6 @@ Route::_reset_processor_counts (ProcessorStreams* err)
|
|||
|
||||
} else if (boost::dynamic_pointer_cast<Send> (*r) != 0) {
|
||||
++send_cnt;
|
||||
} else if (boost::dynamic_pointer_cast<InternalSend> (*r) != 0) {
|
||||
++send_cnt;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1673,7 +1670,6 @@ Route::_reset_processor_counts (ProcessorStreams* err)
|
|||
|
||||
for (r = _processors.begin(); r != _processors.end(); prev = r, ++r) {
|
||||
boost::shared_ptr<Send> s;
|
||||
boost::shared_ptr<InternalSend> is;
|
||||
|
||||
if ((s = boost::dynamic_pointer_cast<Send> (*r)) != 0) {
|
||||
|
||||
|
@ -1687,16 +1683,6 @@ Route::_reset_processor_counts (ProcessorStreams* err)
|
|||
s->expect_inputs ((*prev)->output_streams());
|
||||
}
|
||||
|
||||
} else if ((is = boost::dynamic_pointer_cast<InternalSend> (*r)) != 0) {
|
||||
|
||||
/* XXX ditto, but clean this inheritance pattern up someday soon */
|
||||
|
||||
if (r == _processors.begin()) {
|
||||
is->expect_inputs (n_inputs());
|
||||
} else {
|
||||
is->expect_inputs ((*prev)->output_streams());
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
max_audio = max ((*r)->output_streams ().n_audio(), max_audio);
|
||||
|
|
|
@ -60,7 +60,6 @@
|
|||
#include <ardour/cycle_timer.h>
|
||||
#include <ardour/data_type.h>
|
||||
#include <ardour/filename_extensions.h>
|
||||
#include <ardour/internal_send.h>
|
||||
#include <ardour/io_processor.h>
|
||||
#include <ardour/midi_diskstream.h>
|
||||
#include <ardour/midi_playlist.h>
|
||||
|
@ -3717,8 +3716,6 @@ Session::add_processor (Processor* processor)
|
|||
_plugin_inserts.insert (_plugin_inserts.begin(), plugin_insert);
|
||||
} else if ((send = dynamic_cast<Send *> (processor)) != 0) {
|
||||
_sends.insert (_sends.begin(), send);
|
||||
} else if (dynamic_cast<InternalSend *> (processor) != 0) {
|
||||
/* relax */
|
||||
} else {
|
||||
fatal << _("programming error: unknown type of Insert created!") << endmsg;
|
||||
/*NOTREACHED*/
|
||||
|
@ -3744,8 +3741,6 @@ Session::remove_processor (Processor* processor)
|
|||
}
|
||||
} else if ((plugin_insert = dynamic_cast<PluginInsert *> (processor)) != 0) {
|
||||
_plugin_inserts.remove (plugin_insert);
|
||||
} else if (dynamic_cast<InternalSend *> (processor) != 0) {
|
||||
/* relax */
|
||||
} else if ((send = dynamic_cast<Send *> (processor)) != 0) {
|
||||
list<Send*>::iterator x = find (_sends.begin(), _sends.end(), send);
|
||||
if (x != _sends.end()) {
|
||||
|
|
Loading…
Reference in New Issue
Block a user