a gadzillion changes all over the place. nothing is finished, but all is better than it was. more to come on all almost everything touched by this commit, this is purely a sync-to-repository. compiles and runs, but now incompatible with all previous 3.0 session files (probably)

git-svn-id: svn://localhost/ardour2/branches/3.0@5084 d708f5d6-7413-0410-9779-e7cbd77b26cf
This commit is contained in:
Paul Davis 2009-05-16 02:51:17 +00:00
parent 86dda29be7
commit ace07c80a8
18 changed files with 437 additions and 540 deletions

View file

@ -543,7 +543,8 @@ Editor::drop_regions (const RefPtr<Gdk::DragContext>& context,
guint info, guint time)
{
std::list<boost::shared_ptr<Region> > regions;
region_list_display.get_object_drag_data (regions);
Gtk::TreeView* source;
region_list_display.get_object_drag_data (regions, &source);
for (list<boost::shared_ptr<Region> >::iterator r = regions.begin(); r != regions.end(); ++r) {

View file

@ -153,27 +153,6 @@ IOSelector::n_io_ports () const
}
}
uint32_t
IOSelector::maximum_io_ports () const
{
if (!_find_inputs_for_io_outputs) {
return _io->input_maximum ().get (_io->default_type());
} else {
return _io->output_maximum ().get (_io->default_type());
}
}
uint32_t
IOSelector::minimum_io_ports () const
{
if (!_find_inputs_for_io_outputs) {
return _io->input_minimum ().get (_io->default_type());
} else {
return _io->output_minimum ().get (_io->default_type());
}
}
void
IOSelector::add_channel (boost::shared_ptr<ARDOUR::Bundle> b)
{
@ -249,12 +228,10 @@ IOSelectorWindow::IOSelectorWindow (ARDOUR::Session& session, boost::shared_ptr<
get_action_area()->pack_start (disconnect_button, false, false);
/* Add Port button */
if (_selector.maximum_io_ports() > _selector.n_io_ports()) {
add_button.set_name ("IOSelectorButton");
add_button.set_image (*Gtk::manage (new Gtk::Image (Gtk::Stock::ADD, Gtk::ICON_SIZE_BUTTON)));
get_action_area()->pack_start (add_button, false, false);
add_button.signal_clicked().connect (sigc::bind (sigc::mem_fun (_selector, &IOSelector::add_channel), boost::shared_ptr<Bundle> ()));
}
add_button.set_name ("IOSelectorButton");
add_button.set_image (*Gtk::manage (new Gtk::Image (Gtk::Stock::ADD, Gtk::ICON_SIZE_BUTTON)));
get_action_area()->pack_start (add_button, false, false);
add_button.signal_clicked().connect (sigc::bind (sigc::mem_fun (_selector, &IOSelector::add_channel), boost::shared_ptr<Bundle> ()));
/* Rescan button */
rescan_button.set_name ("IOSelectorButton");
@ -299,11 +276,11 @@ IOSelectorWindow::IOSelectorWindow (ARDOUR::Session& session, boost::shared_ptr<
void
IOSelectorWindow::ports_changed ()
{
if (_selector.maximum_io_ports() > _selector.n_io_ports()) {
add_button.set_sensitive (true);
} else {
add_button.set_sensitive (false);
}
/* XXX make this insensitive based on port connectivity, not
port counts.
*/
add_button.set_sensitive (true);
}
void

View file

@ -45,8 +45,6 @@ class IOSelector : public PortMatrix
}
uint32_t n_io_ports () const;
uint32_t maximum_io_ports () const;
uint32_t minimum_io_ports () const;
boost::shared_ptr<ARDOUR::IO> const io () { return _io; }
void setup_ports (int);
bool list_is_global (int) const;

View file

@ -118,7 +118,8 @@ ProcessorBox::ProcessorBox (Placement pcmnt, Session& sess, PluginSelector &plug
RefPtr<TreeSelection> selection = processor_display.get_selection();
selection->set_mode (Gtk::SELECTION_MULTIPLE);
selection->signal_changed().connect (mem_fun (*this, &ProcessorBox::selection_changed));
processor_display.set_data ("processorbox", this);
processor_display.set_model (model);
processor_display.append_column (X_("notshown"), columns.text);
processor_display.set_name ("ProcessorSelector");
@ -186,16 +187,31 @@ ProcessorBox::route_going_away ()
void
ProcessorBox::object_drop (const list<boost::shared_ptr<Processor> >& procs)
ProcessorBox::object_drop (const list<boost::shared_ptr<Processor> >& procs, Gtk::TreeView* source, Glib::RefPtr<Gdk::DragContext>& context)
{
for (std::list<boost::shared_ptr<Processor> >::const_iterator i = procs.begin();
i != procs.end(); ++i) {
cerr << "Drop from " << source << " (mine is " << &processor_display << ") action = " << hex << context->get_suggested_action() << dec << endl;
for (list<boost::shared_ptr<Processor> >::const_iterator i = procs.begin(); i != procs.end(); ++i) {
XMLNode& state = (*i)->get_state ();
XMLNodeList nlist;
nlist.push_back (&state);
paste_processor_state (nlist);
delete &state;
}
/* since the treeview doesn't take care of this properly, we have to delete the originals
ourselves.
*/
if ((context->get_suggested_action() == Gdk::ACTION_MOVE) && source) {
ProcessorBox* other = reinterpret_cast<ProcessorBox*> (source->get_data ("processorbox"));
if (other) {
cerr << "source was another processor box, delete the selected items\n";
other->delete_dragged_processors (procs);
}
}
context->drag_finish (true, (context->get_suggested_action() == Gdk::ACTION_MOVE), 0);
}
void
@ -433,9 +449,7 @@ ProcessorBox::use_plugins (const SelectedPlugins& plugins)
processor->activate ();
}
assign_default_sort_key (processor);
if (_route->add_processor (processor, &err_streams)) {
if (_route->add_processor (processor, _placement, &err_streams)) {
weird_plugin_dialog (**p, err_streams, _route);
// XXX SHAREDPTR delete plugin here .. do we even need to care?
} else {
@ -500,8 +514,7 @@ ProcessorBox::choose_insert ()
mem_fun(*this, &ProcessorBox::show_processor_active),
boost::weak_ptr<Processor>(processor)));
assign_default_sort_key (processor);
_route->add_processor (processor);
_route->add_processor (processor, _placement);
}
void
@ -553,8 +566,7 @@ ProcessorBox::send_io_finished (IOSelector::Result r, boost::weak_ptr<Processor>
break;
case IOSelector::Accepted:
assign_default_sort_key (processor);
_route->add_processor (processor);
_route->add_processor (processor, _placement);
if (Profile->get_sae()) {
processor->activate ();
}
@ -611,8 +623,7 @@ ProcessorBox::return_io_finished (IOSelector::Result r, boost::weak_ptr<Processo
break;
case IOSelector::Accepted:
assign_default_sort_key (processor);
_route->add_processor (processor);
_route->add_processor (processor, _placement);
if (Profile->get_sae()) {
processor->activate ();
}
@ -658,7 +669,7 @@ ProcessorBox::add_processor_to_display (boost::weak_ptr<Processor> p)
return;
}
if (processor == _route->amp()) {
if (processor == _route->amp() || !processor->visible()) {
return;
}
@ -796,22 +807,16 @@ ProcessorBox::row_deleted (const Gtk::TreeModel::Path& path)
void
ProcessorBox::compute_processor_sort_keys ()
{
uint32_t sort_key;
Gtk::TreeModel::Children children = model->children();
if (_placement == PreFader) {
sort_key = 0;
} else {
sort_key = _route->fader_sort_key() + 1;
}
Route::ProcessorList our_processors;
for (Gtk::TreeModel::Children::iterator iter = children.begin(); iter != children.end(); ++iter) {
boost::shared_ptr<Processor> r = (*iter)[columns.processor];
r->set_sort_key (sort_key);
sort_key++;
our_processors.push_back ((*iter)[columns.processor]);
}
if (_route->sort_processors ()) {
if (_route->reorder_processors (our_processors, _placement)) {
/* reorder failed, so redisplay */
redisplay_processors ();
@ -928,6 +933,8 @@ ProcessorBox::delete_processors ()
return;
}
no_processor_redisplay = true;
for (ProcSelection::iterator i = to_be_deleted.begin(); i != to_be_deleted.end(); ++i) {
void* gui = (*i)->get_gui ();
@ -943,6 +950,27 @@ ProcessorBox::delete_processors ()
redisplay_processors ();
}
void
ProcessorBox::delete_dragged_processors (const list<boost::shared_ptr<Processor> >& procs)
{
list<boost::shared_ptr<Processor> >::const_iterator x;
no_processor_redisplay = true;
for (x = procs.begin(); x != procs.end(); ++x) {
void* gui = (*x)->get_gui ();
if (gui) {
static_cast<Gtk::Widget*>(gui)->hide ();
}
_route->remove_processor(*x);
}
no_processor_redisplay = false;
redisplay_processors ();
}
gint
ProcessorBox::idle_delete_processor (boost::weak_ptr<Processor> weak_processor)
{
@ -1051,9 +1079,7 @@ ProcessorBox::paste_processor_state (const XMLNodeList& nlist)
return;
}
assign_default_sort_key (copies.front());
if (_route->add_processors (copies, 0, copies.front()->sort_key())) {
if (_route->add_processors (copies, _placement)) {
string msg = _(
"Copying the set of processors on the clipboard failed,\n\
@ -1568,12 +1594,3 @@ ProcessorBox::generate_processor_title (boost::shared_ptr<PluginInsert> pi)
return string_compose(_("%1: %2 (by %3)"), _route->name(), pi->name(), maker);
}
void
ProcessorBox::assign_default_sort_key (boost::shared_ptr<Processor> p)
{
p->set_sort_key (_placement == PreFader ? 0 : 9999);
cerr << "default sort key for "
<< _placement << " = " << p->sort_key()
<< endl;
}

View file

@ -128,7 +128,8 @@ class ProcessorBox : public Gtk::HBox, public PluginInterestedObject
Gtkmm2ext::DnDTreeView<boost::shared_ptr<ARDOUR::Processor> > processor_display;
Gtk::ScrolledWindow processor_scroller;
void object_drop (const std::list<boost::shared_ptr<ARDOUR::Processor> >&);
void object_drop (const std::list<boost::shared_ptr<ARDOUR::Processor> >&, Gtk::TreeView*,
Glib::RefPtr<Gdk::DragContext>& context);
Width _width;
@ -168,7 +169,6 @@ class ProcessorBox : public Gtk::HBox, public PluginInterestedObject
void processors_reordered (const Gtk::TreeModel::Path&, const Gtk::TreeModel::iterator&, int*);
void compute_processor_sort_keys ();
void assign_default_sort_key (boost::shared_ptr<ARDOUR::Processor>);
std::vector<sigc::connection> processor_active_connections;
std::vector<sigc::connection> processor_name_connections;
@ -183,6 +183,7 @@ class ProcessorBox : public Gtk::HBox, public PluginInterestedObject
void copy_processors ();
void paste_processors ();
void delete_processors ();
void delete_dragged_processors (const std::list<boost::shared_ptr<ARDOUR::Processor> >&);
void clear_processors ();
void rename_processors ();

View file

@ -71,24 +71,11 @@ class IO : public SessionObject, public AutomatableControls, public Latent
public:
static const std::string state_node_name;
IO (Session&, const std::string& name, DataType default_type = DataType::AUDIO,
ChanCount in_min=ChanCount::ZERO, ChanCount in_max=ChanCount::INFINITE,
ChanCount out_min=ChanCount::ZERO, ChanCount out_max=ChanCount::INFINITE);
IO (Session&, const std::string& name, DataType default_type = DataType::AUDIO);
IO (Session&, const XMLNode&, DataType default_type = DataType::AUDIO);
virtual ~IO();
ChanCount input_minimum() const { return _input_minimum; }
ChanCount input_maximum() const { return _input_maximum; }
ChanCount output_minimum() const { return _output_minimum; }
ChanCount output_maximum() const { return _output_maximum; }
void set_input_minimum (ChanCount n);
void set_input_maximum (ChanCount n);
void set_output_minimum (ChanCount n);
void set_output_maximum (ChanCount n);
bool active() const { return _active; }
void set_active (bool yn);
@ -283,8 +270,6 @@ class IO : public SessionObject, public AutomatableControls, public Latent
XMLNode* deferred_state;
DataType _default_type;
nframes_t _output_offset;
ChanCount _configured_inputs;
ChanCount _configured_outputs;
boost::shared_ptr<Amp> _amp;
boost::shared_ptr<PeakMeter> _meter;
@ -327,11 +312,6 @@ class IO : public SessionObject, public AutomatableControls, public Latent
sigc::connection port_legal_c;
sigc::connection panner_legal_c;
ChanCount _input_minimum; ///< minimum number of input channels (0 for no minimum)
ChanCount _input_maximum; ///< maximum number of input channels (ChanCount::INFINITE for no maximum)
ChanCount _output_minimum; ///< minimum number of output channels (0 for no minimum)
ChanCount _output_maximum; ///< maximum number of output channels (ChanCount::INFINITE for no maximum)
boost::shared_ptr<Bundle> _bundle_for_inputs; ///< a bundle representing our inputs
boost::shared_ptr<Bundle> _bundle_for_outputs; ///< a bundle representing our outputs
@ -361,7 +341,9 @@ class IO : public SessionObject, public AutomatableControls, public Latent
void bundle_changed (Bundle::Change);
int get_port_counts (const XMLNode& node);
int get_port_counts (const XMLNode& node, ChanCount& in, ChanCount& out,
boost::shared_ptr<Bundle>& ic, boost::shared_ptr<Bundle>& oc);
int create_ports (const XMLNode&);
int make_connections (const XMLNode&);
boost::shared_ptr<Bundle> find_possible_bundle (const std::string &desired_name, const std::string &default_name, const std::string &connection_type_name);

View file

@ -63,9 +63,6 @@ class Processor : public SessionObject, public AutomatableControls, public Laten
virtual bool visible() const { return true; }
uint32_t sort_key() const { return _sort_key; }
void set_sort_key (uint32_t key);
bool active () const { return _active; }
bool get_next_ab_is_active () const { return _next_ab_is_active; }
@ -129,7 +126,6 @@ protected:
bool _configured;
ChanCount _configured_input;
ChanCount _configured_output;
uint32_t _sort_key;
void* _gui; /* generic, we don't know or care what this is */
Mapping _mapping;
};

View file

@ -60,12 +60,10 @@ enum mute_type {
class Route : public IO
{
protected:
public:
typedef std::list<boost::shared_ptr<Processor> > ProcessorList;
public:
enum Flag {
Hidden = 0x1,
MasterOut = 0x2,
@ -73,9 +71,7 @@ class Route : public IO
};
Route (Session&, std::string name, Flag flags = Flag(0),
DataType default_type = DataType::AUDIO,
ChanCount in=ChanCount::ZERO, ChanCount out=ChanCount::ZERO);
DataType default_type = DataType::AUDIO);
Route (Session&, const XMLNode&, DataType default_type = DataType::AUDIO);
virtual ~Route();
@ -176,7 +172,7 @@ class Route : public IO
}
}
uint32_t fader_sort_key() const;
ProcessorList::iterator prefader_iterator();
ChanCount max_processor_streams () const { return processor_max_streams; }
ChanCount pre_fader_streams() const;
@ -196,10 +192,12 @@ class Route : public IO
ChanCount count; ///< Input requested of processor
};
int add_processor (boost::shared_ptr<Processor>, ProcessorStreams* err = 0, ProcessorList::iterator* iter=0);
int add_processors (const ProcessorList&, ProcessorStreams* err = 0, uint32_t first_sort_key = 0);
int add_processor (boost::shared_ptr<Processor>, Placement placement, ProcessorStreams* err = 0);
int add_processor (boost::shared_ptr<Processor>, ProcessorList::iterator iter, ProcessorStreams* err = 0);
int add_processors (const ProcessorList&, Placement placement, ProcessorStreams* err = 0);
int add_processors (const ProcessorList&, ProcessorList::iterator iter, ProcessorStreams* err = 0);
int remove_processor (boost::shared_ptr<Processor>, ProcessorStreams* err = 0);
int sort_processors (ProcessorStreams* err = 0);
int reorder_processors (const ProcessorList& new_order, Placement placement, ProcessorStreams* err = 0);
void disable_processors (Placement);
void disable_processors ();
void disable_plugins (Placement);
@ -389,12 +387,10 @@ class Route : public IO
int configure_processors_unlocked (ProcessorStreams*);
void set_deferred_state ();
bool add_processor_from_xml (const XMLNode&, ProcessorList::iterator* iter=0);
bool add_processor_from_xml (const XMLNode&, Placement);
bool add_processor_from_xml (const XMLNode&, ProcessorList::iterator iter);
void placement_range(
Placement p,
ProcessorList::iterator& start,
ProcessorList::iterator& end);
void placement_range (Placement p, ProcessorList::iterator& start, ProcessorList::iterator& end);
};
} // namespace ARDOUR

View file

@ -139,11 +139,6 @@ AudioTrack::deprecated_use_diskstream_connections ()
diskstream->deprecated_io_node = 0;
set_input_minimum (ChanCount::ZERO);
set_input_maximum (ChanCount::INFINITE);
set_output_minimum (ChanCount::ZERO);
set_output_maximum (ChanCount::INFINITE);
if ((prop = node.property ("gain")) != 0) {
set_gain (atof (prop->value().c_str()), this);
_gain = _gain_control->user_float();

View file

@ -329,6 +329,7 @@ int
AudioEngine::process_callback (nframes_t nframes)
{
// CycleTimer ct ("AudioEngine::process");
Glib::Mutex::Lock tm (_process_lock, Glib::TRY_LOCK);
/// The number of frames that will have been processed when we've finished

View file

@ -100,9 +100,7 @@ static double direct_gain_to_control (gain_t gain) {
/** @param default_type The type of port that will be created by ensure_io
* and friends if no type is explicitly requested (to avoid breakage).
*/
IO::IO (Session& s, const string& name,
DataType default_type,
ChanCount in_min, ChanCount in_max, ChanCount out_min, ChanCount out_max)
IO::IO (Session& s, const string& name, DataType default_type)
: SessionObject (s, name)
, AutomatableControls (s)
, _output_buffers (new BufferSet())
@ -111,16 +109,7 @@ IO::IO (Session& s, const string& name,
, _amp (new Amp(s, *this))
, _meter (new PeakMeter(s))
, _panner (new Panner(name, s))
, _input_minimum (ChanCount::ZERO)
, _input_maximum (ChanCount::INFINITE)
, _output_minimum (ChanCount::ZERO)
, _output_maximum (ChanCount::INFINITE)
{
_input_minimum = in_min;
_output_minimum = out_min;
_input_maximum = in_max;
_output_maximum = out_max;
_gain = 1.0;
pending_state_node = 0;
no_panner_reset = false;
@ -521,19 +510,10 @@ IO::set_input (Port* other_port, void* src)
to the specified source.
*/
if (_input_minimum.n_total() > 1) {
/* sorry, you can't do this */
if (!other_port) {
return -1;
}
if (other_port == 0) {
if (_input_minimum == ChanCount::ZERO) {
return ensure_inputs (ChanCount::ZERO, false, true, src);
} else {
return -1;
}
}
if (ensure_inputs (ChanCount(other_port->type(), 1), true, true, src)) {
return -1;
}
@ -553,11 +533,6 @@ IO::remove_output_port (Port* port, void* src)
{
Glib::Mutex::Lock lm (io_lock);
if (n_outputs() <= _output_minimum) {
/* sorry, you can't do this */
return -1;
}
if (_outputs.remove(port)) {
change = IOChange (change|ConfigurationChanged);
@ -610,10 +585,6 @@ IO::add_output_port (string destination, void* src, DataType type)
{
Glib::Mutex::Lock lm (io_lock);
if (n_outputs() >= _output_maximum) {
return -1;
}
/* Create a new output port */
string portname = build_legal_port_name (type, false);
@ -657,11 +628,6 @@ IO::remove_input_port (Port* port, void* src)
{
Glib::Mutex::Lock lm (io_lock);
if (n_inputs() <= _input_minimum) {
/* sorry, you can't do this */
return -1;
}
if (_inputs.remove(port)) {
change = IOChange (change|ConfigurationChanged);
@ -714,10 +680,6 @@ IO::add_input_port (string source, void* src, DataType type)
{
Glib::Mutex::Lock lm (io_lock);
if (n_inputs().get (type) >= _input_maximum.get (type)) {
return -1;
}
/* Create a new input port */
string portname = build_legal_port_name (type, true);
@ -801,8 +763,6 @@ IO::ensure_inputs_locked (ChanCount count, bool clear, void* src)
Port* input_port = 0;
bool changed = false;
_configured_inputs = count;
for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
const size_t n = count.get(*t);
@ -870,12 +830,6 @@ IO::ensure_io (ChanCount in, ChanCount out, bool clear, void* src)
assert(in != ChanCount::INFINITE);
assert(out != ChanCount::INFINITE);
in = ChanCount::min (_input_maximum, in);
out = ChanCount::min (_output_maximum, out);
_configured_inputs = in;
_configured_outputs = out;
if (in == n_inputs() && out == n_outputs() && !clear) {
return 0;
}
@ -1007,8 +961,6 @@ IO::ensure_inputs (ChanCount count, bool clear, bool lockit, void* src)
{
bool changed = false;
count = min (_input_maximum, count);
if (count == n_inputs() && !clear) {
return 0;
}
@ -1036,8 +988,6 @@ IO::ensure_outputs_locked (ChanCount count, bool clear, void* src)
bool changed = false;
bool need_pan_reset = false;
_configured_outputs = count;
if (n_outputs() != count) {
need_pan_reset = true;
}
@ -1098,13 +1048,6 @@ IO::ensure_outputs (ChanCount count, bool clear, bool lockit, void* src)
{
bool changed = false;
if (_output_maximum != ChanCount::INFINITE) {
count = min (_output_maximum, count);
if (count == n_outputs() && !clear) {
return 0;
}
}
/* XXX caller should hold io_lock, but generally doesn't */
if (lockit) {
@ -1276,7 +1219,7 @@ IO::state (bool full_state)
node->add_property ("gain", buf);
/* port counts */
node->add_child_nocopy(*n_inputs().state("Inputs"));
node->add_child_nocopy(*n_outputs().state("Outputs"));
@ -1313,44 +1256,6 @@ IO::set_state (const XMLNode& node)
_id = prop->value ();
}
int in_min = -1;
int in_max = -1;
int out_min = -1;
int out_max = -1;
if ((prop = node.property ("iolimits")) != 0) {
sscanf (prop->value().c_str(), "%d,%d,%d,%d",
&in_min, &in_max, &out_min, &out_max);
// Legacy numbers:
// minimum == -1 => minimum == 0
// maximum == -1 => maximum == infinity
if (in_min < 0) {
_input_minimum = ChanCount::ZERO;
} else {
_input_minimum = ChanCount (_default_type, in_min);
}
if (in_max < 0) {
_input_maximum = ChanCount::INFINITE;
} else {
_input_maximum = ChanCount (_default_type, in_max);
}
if (out_min < 0) {
_output_minimum = ChanCount::ZERO;
} else {
_output_minimum = ChanCount (_default_type, out_min);
}
if (out_max < 0) {
_output_maximum = ChanCount::INFINITE;
} else {
_output_maximum = ChanCount (_default_type, out_max);
}
}
if ((prop = node.property ("gain")) != 0) {
set_gain (atof (prop->value().c_str()), this);
_gain = _gain_control->user_float();
@ -1391,8 +1296,6 @@ IO::set_state (const XMLNode& node)
}
}
get_port_counts (node);
if (ports_legal) {
if (create_ports (node)) {
@ -1541,7 +1444,6 @@ IO::ports_became_legal ()
port_legal_c.disconnect ();
get_port_counts (*pending_state_node);
ret = create_ports (*pending_state_node);
if (connecting_legal) {
@ -1645,69 +1547,74 @@ IO::find_possible_bundle (const string &desired_name, const string &default_name
}
int
IO::get_port_counts (const XMLNode& node)
IO::get_port_counts (const XMLNode& node, ChanCount& in, ChanCount& out,
boost::shared_ptr<Bundle>& ic, boost::shared_ptr<Bundle>& oc)
{
XMLProperty const * prop;
XMLNodeConstIterator iter;
ChanCount num_inputs = n_inputs();
ChanCount num_outputs = n_outputs();
in = n_inputs();
out = n_outputs();
for (iter = node.children().begin(); iter != node.children().end(); ++iter) {
if ((*iter)->name() == X_("Inputs")) {
num_inputs = ChanCount::max(num_inputs, ChanCount(**iter));
in = ChanCount::max(in, ChanCount(**iter));
} else if ((*iter)->name() == X_("Outputs")) {
num_outputs = ChanCount::max(num_inputs, ChanCount(**iter));
out = ChanCount::max(out, ChanCount(**iter));
}
}
if ((prop = node.property ("input-connection")) != 0) {
boost::shared_ptr<Bundle> c = find_possible_bundle (prop->value(), _("in"), _("input"));
if (c) {
num_inputs = ChanCount::max(num_inputs, ChanCount(c->type(), c->nchannels()));
ic = find_possible_bundle (prop->value(), _("in"), _("input"));
if (ic) {
in = ChanCount::max(in, ChanCount(ic->type(), ic->nchannels()));
}
} else if ((prop = node.property ("inputs")) != 0) {
num_inputs = ChanCount::max(num_inputs, ChanCount(_default_type,
count (prop->value().begin(), prop->value().end(), '{')));
in = ChanCount::max(in, ChanCount(_default_type,
count (prop->value().begin(), prop->value().end(), '{')));
}
if ((prop = node.property ("output-connection")) != 0) {
boost::shared_ptr<Bundle> c = find_possible_bundle (prop->value(), _("out"), _("output"));
if (c) {
num_outputs = ChanCount::max(num_outputs, ChanCount(c->type(), c->nchannels()));
oc = find_possible_bundle (prop->value(), _("out"), _("output"));
if (oc) {
out = ChanCount::max(out, ChanCount(oc->type(), oc->nchannels()));
}
} else if ((prop = node.property ("outputs")) != 0) {
num_outputs = ChanCount::max(num_outputs, ChanCount(_default_type,
count (prop->value().begin(), prop->value().end(), '{')));
out = ChanCount::max(out, ChanCount(_default_type,
count (prop->value().begin(), prop->value().end(), '{')));
}
_configured_inputs = num_inputs;
_configured_outputs = num_outputs;
_input_minimum = ChanCount::min(_input_minimum, num_inputs);
_input_maximum = ChanCount::max(_input_maximum, num_inputs);
_output_minimum = ChanCount::min(_output_minimum, num_outputs);
_output_maximum = ChanCount::max(_output_maximum, num_outputs);
return 0;
}
int
IO::create_ports (const XMLNode& node)
{
ChanCount in;
ChanCount out;
boost::shared_ptr<Bundle> ic;
boost::shared_ptr<Bundle> oc;
no_panner_reset = true;
if (ensure_io (_input_minimum, _output_minimum, true, this)) {
get_port_counts (*pending_state_node, in, out, ic, oc);
if (ensure_io (in, out, true, this)) {
error << string_compose(_("%1: cannot create I/O ports"), _name) << endmsg;
return -1;
}
/* XXX use ic and oc if relevant */
no_panner_reset = false;
cerr << "IO " << name() << " created ports, ci = " << n_inputs() << endl;
set_deferred_state ();
@ -1843,7 +1750,7 @@ IO::set_outputs (const string& str)
return 0;
}
// FIXME: audio-only
// FIXME: audio-only - need a way to identify port types from XML/string
if (ensure_outputs (ChanCount(DataType::AUDIO, nports), true, true, this)) {
return -1;
}
@ -1970,30 +1877,6 @@ IO::set_name (const string& requested_name)
return r;
}
void
IO::set_input_minimum (ChanCount n)
{
_input_minimum = n;
}
void
IO::set_input_maximum (ChanCount n)
{
_input_maximum = n;
}
void
IO::set_output_minimum (ChanCount n)
{
_output_minimum = n;
}
void
IO::set_output_maximum (ChanCount n)
{
_output_maximum = n;
}
void
IO::set_port_latency (nframes_t nframes)
{
@ -2411,7 +2294,6 @@ IO::build_legal_port_name (DataType type, bool in)
const int name_size = jack_port_name_size();
int limit;
string suffix;
int maxports;
if (type == DataType::AUDIO) {
suffix = _("audio");
@ -2423,20 +2305,10 @@ IO::build_legal_port_name (DataType type, bool in)
if (in) {
suffix += _("_in");
maxports = _input_maximum.get(type);
} else {
suffix += _("_out");
maxports = _output_maximum.get(type);
}
if (maxports == 1) {
// allow space for the slash + the suffix
limit = name_size - _session.engine().client_name().length() - (suffix.length() + 1);
char buf[name_size+1];
snprintf (buf, name_size+1, ("%.*s/%s"), limit, _name.c_str(), suffix.c_str());
return string (buf);
}
// allow up to 4 digits for the output port number, plus the slash, suffix and extra space
limit = name_size - _session.engine().client_name().length() - (suffix.length() + 5);

View file

@ -57,9 +57,6 @@ MidiTrack::MidiTrack (Session& sess, string name, Route::Flag flag, TrackMode mo
_freeze_record.state = NoFreeze;
_saved_meter_point = _meter_point;
_mode = mode;
set_input_minimum(ChanCount(DataType::MIDI, 1));
set_input_maximum(ChanCount(DataType::MIDI, 1));
}
MidiTrack::MidiTrack (Session& sess, const XMLNode& node)
@ -68,9 +65,6 @@ MidiTrack::MidiTrack (Session& sess, const XMLNode& node)
, _note_mode(Sustained)
{
_set_state(node, false);
set_input_minimum(ChanCount(DataType::MIDI, 1));
set_input_maximum(ChanCount(DataType::MIDI, 1));
}
MidiTrack::~MidiTrack ()

View file

@ -848,10 +848,6 @@ PluginInsert::set_state(const XMLNode& node)
break;
}
if (niter == nlist.end()) {
warning << string_compose(_("XML node describing a port automation is missing the `%1' information"), port_automation_node_name) << endmsg;
}
// The name of the PluginInsert comes from the plugin, nothing else
_name = plugin->get_info()->name;

View file

@ -64,17 +64,10 @@ Processor::Processor(Session& session, const string& name)
, _active(false)
, _next_ab_is_active(false)
, _configured(false)
, _sort_key (0)
, _gui(0)
{
}
void
Processor::set_sort_key (uint32_t key)
{
_sort_key = key;
}
XMLNode&
Processor::get_state (void)
{
@ -102,14 +95,10 @@ Processor::state (bool full_state)
stringstream sstr;
char buf[64];
// NOTE: This conflicts with "id" used by plugin for name in legacy sessions
id().print (buf, sizeof (buf));
node->add_property("id", buf);
node->add_property("name", _name);
node->add_property("active", active() ? "yes" : "no");
snprintf (buf, sizeof (buf), "%u", _sort_key);
node->add_property("sort-key", buf);
if (_extra_xml){
node->add_child_copy (*_extra_xml);

View file

@ -63,15 +63,12 @@ using namespace PBD;
uint32_t Route::order_key_cnt = 0;
sigc::signal<void,const char*> Route::SyncOrderKeys;
Route::Route (Session& sess, string name, Flag flg,
DataType default_type, ChanCount in, ChanCount out)
: IO (sess, name, default_type, in, ChanCount::INFINITE, out, ChanCount::INFINITE)
Route::Route (Session& sess, string name, Flag flg, DataType default_type)
: IO (sess, name, default_type)
, _flags (flg)
, _solo_control (new ToggleControllable (X_("solo"), *this, ToggleControllable::SoloControl))
, _mute_control (new ToggleControllable (X_("mute"), *this, ToggleControllable::MuteControl))
{
_configured_inputs = in;
_configured_outputs = out;
init ();
}
@ -129,14 +126,11 @@ Route::init ()
/* amp & meter belong to IO but need to be added to our processor list */
_amp->set_sort_key (0);
_meter->set_sort_key (1);
add_processor (_amp);
add_processor (_meter);
add_processor (_amp, PostFader);
add_processor (_meter, PreFader);
_main_outs.reset (new Delivery (_session, this, _name, Delivery::Main));
ProcessorList::iterator i = _processors.end();
add_processor (_main_outs, 0, &i);
add_processor (_main_outs, PostFader);
}
Route::~Route ()
@ -598,31 +592,59 @@ dump_processors(const string& name, const list<boost::shared_ptr<Processor> >& p
cerr << name << " {" << endl;
for (list<boost::shared_ptr<Processor> >::const_iterator p = procs.begin();
p != procs.end(); ++p) {
cerr << "\t" << (*p)->sort_key() << ": " << (*p)->name() << endl;
cerr << "\t" << (*p)->name() << endl;
}
cerr << "}" << endl;
}
struct ProcessorSortByKey {
bool operator() (boost::shared_ptr<Processor> a, boost::shared_ptr<Processor> b) {
return a->sort_key() < b->sort_key();
}
};
uint32_t
Route::fader_sort_key() const
Route::ProcessorList::iterator
Route::prefader_iterator()
{
return _amp->sort_key();
Glib::RWLock::ReaderLock lm (_processor_lock);
return find (_processors.begin(), _processors.end(), _amp);
}
int
Route::add_processor (boost::shared_ptr<Processor> processor, Placement placement, ProcessorStreams* err)
{
ProcessorList::iterator loc;
/* XXX this is not thread safe - we don't hold the lock across determining the iter
to add before and actually doing the insertion. dammit.
*/
if (placement == PreFader) {
/* generic pre-fader: insert immediately before the amp */
loc = find(_processors.begin(), _processors.end(), _amp);
} else {
/* generic post-fader: insert at end */
loc = _processors.end();
if (processor->visible() && !_processors.empty()) {
/* check for invisible processors stacked at the end and leave them there */
ProcessorList::iterator p;
p = _processors.end();
--p;
cerr << "Let's check " << (*p)->name() << " vis ? " << (*p)->visible() << endl;
while (!(*p)->visible() && p != _processors.begin()) {
--p;
}
++p;
loc = p;
}
}
return add_processor (processor, loc, err);
}
/** Add a processor to the route.
* If @a iter is not NULL, it must point to an iterator in _processors and the new
* processor will be inserted immediately before this location. Otherwise,
* @a position is used.
*/
int
Route::add_processor (boost::shared_ptr<Processor> processor, ProcessorStreams* err, ProcessorList::iterator* iter)
Route::add_processor (boost::shared_ptr<Processor> processor, ProcessorList::iterator iter, ProcessorStreams* err)
{
ChanCount old_pms = processor_max_streams;
@ -630,9 +652,7 @@ Route::add_processor (boost::shared_ptr<Processor> processor, ProcessorStreams*
return 1;
}
cerr << "Adding a processor called " << processor->name() << " sk = " << processor->sort_key()
<< ((iter == 0) ? " NO given position " : " with given position")
<< endl;
cerr << "Adding a processor called " << processor->name() << endl;
{
Glib::RWLock::WriterLock lm (_processor_lock);
@ -645,15 +665,10 @@ Route::add_processor (boost::shared_ptr<Processor> processor, ProcessorStreams*
if (processor == _amp || processor == _meter || processor == _main_outs) {
// Ensure only one of these are in the list at any time
if (loc != _processors.end()) {
if (iter) {
if (*iter == loc) { // Already in place, do nothing
return 0;
} else { // New position given, relocate
_processors.erase(loc);
}
} else { // Insert at end
_processors.erase(loc);
loc = _processors.end();
if (iter == loc) { // Already in place, do nothing
return 0;
} else { // New position given, relocate
_processors.erase (loc);
}
}
@ -662,41 +677,26 @@ Route::add_processor (boost::shared_ptr<Processor> processor, ProcessorStreams*
cerr << "ERROR: Processor added to route twice!" << endl;
return 1;
}
loc = iter;
}
if (iter) {
// Use position given by user
loc = *iter;
} else {
if (processor->sort_key() == 0) {
/* generic pre-fader: insert immediately before the amp */
loc = find(_processors.begin(), _processors.end(), _amp);
} else if (processor->sort_key() > _processors.size()) {
/* generic post-fader: insert at end */
loc = _processors.end();
} else {
/* find insert point */
ProcessorSortByKey cmp;
loc = upper_bound (_processors.begin(), _processors.end(), processor, cmp);
}
}
// Update sort keys
if (loc == _processors.end()) {
processor->set_sort_key(_processors.size());
} else {
processor->set_sort_key((*loc)->sort_key());
for (ProcessorList::iterator p = loc; p != _processors.end(); ++p) {
(*p)->set_sort_key((*p)->sort_key() + 1);
}
}
cerr << "Adding " << processor->name() << endl;
_processors.insert(loc, processor);
_processors.insert (loc, processor);
// Set up processor list channels. This will set processor->[input|output]_streams(),
// configure redirect ports properly, etc.
if (configure_processors_unlocked (err)) {
ProcessorStreams rerr;
if (configure_processors_unlocked (&rerr)) {
dump_processors(_name + "bad config", _processors);
if (err) {
*err = rerr;
}
cerr << "Error at proc " << rerr.index << " with input of " << rerr.count << endl;
ProcessorList::iterator ploc = loc;
--ploc;
_processors.erase(ploc);
@ -736,8 +736,146 @@ Route::add_processor (boost::shared_ptr<Processor> processor, ProcessorStreams*
return 0;
}
bool
Route::add_processor_from_xml (const XMLNode& node, Placement placement)
{
ProcessorList::iterator loc;
if (placement == PreFader) {
/* generic pre-fader: insert immediately before the amp */
loc = find(_processors.begin(), _processors.end(), _amp);
} else {
/* generic post-fader: insert at end */
loc = _processors.end();
}
return add_processor_from_xml (node, loc);
}
bool
Route::add_processor_from_xml (const XMLNode& node, ProcessorList::iterator iter)
{
const XMLProperty *prop;
// legacy sessions use a different node name for sends
if (node.name() == "Send") {
try {
boost::shared_ptr<Send> send (new Send (_session, node));
add_processor (send, iter);
return true;
}
catch (failed_constructor &err) {
error << _("Send construction failed") << endmsg;
return false;
}
} else if (node.name() == "Processor") {
try {
if ((prop = node.property ("type")) != 0) {
boost::shared_ptr<Processor> processor;
bool have_insert = false;
if (prop->value() == "ladspa" || prop->value() == "Ladspa" ||
prop->value() == "lv2" ||
prop->value() == "vst" ||
prop->value() == "audiounit") {
processor.reset (new PluginInsert(_session, node));
have_insert = true;
} else if (prop->value() == "port") {
processor.reset (new PortInsert (_session, node));
} else if (prop->value() == "send") {
processor.reset (new Send (_session, node));
have_insert = true;
} else if (prop->value() == "meter") {
processor = _meter;
} else if (prop->value() == "amp") {
processor = _amp;
} else if (prop->value() == "listen" || prop->value() == "deliver") {
/* XXX need to generalize */
processor = _control_outs;
} else if (prop->value() == "main-outs") {
processor = _main_outs;
} else {
error << string_compose(_("unknown Processor type \"%1\"; ignored"), prop->value()) << endmsg;
}
if (iter == _processors.end() && processor->visible() && !_processors.empty()) {
/* check for invisible processors stacked at the end and leave them there */
ProcessorList::iterator p;
p = _processors.end();
--p;
cerr << "Let's check " << (*p)->name() << " vis ? " << (*p)->visible() << endl;
while (!(*p)->visible() && p != _processors.begin()) {
--p;
}
++p;
iter = p;
}
return (add_processor (processor, iter) == 0);
} else {
error << _("Processor XML node has no type property") << endmsg;
}
}
catch (failed_constructor &err) {
warning << _("processor could not be created. Ignored.") << endmsg;
return false;
}
}
return false;
}
int
Route::add_processors (const ProcessorList& others, ProcessorStreams* err, uint32_t first_sort_key)
Route::add_processors (const ProcessorList& others, Placement placement, ProcessorStreams* err)
{
ProcessorList::iterator loc;
if (placement == PreFader) {
/* generic pre-fader: insert immediately before the amp */
loc = find(_processors.begin(), _processors.end(), _amp);
} else {
/* generic post-fader: insert at end */
loc = _processors.end();
if (!_processors.empty()) {
/* check for invisible processors stacked at the end and leave them there */
ProcessorList::iterator p;
p = _processors.end();
--p;
cerr << "Let's check " << (*p)->name() << " vis ? " << (*p)->visible() << endl;
while (!(*p)->visible() && p != _processors.begin()) {
--p;
}
++p;
loc = p;
}
}
return add_processors (others, loc, err);
}
int
Route::add_processors (const ProcessorList& others, ProcessorList::iterator iter, ProcessorStreams* err)
{
/* NOTE: this is intended to be used ONLY when copying
processors from another Route. Hence the subtle
@ -750,29 +888,16 @@ Route::add_processors (const ProcessorList& others, ProcessorStreams* err, uint3
return 1;
}
if (others.empty()) {
return 0;
}
{
Glib::RWLock::WriterLock lm (_processor_lock);
ProcessorList::iterator loc;
ProcessorList::iterator existing_end = _processors.end();
--existing_end;
ChanCount potential_max_streams = ChanCount::max(input_minimum(), output_minimum());
if (first_sort_key == 0) {
/* generic pre-fader: insert immediately before the amp */
cerr << "Add new procs at amp, sk = " << first_sort_key << endl;
loc = find(_processors.begin(), _processors.end(), _amp);
} else if (first_sort_key > _processors.size()) {
/* generic post-fader: insert at end */
cerr << "Add new procs at end, sk = " << first_sort_key << endl;
loc = _processors.end();
} else {
/* find insert point */
ProcessorSortByKey cmp;
cerr << "Add new procs at sk = " << first_sort_key << endl;
loc = upper_bound (_processors.begin(), _processors.end(), others.front(), cmp);
}
ChanCount potential_max_streams = ChanCount::max (n_inputs(), n_outputs());
for (ProcessorList::const_iterator i = others.begin(); i != others.end(); ++i) {
@ -797,7 +922,7 @@ Route::add_processors (const ProcessorList& others, ProcessorStreams* err, uint3
// Ensure peak vector sizes before the plugin is activated
_meter->configure_io (potential_max_streams, potential_max_streams);
_processors.insert (loc, *i);
_processors.insert (iter, *i);
if (configure_processors_unlocked (err)) {
++existing_end;
@ -1150,16 +1275,18 @@ Route::configure_processors_unlocked (ProcessorStreams* err)
_in_configure_processors = true;
// Check each processor in order to see if we can configure as requested
ChanCount in = _configured_inputs;
ChanCount in = n_inputs();
ChanCount out;
list< pair<ChanCount,ChanCount> > configuration;
uint32_t index = 0;
for (ProcessorList::iterator p = _processors.begin(); p != _processors.end(); ++p, ++index) {
(*p)->set_sort_key(index);
cerr << "Can " << (*p)->name() << " support in= " << in << " out= " << out;
if ((*p)->can_support_io_configuration(in, out)) {
cerr << " yes\n";
configuration.push_back(make_pair(in, out));
in = out;
} else {
cerr << " no\n";
if (err) {
err->index = index;
err->count = in;
@ -1181,7 +1308,7 @@ Route::configure_processors_unlocked (ProcessorStreams* err)
// Ensure route outputs match last processor's outputs
if (out != n_outputs()) {
ensure_io(_configured_inputs, out, false, this);
ensure_io (n_inputs(), out, false, this);
}
_in_configure_processors = false;
@ -1244,21 +1371,68 @@ Route::all_processors_active (Placement p, bool state)
}
int
Route::sort_processors (ProcessorStreams* err)
Route::reorder_processors (const ProcessorList& new_order, Placement placement, ProcessorStreams* err)
{
{
ProcessorSortByKey comparator;
Glib::RWLock::WriterLock lm (_processor_lock);
ChanCount old_pms = processor_max_streams;
/* the sweet power of C++ ... */
ProcessorList::iterator oiter;
ProcessorList::const_iterator niter;
ProcessorList as_it_was_before = _processors;
ProcessorList as_it_will_be;
ProcessorList::iterator start, end;
dump_processors (_name + " PRESORT", _processors);
dump_processors (_name + " PreReorder", _processors);
placement_range (placement, start, end);
oiter = start;
niter = new_order.begin();
while (oiter != end && niter != new_order.end()) {
/* if the next processor in the old list is invisible (i.e. should not be in the new order)
then append it to the temp list.
Otherwise, see if the next processor in the old list is in the new list. if not,
its been deleted. If its there, append it to the temp list.
*/
if (oiter == end) {
/* no more elements in the old list, so just stick the rest of
the new order onto the temp list.
*/
as_it_will_be.insert (as_it_will_be.end(), niter, new_order.end());
} else {
if (!(*oiter)->visible()) {
as_it_will_be.push_back (*oiter);
} else {
/* visible processor: check that its in the new order */
if (find (new_order.begin(), new_order.end(), (*oiter)) == new_order.end()) {
/* deleted: do nothing */
} else {
/* ignore this one, and add the next item from the new order instead */
as_it_will_be.push_back (*niter);
++niter;
}
}
/* now remove from old order - its taken care of no matter what */
oiter = _processors.erase (oiter);
}
}
_processors.insert (end, as_it_will_be.begin(), as_it_will_be.end());
dump_processors (_name + " PostReorder", _processors);
_processors.sort (comparator);
if (configure_processors_unlocked (err)) {
_processors = as_it_was_before;
processor_max_streams = old_pms;
@ -1267,6 +1441,7 @@ Route::sort_processors (ProcessorStreams* err)
}
dump_processors (_name + " sorted", _processors);
/* do we really need to do this every time? */
reset_panner ();
processors_changed (); /* EMIT SIGNAL */
@ -1440,96 +1615,12 @@ Route::set_deferred_state ()
nlist = deferred_state->children();
for (niter = nlist.begin(); niter != nlist.end(); ++niter){
add_processor_from_xml (**niter);
}
_set_processor_states (nlist);
delete deferred_state;
deferred_state = 0;
}
bool
Route::add_processor_from_xml (const XMLNode& node, ProcessorList::iterator* iter)
{
const XMLProperty *prop;
// legacy sessions use a different node name for sends
if (node.name() == "Send") {
try {
boost::shared_ptr<Send> send (new Send (_session, node));
add_processor (send, 0, iter);
return true;
}
catch (failed_constructor &err) {
error << _("Send construction failed") << endmsg;
return false;
}
} else if (node.name() == "Processor") {
try {
if ((prop = node.property ("type")) != 0) {
boost::shared_ptr<Processor> processor;
bool have_insert = false;
if (prop->value() == "ladspa" || prop->value() == "Ladspa" ||
prop->value() == "lv2" ||
prop->value() == "vst" ||
prop->value() == "audiounit") {
processor.reset (new PluginInsert(_session, node));
have_insert = true;
} else if (prop->value() == "port") {
processor.reset (new PortInsert (_session, node));
} else if (prop->value() == "send") {
processor.reset (new Send (_session, node));
have_insert = true;
} else if (prop->value() == "meter") {
processor = _meter;
} else if (prop->value() == "amp") {
processor = _amp;
} else if (prop->value() == "listen" || prop->value() == "deliver") {
/* XXX need to generalize */
processor = _control_outs;
} else if (prop->value() == "main-outs") {
processor = _main_outs;
} else {
error << string_compose(_("unknown Processor type \"%1\"; ignored"), prop->value()) << endmsg;
}
return (add_processor (processor, 0, iter) == 0);
} else {
error << _("Processor XML node has no type property") << endmsg;
}
}
catch (failed_constructor &err) {
warning << _("processor could not be created. Ignored.") << endmsg;
return false;
}
}
return false;
}
int
Route::set_state (const XMLNode& node)
{
@ -1671,31 +1762,23 @@ Route::_set_state (const XMLNode& node, bool call_base)
}
}
XMLNodeList processor_nodes;
bool has_meter_processor = false; // legacy sessions don't
for (niter = nlist.begin(); niter != nlist.end(); ++niter){
child = *niter;
if (child->name() == X_("Send") || child->name() == X_("Processor")) {
processor_nodes.push_back(child);
if ((prop = child->property (X_("type"))) != 0 && prop->value() == "meter") {
has_meter_processor = true;
}
deferred_state->add_child_copy (*child);
}
}
_set_processor_states(processor_nodes);
if (!has_meter_processor) {
set_meter_point(_meter_point, NULL);
if (ports_legal) {
_set_processor_states (deferred_state->children());
delete deferred_state;
deferred_state = 0;
}
processors_changed ();
for (niter = nlist.begin(); niter != nlist.end(); ++niter){
child = *niter;
// All processors have been applied already
if (child->name() == X_("Automation")) {
@ -1752,9 +1835,11 @@ void
Route::_set_processor_states(const XMLNodeList &nlist)
{
XMLNodeConstIterator niter;
bool has_meter_processor = false; // legacy sessions don't
ProcessorList::iterator i, o;
cerr << "Setting processor states with in = " << n_inputs() << endl;
// Iterate through existing processors, remove those which are not in the state list
for (i = _processors.begin(); i != _processors.end(); ) {
ProcessorList::iterator tmp = i;
@ -1785,7 +1870,11 @@ Route::_set_processor_states(const XMLNodeList &nlist)
for (niter = nlist.begin(); niter != nlist.end(); ++niter, ++i) {
XMLProperty* prop = (*niter)->property ("type");
if (prop && prop->value() == "meter") {
has_meter_processor = true;
}
o = i;
if (prop->value() != "meter" && prop->value() != "amp" && prop->value() != "main-outs") {
@ -1806,7 +1895,7 @@ Route::_set_processor_states(const XMLNodeList &nlist)
// create it and move it to the correct location
if (o == _processors.end()) {
if (add_processor_from_xml (**niter, &i)) {
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;
@ -1818,7 +1907,6 @@ Route::_set_processor_states(const XMLNodeList &nlist)
if (i != o) {
boost::shared_ptr<Processor> tmp = (*o);
cerr << "move proc from state\n";
_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
@ -1827,6 +1915,19 @@ Route::_set_processor_states(const XMLNodeList &nlist)
(*i)->set_state (**niter);
}
}
/* note: there is no configure_processors() call because we figure that
the XML state represents a working signal route.
*/
if (!has_meter_processor) {
set_meter_point (_meter_point, NULL);
}
processors_changed ();
}
void
@ -1887,8 +1988,7 @@ Route::add_listener (boost::shared_ptr<IO> io, const string& listen_name)
return boost::shared_ptr<Delivery>();
}
listener->set_sort_key (_meter->sort_key() + 1);
add_processor (listener, NULL);
add_processor (listener, PostFader);
return listener;
}
@ -2360,16 +2460,6 @@ Route::set_meter_point (MeterPoint p, void *src)
}
_processors.insert(loc, _meter);
// Update sort key
if (loc == _processors.end()) {
_meter->set_sort_key(_processors.size());
} else {
_meter->set_sort_key((*loc)->sort_key());
for (ProcessorList::iterator p = loc; p != _processors.end(); ++p) {
(*p)->set_sort_key((*p)->sort_key() + 1);
}
}
meter_change (src); /* EMIT SIGNAL */
processors_changed (); /* EMIT SIGNAL */
_session.set_dirty ();

View file

@ -108,8 +108,7 @@ Send::set_state(const XMLNode& node)
bool
Send::can_support_io_configuration (const ChanCount& in, ChanCount& out) const
{
if (_io->input_maximum() == ChanCount::INFINITE
&& _io->output_maximum() == ChanCount::INFINITE) {
if (_io->n_inputs() == ChanCount::ZERO && _io->n_outputs() == ChanCount::ZERO) {
/* not configured yet, we can support anything */
@ -120,10 +119,8 @@ Send::can_support_io_configuration (const ChanCount& in, ChanCount& out) const
/* for a send, processor input corresponds to IO output */
if (_io->output_maximum() == in) {
out = in;
return true;
}
out = in;
return true;
}
return false;
@ -138,11 +135,6 @@ Send::configure_io (ChanCount in, ChanCount out)
return false;
}
/*_io->set_output_maximum (in);
_io->set_output_minimum (in);
_io->set_input_maximum (ChanCount::ZERO);
_io->set_input_minimum (ChanCount::ZERO);*/
if (_io->ensure_io (ChanCount::ZERO, in, false, this) != 0) {
return false;
}

View file

@ -271,8 +271,8 @@ Session::Session (AudioEngine &eng,
if (control_out_channels) {
ChanCount count(DataType::AUDIO, control_out_channels);
shared_ptr<Route> r (new Route (*this, _("monitor"), Route::ControlOut,
DataType::AUDIO, count, count));
shared_ptr<Route> r (new Route (*this, _("monitor"), Route::ControlOut, DataType::AUDIO));
r->ensure_io (count, count, false, this);
r->set_remote_control_id (control_id++);
rl.push_back (r);
@ -281,8 +281,8 @@ Session::Session (AudioEngine &eng,
if (master_out_channels) {
ChanCount count(DataType::AUDIO, master_out_channels);
cerr << "new MO with " << count << endl;
shared_ptr<Route> r (new Route (*this, _("master"), Route::MasterOut,
DataType::AUDIO, count, count));
shared_ptr<Route> r (new Route (*this, _("master"), Route::MasterOut, DataType::AUDIO));
r->ensure_io (count, count, false, this);
r->set_remote_control_id (control_id);
rl.push_back (r);
@ -671,12 +671,9 @@ Session::when_engine_running ()
_master_out->ports_became_legal();
}
/* create ports, without any connections
*/
_master_out->ensure_io (_master_out->input_minimum (), _master_out->output_minimum (), true, this);
/* if requested auto-connect the outputs to the first N physical ports.
*/
if (Config->get_auto_connect_master()) {
uint32_t limit = _master_out->n_outputs().n_total();
@ -771,7 +768,7 @@ Session::hookup_io ()
if (_control_out) {
_control_out->ensure_io (_control_out->input_minimum(), _control_out->output_minimum(), false, this);
// _control_out->ensure_io (_control_out->input_minimum(), _control_out->output_minimum(), false, this);
boost::shared_ptr<RouteList> r = routes.reader ();

View file

@ -86,7 +86,7 @@ class DnDTreeView : public DnDTreeViewBase
DnDTreeView() {}
~DnDTreeView() {}
sigc::signal<void,const std::list<DataType>& > signal_drop;
sigc::signal<void,const std::list<DataType>&,Gtk::TreeView*,Glib::RefPtr<Gdk::DragContext>&> signal_drop;
void on_drag_data_get(const Glib::RefPtr<Gdk::DragContext>& context, Gtk::SelectionData& selection_data, guint info, guint time) {
if (selection_data.get_target() == "GTK_TREE_MODEL_ROW") {
@ -123,7 +123,7 @@ class DnDTreeView : public DnDTreeViewBase
} else if (selection_data.get_target() == object_type) {
end_object_drag ();
end_object_drag (const_cast<Glib::RefPtr<Gdk::DragContext>& > (context));
} else {
/* some kind of target type added by the app, which will be handled by a signal handler */
@ -135,7 +135,7 @@ class DnDTreeView : public DnDTreeViewBase
* object that wants to get the list of dragged items.
*/
void get_object_drag_data (std::list<DataType>& l) {
void get_object_drag_data (std::list<DataType>& l, Gtk::TreeView** source) {
Glib::RefPtr<Gtk::TreeModel> model = drag_data.source->get_model();
DataType v;
Gtk::TreeSelection::ListHandle_Path selection = drag_data.source->get_selection()->get_selected_rows ();
@ -144,13 +144,16 @@ class DnDTreeView : public DnDTreeViewBase
model->get_iter (*x)->get_value (drag_data.data_column, v);
l.push_back (v);
}
*source = drag_data.source;
}
private:
void end_object_drag () {
void end_object_drag (Glib::RefPtr<Gdk::DragContext>& context) {
std::list<DataType> l;
get_object_drag_data (l);
signal_drop (l);
Gtk::TreeView* source;
get_object_drag_data (l, &source);
signal_drop (l, source, context);
}
};