revisit setting up processors during route construction; remove several more XML-based constructors; don't put () parens around inactive plugin names (we have a checkbox); improve management of send, return and insert bitslot IDs; clean up Diskstream construction a bit more

git-svn-id: svn://localhost/ardour2/branches/3.0@6819 d708f5d6-7413-0410-9779-e7cbd77b26cf
This commit is contained in:
Paul Davis 2010-04-01 01:24:13 +00:00
parent 50dd880d7e
commit c0c617902e
21 changed files with 268 additions and 481 deletions

View file

@ -177,10 +177,6 @@ ProcessorEntry::name () const
boost::shared_ptr<Send> send;
string name_display;
if (!_processor->active()) {
name_display = " (";
}
if ((send = boost::dynamic_pointer_cast<Send> (_processor)) != 0 &&
!boost::dynamic_pointer_cast<InternalSend>(_processor)) {
@ -214,10 +210,6 @@ ProcessorEntry::name () const
}
if (!_processor->active()) {
name_display += ')';
}
return name_display;
}
@ -1332,7 +1324,8 @@ ProcessorBox::paste_processor_state (const XMLNodeList& nlist, boost::shared_ptr
is a plugin.
*/
p.reset (new PluginInsert (*_session, **niter));
p.reset (new PluginInsert (*_session));
p->set_state (**niter, Stateful::current_state_version);
}
copies.push_back (p);

View file

@ -231,7 +231,7 @@ class AudioDiskstream : public Diskstream
void transport_stopped (struct tm&, time_t, bool abort);
void transport_looped (nframes_t transport_frame);
void init (Diskstream::Flag);
void init ();
void init_channel (ChannelInfo &chan);
void destroy_channel (ChannelInfo &chan);

View file

@ -216,8 +216,6 @@ class Diskstream : public SessionObject
uint32_t frames;
};
virtual void init (Flag);
virtual int use_new_write_source (uint32_t n=0) = 0;
virtual int find_and_use_playlist (const std::string&) = 0;

View file

@ -154,7 +154,7 @@ class MidiDiskstream : public Diskstream
void transport_stopped (struct tm&, time_t, bool abort);
void transport_looped (nframes_t transport_frame);
void init (Diskstream::Flag);
void init ();
int use_new_write_source (uint32_t n=0);

View file

@ -43,8 +43,7 @@ class Plugin;
class PluginInsert : public Processor
{
public:
PluginInsert (Session&, boost::shared_ptr<Plugin>);
PluginInsert (Session&, const XMLNode&);
PluginInsert (Session&, boost::shared_ptr<Plugin> = boost::shared_ptr<Plugin>());
~PluginInsert ();
static const std::string port_automation_node_name;

View file

@ -44,7 +44,6 @@ class PortInsert : public IOProcessor
{
public:
PortInsert (Session&, boost::shared_ptr<MuteMaster> mm);
PortInsert (Session&, boost::shared_ptr<MuteMaster> mm, const XMLNode&);
~PortInsert ();
XMLNode& state(bool full);

View file

@ -49,7 +49,6 @@ class Processor : public SessionObject, public AutomatableControls, public Laten
static const std::string state_node_name;
Processor(Session&, const std::string& name);
Processor(Session&, const XMLNode& node);
virtual ~Processor() { }
@ -98,8 +97,6 @@ class Processor : public SessionObject, public AutomatableControls, public Laten
void *get_gui () const { return _gui; }
void set_gui (void *p) { _gui = p; }
static PBD::Signal1<void,Processor*> ProcessorCreated;
PBD::Signal0<void> ActiveChanged;
PBD::Signal2<void,ChanCount,ChanCount> ConfigurationChanged;

View file

@ -38,7 +38,6 @@ class Return : public IOProcessor
{
public:
Return (Session&, bool internal = false);
Return (Session&, const XMLNode&, bool internal = false);
virtual ~Return ();
uint32_t bit_slot() const { return _bitslot; }

View file

@ -37,7 +37,6 @@ class Send : public Delivery
{
public:
Send (Session&, boost::shared_ptr<MuteMaster>, Delivery::Role r = Delivery::Send);
Send (Session&, boost::shared_ptr<MuteMaster>, const XMLNode&, int version = 3000, Delivery::Role r = Delivery::Send);
virtual ~Send ();
uint32_t bit_slot() const { return _bitslot; }

View file

@ -619,6 +619,9 @@ class Session : public PBD::StatefulDestructible, public PBD::ScopedConnectionLi
void mark_send_id (uint32_t);
void mark_return_id (uint32_t);
void mark_insert_id (uint32_t);
void unmark_send_id (uint32_t);
void unmark_return_id (uint32_t);
void unmark_insert_id (uint32_t);
/* s/w "RAID" management */
@ -1294,9 +1297,6 @@ class Session : public PBD::StatefulDestructible, public PBD::ScopedConnectionLi
boost::dynamic_bitset<uint32_t> return_bitset;
boost::dynamic_bitset<uint32_t> insert_bitset;
void add_processor (Processor *);
void remove_processor (Processor *);
/* S/W RAID */
struct space_and_path {

View file

@ -79,10 +79,7 @@ AudioDiskstream::AudioDiskstream (Session &sess, const string &name, Diskstream:
/* prevent any write sources from being created */
in_set_state = true;
init(flag);
use_new_playlist ();
in_set_state = false;
}
@ -92,7 +89,7 @@ AudioDiskstream::AudioDiskstream (Session& sess, const XMLNode& node)
, channels (new ChannelList)
{
in_set_state = true;
init (Recordable);
init ();
if (set_state (node, Stateful::loading_state_version)) {
in_set_state = false;
@ -107,10 +104,8 @@ AudioDiskstream::AudioDiskstream (Session& sess, const XMLNode& node)
}
void
AudioDiskstream::init (Diskstream::Flag f)
AudioDiskstream::init ()
{
Diskstream::init(f);
/* there are no channels at this point, so these
two calls just get speed_buffer_size and wrap_buffer
size setup without duplicating their code.

View file

@ -61,7 +61,7 @@ using namespace std;
using namespace ARDOUR;
using namespace PBD;
/* XXX This goes uninitialized when there is no ~/.ardour3 directory.
/* XXX This goes uninitialized when there is no ~/.config/ardour3 directory.
* I can't figure out why, so this will do for now (just stole the
* default from configuration_vars.h). 0 is not a good value for
* allocating buffer sizes..
@ -73,55 +73,97 @@ PBD::Signal0<void> Diskstream::DiskUnderrun;
Diskstream::Diskstream (Session &sess, const string &name, Flag flag)
: SessionObject(sess, name)
, i_am_the_modifier (0)
, _route (0)
, _record_enabled (0)
, _visible_speed (1.0f)
, _actual_speed (1.0f)
, _buffer_reallocation_required (false)
, _seek_required (false)
, force_refill (false)
, capture_start_frame (0)
, capture_captured (0)
, was_recording (false)
, adjust_capture_position (0)
, _capture_offset (0)
, _roll_delay (0)
, first_recordable_frame (max_frames)
, last_recordable_frame (max_frames)
, last_possibly_recording (0)
, _alignment_style (ExistingMaterial)
, _scrubbing (false)
, _slaved (false)
, loop_location (0)
, overwrite_frame (0)
, overwrite_offset (0)
, pending_overwrite (false)
, overwrite_queued (false)
, input_change_pending (NoChange)
, wrap_buffer_size (0)
, speed_buffer_size (0)
, _speed (1.0)
, _target_speed (_speed)
, file_frame (0)
, playback_sample (0)
, playback_distance (0)
, _read_data_count (0)
, _write_data_count (0)
, in_set_state (false)
, _persistent_alignment_style (ExistingMaterial)
, first_input_change (true)
, scrub_start (0)
, scrub_buffer_size (0)
, scrub_offset (0)
, _flags (flag)
{
init (flag);
}
Diskstream::Diskstream (Session& sess, const XMLNode& /*node*/)
: SessionObject(sess, "unnamed diskstream")
, i_am_the_modifier (0)
, _route (0)
, _record_enabled (0)
, _visible_speed (1.0f)
, _actual_speed (1.0f)
, _buffer_reallocation_required (false)
, _seek_required (false)
, force_refill (false)
, capture_start_frame (0)
, capture_captured (0)
, was_recording (false)
, adjust_capture_position (0)
, _capture_offset (0)
, _roll_delay (0)
, first_recordable_frame (max_frames)
, last_recordable_frame (max_frames)
, last_possibly_recording (0)
, _alignment_style (ExistingMaterial)
, _scrubbing (false)
, _slaved (false)
, loop_location (0)
, overwrite_frame (0)
, overwrite_offset (0)
, pending_overwrite (false)
, overwrite_queued (false)
, input_change_pending (NoChange)
, wrap_buffer_size (0)
, speed_buffer_size (0)
, _speed (1.0)
, _target_speed (_speed)
, file_frame (0)
, playback_sample (0)
, playback_distance (0)
, _read_data_count (0)
, _write_data_count (0)
, in_set_state (false)
, _persistent_alignment_style (ExistingMaterial)
, first_input_change (true)
, scrub_start (0)
, scrub_buffer_size (0)
, scrub_offset (0)
, _flags (Recordable)
{
init (Recordable);
}
void
Diskstream::init (Flag f)
{
_flags = f;
_route = 0;
_alignment_style = ExistingMaterial;
_persistent_alignment_style = ExistingMaterial;
first_input_change = true;
i_am_the_modifier = 0;
g_atomic_int_set (&_record_enabled, 0);
was_recording = false;
capture_start_frame = 0;
capture_captured = 0;
_visible_speed = 1.0f;
_actual_speed = 1.0f;
_buffer_reallocation_required = false;
_seek_required = false;
first_recordable_frame = max_frames;
last_recordable_frame = max_frames;
_roll_delay = 0;
_capture_offset = 0;
_slaved = false;
adjust_capture_position = 0;
last_possibly_recording = 0;
loop_location = 0;
wrap_buffer_size = 0;
speed_buffer_size = 0;
_speed = 1.0;
_target_speed = _speed;
file_frame = 0;
playback_sample = 0;
playback_distance = 0;
_read_data_count = 0;
_write_data_count = 0;
pending_overwrite = false;
overwrite_frame = 0;
overwrite_queued = false;
input_change_pending = NoChange;
}
Diskstream::~Diskstream ()

View file

@ -81,7 +81,7 @@ MidiDiskstream::MidiDiskstream (Session &sess, const string &name, Diskstream::F
in_set_state = true;
init(flag);
init ();
use_new_playlist ();
in_set_state = false;
@ -100,7 +100,7 @@ MidiDiskstream::MidiDiskstream (Session& sess, const XMLNode& node)
, _frames_read_from_ringbuffer(0)
{
in_set_state = true;
init (Recordable);
init ();
if (set_state (node, Stateful::loading_state_version)) {
in_set_state = false;
@ -115,10 +115,8 @@ MidiDiskstream::MidiDiskstream (Session& sess, const XMLNode& node)
}
void
MidiDiskstream::init (Diskstream::Flag f)
MidiDiskstream::init ()
{
Diskstream::init(f);
/* there are no channels at this point, so these
two calls just get speed_buffer_size and wrap_buffer
size setup without duplicating their code.

View file

@ -62,35 +62,16 @@ using namespace PBD;
const string PluginInsert::port_automation_node_name = "PortAutomation";
PluginInsert::PluginInsert (Session& s, boost::shared_ptr<Plugin> plug)
: Processor (s, plug->name())
: Processor (s, (plug ? plug->name() : string ("toBeRenamed")))
, _signal_analysis_collected_nframes(0)
, _signal_analysis_collect_nframes_max(0)
{
/* the first is the master */
_plugins.push_back (plug);
set_automatable ();
if (plug) {
_plugins.push_back (plug);
set_automatable ();
{
Glib::Mutex::Lock em (_session.engine().process_lock());
IO::PortCountChanged (max(input_streams(), output_streams()));
}
ProcessorCreated (this); /* EMIT SIGNAL */
}
PluginInsert::PluginInsert (Session& s, const XMLNode& node)
: Processor (s, "unnamed plugin insert"),
_signal_analysis_collected_nframes(0),
_signal_analysis_collect_nframes_max(0)
{
if (set_state (node, Stateful::loading_state_version)) {
throw failed_constructor();
}
_pending_active = _active;
{
Glib::Mutex::Lock em (_session.engine().process_lock());
IO::PortCountChanged (max(input_streams(), output_streams()));
}
@ -810,6 +791,8 @@ PluginInsert::set_state(const XMLNode& node, int version)
}
}
Processor::set_state (node, version);
if (version < 3000) {
for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
@ -823,13 +806,20 @@ PluginInsert::set_state(const XMLNode& node, int version)
set_parameter_state_2X (node, version);
} else {
Processor::set_state (node, version);
set_parameter_state (node, version);
}
// The name of the PluginInsert comes from the plugin, nothing else
_name = plugin->get_info()->name;
/* catch up on I/O */
{
Glib::Mutex::Lock em (_session.engine().process_lock());
IO::PortCountChanged (max(input_streams(), output_streams()));
}
return 0;
}

View file

@ -49,29 +49,11 @@ PortInsert::PortInsert (Session& s, boost::shared_ptr<MuteMaster> mm)
_latency_detect = false;
_latency_flush_frames = false;
_measured_latency = 0;
ProcessorCreated (this); /* EMIT SIGNAL */
}
PortInsert::PortInsert (Session& s, boost::shared_ptr<MuteMaster> mm, const XMLNode& node)
: IOProcessor (s, true, true, "unnamed port insert")
, _out (new Delivery (s, _output, mm, _name, Delivery::Insert))
{
_mtdm = 0;
_latency_detect = false;
_latency_flush_frames = false;
_measured_latency = 0;
if (set_state (node, Stateful::loading_state_version)) {
throw failed_constructor();
}
ProcessorCreated (this); /* EMIT SIGNAL */
}
PortInsert::~PortInsert ()
{
_session.unmark_insert_id (bitslot);
delete _mtdm;
}
@ -179,6 +161,18 @@ PortInsert::set_state (const XMLNode& node, int version)
XMLPropertyList plist;
const XMLProperty *prop;
const XMLNode* insert_node = &node;
// legacy sessions: search for child IOProcessor node
for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
if ((*niter)->name() == "IOProcessor") {
insert_node = *niter;
break;
}
}
Processor::set_state (*insert_node, version);
if ((prop = node.property ("type")) == 0) {
error << _("XML node describing port insert is missing the `type' field") << endmsg;
return -1;
@ -192,21 +186,12 @@ PortInsert::set_state (const XMLNode& node, int version)
if ((prop = node.property ("bitslot")) == 0) {
bitslot = _session.next_insert_id();
} else {
_session.unmark_insert_id (bitslot);
sscanf (prop->value().c_str(), "%" PRIu32, &bitslot);
_session.mark_insert_id (bitslot);
}
const XMLNode* insert_node = &node;
// legacy sessions: search for child IOProcessor node
for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
if ((*niter)->name() == "IOProcessor") {
insert_node = *niter;
break;
}
}
Processor::set_state (*insert_node, version);
set_name (string_compose (_("insert %1"), bitslot));
return 0;
}

View file

@ -56,8 +56,6 @@ using namespace std;
using namespace ARDOUR;
using namespace PBD;
PBD::Signal1<void,Processor*> Processor::ProcessorCreated;
// Always saved as Processor, but may be IOProcessor or Send in legacy sessions
const string Processor::state_node_name = "Processor";
@ -73,19 +71,6 @@ Processor::Processor(Session& session, const string& name)
{
}
Processor::Processor (Session& session, const XMLNode& node)
: SessionObject(session, "renameMe")
, AutomatableControls(session)
, _pending_active(false)
, _active(false)
, _next_ab_is_active(false)
, _configured(false)
, _gui(0)
, _display_to_user (true)
{
set_state (node, Stateful::loading_state_version);
}
XMLNode&
Processor::get_state (void)
{

View file

@ -45,12 +45,11 @@ Return::Return (Session& s, bool internal)
_amp.reset (new Amp (_session, boost::shared_ptr<MuteMaster>()));
_meter.reset (new PeakMeter (_session));
ProcessorCreated (this); /* EMIT SIGNAL */
}
Return::~Return ()
{
_session.unmark_return_id (_bitslot);
}
XMLNode&
@ -77,14 +76,6 @@ Return::set_state (const XMLNode& node, int version)
XMLNodeList nlist = node.children();
XMLNodeIterator niter;
const XMLProperty* prop;
if ((prop = node.property ("bitslot")) == 0) {
_bitslot = _session.next_return_id();
} else {
sscanf (prop->value().c_str(), "%" PRIu32, &_bitslot);
_session.mark_return_id (_bitslot);
}
const XMLNode* insert_node = &node;
/* Return has regular IO automation (gain, pan) */
@ -99,6 +90,17 @@ Return::set_state (const XMLNode& node, int version)
IOProcessor::set_state (*insert_node, version);
if ((prop = node.property ("bitslot")) == 0) {
_bitslot = _session.next_return_id();
} else {
_session.unmark_return_id (_bitslot);
sscanf (prop->value().c_str(), "%" PRIu32, &_bitslot);
_session.mark_return_id (_bitslot);
}
set_name (string_compose (_("return %1"), _bitslot));
return 0;
}

View file

@ -124,7 +124,7 @@ Route::init ()
_amp.reset (new Amp (_session, _mute_master));
add_processor (_amp, PostFader);
/* add standard processors other than amp (added by ::init()) */
/* add standard processors: meter, main outs, monitor out */
_meter.reset (new PeakMeter (_session));
_meter->set_display_to_user (false);
@ -834,183 +834,6 @@ Route::add_processor (boost::shared_ptr<Processor> processor, ProcessorList::ite
return 0;
}
bool
Route::add_processor_from_xml (const XMLNode& node, ProcessorList::iterator iter)
{
const XMLProperty *prop;
if (node.name() != "Processor") {
return false;
}
try {
if ((prop = node.property ("type")) != 0) {
boost::shared_ptr<Processor> processor;
/* meter, amp, monitor and intreturn are all singletons, deal with them first */
if (prop->value() == "meter") {
if (_meter) {
if (_meter->set_state (node, Stateful::loading_state_version)) {
return false;
} else {
return true;
}
}
PeakMeter* pm = new PeakMeter (_session);
if (pm->set_state (node, Stateful::loading_state_version)) {
delete pm;
return false;
}
_meter.reset (pm);
_meter->set_display_to_user (_meter_point == MeterCustom);
processor = _meter;
} else if (prop->value() == "monitor") {
if (_monitor_control) {
if (_monitor_control->set_state (node, Stateful::loading_state_version)) {
return false;
} else {
return true;
}
}
MonitorProcessor* mp = new MonitorProcessor (_session);
if (mp->set_state (node, Stateful::loading_state_version)) {
delete mp;
return false;
}
_monitor_control.reset (mp);
processor = _monitor_control;
} else if (prop->value() == "amp") {
if (_amp) {
processor = _amp;
if (processor->set_state (node, Stateful::loading_state_version)) {
return false;
} else {
/* no reason to add it */
return true;
}
}
Amp* a = new Amp (_session, _mute_master);
if (_amp->set_state (node, Stateful::loading_state_version)) {
delete a;
return false;
}
_amp.reset (a);
processor = _amp;
} else if (prop->value() == "intreturn") {
/* a route only has one internal return. If it exists already
just set its state, and return
*/
if (_intreturn) {
if (_intreturn->set_state (node, Stateful::loading_state_version)) {
return false;
} else {
return true;
}
}
InternalReturn* iret = new InternalReturn (_session);
if (iret->set_state (node, Stateful::loading_state_version)) {
delete iret;
return false;
}
_intreturn.reset (iret);
processor = _intreturn;
} else if (prop->value() == "main-outs") {
if (_main_outs) {
if (_main_outs->set_state (node, Stateful::loading_state_version)) {
return false;
} else {
return true;
}
}
Delivery* del = new Delivery (_session, _output, _mute_master, X_("toBeResetFroXML"), Delivery::Role (0));
if (del->set_state (node, Stateful::loading_state_version)) {
delete del;
return false;
}
_main_outs.reset (del);
processor = _main_outs;
} else if (prop->value() == "intsend") {
InternalSend* isend = new InternalSend (_session, _mute_master, boost::shared_ptr<Route>(), Delivery::Role (0));
if (isend->set_state (node, Stateful::loading_state_version)) {
delete isend;
return false;
}
processor.reset (isend);
} else if (prop->value() == "ladspa" || prop->value() == "Ladspa" ||
prop->value() == "lv2" ||
prop->value() == "vst" ||
prop->value() == "audiounit") {
processor.reset (new PluginInsert(_session, node));
} else if (prop->value() == "port") {
processor.reset (new PortInsert (_session, _mute_master, node));
} else if (prop->value() == "send") {
processor.reset (new Send (_session, _mute_master, node));
} else {
error << string_compose(_("unknown Processor type \"%1\"; ignored"), prop->value()) << endmsg;
return false;
}
if (iter == _processors.end() && processor->display_to_user() && !_processors.empty()) {
/* check for invisible processors stacked at the end and leave them there */
ProcessorList::iterator p;
p = _processors.end();
--p;
while (!(*p)->display_to_user() && p != _processors.begin()) {
--p;
}
++p;
iter = p;
}
return (add_processor (processor, iter, 0, false) == 0);
} else {
error << _("Processor XML node has no type property") << endmsg;
return false;
}
}
catch (failed_constructor &err) {
warning << _("processor could not be created. Ignored.") << endmsg;
return false;
}
}
bool
Route::add_processor_from_xml_2X (const XMLNode& node, int version, ProcessorList::iterator iter)
{
@ -1028,18 +851,18 @@ Route::add_processor_from_xml_2X (const XMLNode& node, int version, ProcessorLis
prop->value() == "vst" ||
prop->value() == "audiounit") {
processor.reset (new PluginInsert (_session, node));
processor.reset (new PluginInsert (_session));
} else {
processor.reset (new PortInsert (_session, _mute_master, node));
processor.reset (new PortInsert (_session, _mute_master));
}
}
} else if (node.name() == "Send") {
processor.reset (new Send (_session, _mute_master, node, version));
processor.reset (new Send (_session, _mute_master));
} else {
@ -1047,6 +870,10 @@ Route::add_processor_from_xml_2X (const XMLNode& node, int version, ProcessorLis
return false;
}
if (processor->set_state (node, version)) {
return false;
}
if (iter == _processors.end() && processor->display_to_user() && !_processors.empty()) {
/* check for invisible processors stacked at the end and leave them there */
ProcessorList::iterator p;
@ -1769,7 +1596,9 @@ Route::reorder_processors (const ProcessorList& new_order, ProcessorStreams* err
}
}
processors_changed (RouteProcessorChange ()); /* EMIT SIGNAL */
if (true) {
processors_changed (RouteProcessorChange ()); /* EMIT SIGNAL */
}
return 0;
}
@ -2316,101 +2145,94 @@ Route::set_processor_state (const XMLNode& node)
{
const XMLNodeList &nlist = node.children();
XMLNodeConstIterator niter;
ProcessorList::iterator i, o;
ProcessorList new_order;
bool must_configure = false;
// Iterate through existing processors, remove those which are not in the state list
for (i = _processors.begin(); i != _processors.end(); ) {
/* leave amp alone, always */
if ((*i) == _amp) {
++i;
continue;
}
ProcessorList::iterator tmp = i;
++tmp;
bool processorInStateList = false;
for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
XMLProperty* id_prop = (*niter)->property(X_("id"));
if (id_prop && (*i)->id() == id_prop->value()) {
processorInStateList = true;
break;
}
}
if (!processorInStateList) {
remove_processor (*i);
}
i = tmp;
}
// Iterate through state list and make sure all processors are on the track and in the correct order,
// set the state of existing processors according to the new state on the same go
i = _processors.begin();
for (niter = nlist.begin(); niter != nlist.end(); ++niter, ++i) {
for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
XMLProperty* prop = (*niter)->property ("type");
o = i;
if (prop->value() == "amp") {
_amp->set_state (**niter, Stateful::current_state_version);
new_order.push_back (_amp);
} else if (prop->value() == "meter") {
_meter->set_state (**niter, Stateful::current_state_version);
new_order.push_back (_meter);
} else if (prop->value() == "main-outs") {
_main_outs->set_state (**niter, Stateful::current_state_version);
new_order.push_back (_main_outs);
} else if (is_monitor() && prop->value() == "intreturn") {
if (!_intreturn) {
_intreturn.reset (new InternalReturn (_session));
must_configure = true;
}
_intreturn->set_state (**niter, Stateful::current_state_version);
new_order.push_back (_intreturn);
} else if (is_monitor() && prop->value() == "monitor") {
if (!_monitor_control) {
_monitor_control.reset (new MonitorProcessor (_session));
must_configure = true;
}
_monitor_control->set_state (**niter, Stateful::current_state_version);
new_order.push_back (_monitor_control);
} else {
ProcessorList::iterator o;
// Check whether the next processor in the list is the right one,
// except for "amp" which is always there and may not have the
// old ID since it is always created anew in every Route
if (prop->value() != "amp") {
while (o != _processors.end()) {
for (o = _processors.begin(); o != _processors.end(); ++o) {
XMLProperty* id_prop = (*niter)->property(X_("id"));
if (id_prop && (*o)->id() == id_prop->value()) {
(*o)->set_state (**niter, Stateful::current_state_version);
new_order.push_back (*o);
break;
}
++o;
}
}
// If the processor (*niter) is not on the route,
// create it and move it to the correct location
if (o == _processors.end()) {
if (add_processor_from_xml (**niter, i)) {
--i; // move iterator to the newly inserted processor
} else {
cerr << "Error restoring route: unable to restore processor" << endl;
}
} else {
// If the processor (*niter) is not on the route then create it
// Otherwise, the processor already exists; just
// ensure it is at the location provided in the XML state
if (o == _processors.end()) {
if (i != o) {
boost::shared_ptr<Processor> tmp = (*o);
_processors.erase (o); // remove the old copy
_processors.insert (i, tmp); // insert the processor at the correct location
--i; // move iterator to the correct processor
}
boost::shared_ptr<Processor> processor;
// and make it (just) so
if (prop->value() == "intsend") {
(*i)->set_state (**niter, Stateful::current_state_version);
}
}
processor.reset (new InternalSend (_session, _mute_master, boost::shared_ptr<Route>(), Delivery::Role (0)));
/* note: there is no configure_processors() call because we figure that
the XML state represents a working signal route.
*/
} else if (prop->value() == "ladspa" || prop->value() == "Ladspa" ||
prop->value() == "lv2" ||
prop->value() == "vst" ||
prop->value() == "audiounit") {
processors_changed (RouteProcessorChange ());
processor.reset (new PluginInsert(_session));
} else if (prop->value() == "port") {
processor.reset (new PortInsert (_session, _mute_master));
} else if (prop->value() == "send") {
processor.reset (new Send (_session, _mute_master));
} else {
error << string_compose(_("unknown Processor type \"%1\"; ignored"), prop->value()) << endmsg;
continue;
}
processor->set_state (**niter, Stateful::current_state_version);
new_order.push_back (processor);
must_configure = true;
}
}
}
{
Glib::RWLock::WriterLock lm (_processor_lock);
_processors = new_order;
if (must_configure) {
configure_processors_unlocked (0);
}
}
processors_changed (RouteProcessorChange ());
}
void
@ -3388,13 +3210,10 @@ Route::nth_send (uint32_t n)
ProcessorList::iterator i;
for (i = _processors.begin(); i != _processors.end(); ++i) {
cerr << "check " << (*i)->name() << endl;
if (boost::dynamic_pointer_cast<Send> (*i)) {
if (n-- == 0) {
return *i;
}
} else {
cerr << "\tnot a send\n";
}
}

View file

@ -44,26 +44,11 @@ Send::Send (Session& s, boost::shared_ptr<MuteMaster> mm, Role r)
{
_amp.reset (new Amp (_session, _mute_master));
_meter.reset (new PeakMeter (_session));
ProcessorCreated (this); /* EMIT SIGNAL */
}
Send::Send (Session& s, boost::shared_ptr<MuteMaster> mm, const XMLNode& node, int version, Role r)
: Delivery (s, mm, "send", r)
, _metering (false)
{
_amp.reset (new Amp (_session, _mute_master));
_meter.reset (new PeakMeter (_session));
if (set_state (node, version)) {
throw failed_constructor();
}
ProcessorCreated (this); /* EMIT SIGNAL */
}
Send::~Send ()
{
_session.unmark_send_id (_bitslot);
}
void
@ -139,7 +124,7 @@ Send::get_state(void)
}
XMLNode&
Send::state(bool full)
Send::state (bool full)
{
XMLNode& node = Delivery::state(full);
char buf[32];
@ -158,19 +143,24 @@ Send::set_state (const XMLNode& node, int version)
XMLNodeIterator niter;
const XMLProperty* prop;
if ((prop = node.property ("bitslot")) == 0) {
_bitslot = _session.next_send_id();
} else {
sscanf (prop->value().c_str(), "%" PRIu32, &_bitslot);
_session.mark_send_id (_bitslot);
}
Delivery::set_state (node, version);
const XMLNode* insert_node = &node;
/* don't try to reset bitslot if its already set: this can cause
issues with the session's accounting of send ID's
*/
if ((prop = node.property ("bitslot")) == 0) {
_bitslot = _session.next_send_id();
} else {
_session.unmark_send_id (_bitslot);
sscanf (prop->value().c_str(), "%" PRIu32, &_bitslot);
_session.mark_send_id (_bitslot);
}
set_name (string_compose (_("send %1"), _bitslot));
/* XXX need to load automation state & data for amp */
Delivery::set_state (*insert_node, version);
return 0;
}

View file

@ -3101,35 +3101,6 @@ Session::graph_reordered ()
}
}
void
Session::add_processor (Processor* processor)
{
/* Session does not own Processors (they belong to a Route) but we do want to track
the arrival and departure of port inserts, sends and returns for naming
purposes.
*/
processor->DropReferences.connect_same_thread (*this, boost::bind (&Session::remove_processor, this, processor));
set_dirty();
}
void
Session::remove_processor (Processor* processor)
{
Send* send;
Return* retrn;
PortInsert* port_insert;
if ((port_insert = dynamic_cast<PortInsert *> (processor)) != 0) {
insert_bitset[port_insert->bit_slot()] = false;
} else if ((send = dynamic_cast<Send *> (processor)) != 0) {
send_bitset[send->bit_slot()] = false;
} else if ((retrn = dynamic_cast<Return *> (processor)) != 0) {
return_bitset[retrn->bit_slot()] = false;
}
set_dirty();
}
nframes_t
Session::available_capture_duration ()
{
@ -3317,6 +3288,8 @@ Session::next_return_id ()
void
Session::mark_send_id (uint32_t id)
{
cerr << "Marking send ID " << id << " in use\n";
if (id >= send_bitset.size()) {
send_bitset.resize (id+16, false);
}
@ -3350,6 +3323,31 @@ Session::mark_insert_id (uint32_t id)
insert_bitset[id] = true;
}
void
Session::unmark_send_id (uint32_t id)
{
if (id < send_bitset.size()) {
send_bitset[id] = false;
}
}
void
Session::unmark_return_id (uint32_t id)
{
if (id < return_bitset.size()) {
return_bitset[id] = false;
}
}
void
Session::unmark_insert_id (uint32_t id)
{
if (id < insert_bitset.size()) {
insert_bitset[id] = false;
}
}
/* Named Selection management */
boost::shared_ptr<NamedSelection>

View file

@ -272,7 +272,6 @@ Session::first_stage_init (string fullpath, string snapshot_name)
SourceFactory::SourceCreated.connect_same_thread (*this, boost::bind (&Session::add_source, this, _1));
PlaylistFactory::PlaylistCreated.connect_same_thread (*this, boost::bind (&Session::add_playlist, this, _1, _2));
Processor::ProcessorCreated.connect_same_thread (*this, boost::bind (&Session::add_processor, this, _1));
AutomationList::AutomationListCreated.connect_same_thread (*this, boost::bind (&Session::add_automation_list, this, _1));
Controllable::Destroyed.connect_same_thread (*this, boost::bind (&Session::remove_controllable, this, _1));
IO::PortCountChanged.connect_same_thread (*this, boost::bind (&Session::ensure_buffers, this, _1));