diff options
author | Paul Davis <paul@linuxaudiosystems.com> | 2009-05-16 02:51:17 +0000 |
---|---|---|
committer | Paul Davis <paul@linuxaudiosystems.com> | 2009-05-16 02:51:17 +0000 |
commit | ace07c80a81a631eb8ff95155e5ace2751838809 (patch) | |
tree | 4e440b7878535f04561dbddbe3ae4848a3207840 | |
parent | 86dda29be798073d3d8b08aa833b52773b41daad (diff) |
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
-rw-r--r-- | gtk2_ardour/editor_canvas.cc | 3 | ||||
-rw-r--r-- | gtk2_ardour/io_selector.cc | 41 | ||||
-rw-r--r-- | gtk2_ardour/io_selector.h | 2 | ||||
-rw-r--r-- | gtk2_ardour/processor_box.cc | 91 | ||||
-rw-r--r-- | gtk2_ardour/processor_box.h | 5 | ||||
-rw-r--r-- | libs/ardour/ardour/io.h | 26 | ||||
-rw-r--r-- | libs/ardour/ardour/processor.h | 4 | ||||
-rw-r--r-- | libs/ardour/ardour/route.h | 26 | ||||
-rw-r--r-- | libs/ardour/audio_track.cc | 5 | ||||
-rw-r--r-- | libs/ardour/audioengine.cc | 1 | ||||
-rw-r--r-- | libs/ardour/io.cc | 200 | ||||
-rw-r--r-- | libs/ardour/midi_track.cc | 6 | ||||
-rw-r--r-- | libs/ardour/plugin_insert.cc | 4 | ||||
-rw-r--r-- | libs/ardour/processor.cc | 11 | ||||
-rw-r--r-- | libs/ardour/route.cc | 504 | ||||
-rw-r--r-- | libs/ardour/send.cc | 14 | ||||
-rw-r--r-- | libs/ardour/session.cc | 15 | ||||
-rw-r--r-- | libs/gtkmm2ext/gtkmm2ext/dndtreeview.h | 15 |
18 files changed, 435 insertions, 538 deletions
diff --git a/gtk2_ardour/editor_canvas.cc b/gtk2_ardour/editor_canvas.cc index bdb051173d..428334dfc6 100644 --- a/gtk2_ardour/editor_canvas.cc +++ b/gtk2_ardour/editor_canvas.cc @@ -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) { diff --git a/gtk2_ardour/io_selector.cc b/gtk2_ardour/io_selector.cc index 93ade90dca..3bc4836920 100644 --- a/gtk2_ardour/io_selector.cc +++ b/gtk2_ardour/io_selector.cc @@ -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 diff --git a/gtk2_ardour/io_selector.h b/gtk2_ardour/io_selector.h index ccd3bc929f..872fd5d7d6 100644 --- a/gtk2_ardour/io_selector.h +++ b/gtk2_ardour/io_selector.h @@ -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; diff --git a/gtk2_ardour/processor_box.cc b/gtk2_ardour/processor_box.cc index a259a25695..027d9df51e 100644 --- a/gtk2_ardour/processor_box.cc +++ b/gtk2_ardour/processor_box.cc @@ -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; -} - diff --git a/gtk2_ardour/processor_box.h b/gtk2_ardour/processor_box.h index f5af4c49dc..a003ed8c5d 100644 --- a/gtk2_ardour/processor_box.h +++ b/gtk2_ardour/processor_box.h @@ -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 (); diff --git a/libs/ardour/ardour/io.h b/libs/ardour/ardour/io.h index 297a4ee82c..5c7d8d0f0f 100644 --- a/libs/ardour/ardour/io.h +++ b/libs/ardour/ardour/io.h @@ -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); diff --git a/libs/ardour/ardour/processor.h b/libs/ardour/ardour/processor.h index 68fdb5c6a6..73a93b31d9 100644 --- a/libs/ardour/ardour/processor.h +++ b/libs/ardour/ardour/processor.h @@ -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; }; diff --git a/libs/ardour/ardour/route.h b/libs/ardour/ardour/route.h index aee361d3a5..c498b1f04e 100644 --- a/libs/ardour/ardour/route.h +++ b/libs/ardour/ardour/route.h @@ -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 diff --git a/libs/ardour/audio_track.cc b/libs/ardour/audio_track.cc index 878ad1118f..70e317c880 100644 --- a/libs/ardour/audio_track.cc +++ b/libs/ardour/audio_track.cc @@ -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(); diff --git a/libs/ardour/audioengine.cc b/libs/ardour/audioengine.cc index 1dc646b610..fe9c064efa 100644 --- a/libs/ardour/audioengine.cc +++ b/libs/ardour/audioengine.cc @@ -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 diff --git a/libs/ardour/io.cc b/libs/ardour/io.cc index cdd80b747d..0cacdb160e 100644 --- a/libs/ardour/io.cc +++ b/libs/ardour/io.cc @@ -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; } @@ -1971,30 +1878,6 @@ IO::set_name (const string& requested_name) } 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) { Glib::Mutex::Lock lm (io_lock); @@ -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); diff --git a/libs/ardour/midi_track.cc b/libs/ardour/midi_track.cc index 6feb3253ce..c993b17ced 100644 --- a/libs/ardour/midi_track.cc +++ b/libs/ardour/midi_track.cc @@ -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 () diff --git a/libs/ardour/plugin_insert.cc b/libs/ardour/plugin_insert.cc index 6a6e9cf100..f7a348f33f 100644 --- a/libs/ardour/plugin_insert.cc +++ b/libs/ardour/plugin_insert.cc @@ -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; diff --git a/libs/ardour/processor.cc b/libs/ardour/processor.cc index 84fb43d68c..3fc9fcaee2 100644 --- a/libs/ardour/processor.cc +++ b/libs/ardour/processor.cc @@ -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); diff --git a/libs/ardour/route.cc b/libs/ardour/route.cc index 06b9308d35..67ff44a709 100644 --- a/libs/ardour/route.cc +++ b/libs/ardour/route.cc @@ -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; } +Route::ProcessorList::iterator +Route::prefader_iterator() +{ + Glib::RWLock::ReaderLock lm (_processor_lock); + return find (_processors.begin(), _processors.end(), _amp); +} -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 +int +Route::add_processor (boost::shared_ptr<Processor> processor, Placement placement, ProcessorStreams* err) { - return _amp->sort_key(); + 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; } - } - 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); - } + loc = iter; } - _processors.insert(loc, processor); + cerr << "Adding " << processor->name() << endl; + + _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; + ProcessorList::iterator oiter; + ProcessorList::const_iterator niter; + ProcessorList as_it_was_before = _processors; + ProcessorList as_it_will_be; + ProcessorList::iterator start, end; - /* the sweet power of C++ ... */ + dump_processors (_name + " PreReorder", _processors); + placement_range (placement, start, end); - ProcessorList as_it_was_before = _processors; + oiter = start; + niter = new_order.begin(); - dump_processors (_name + " PRESORT", _processors); + 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 (); diff --git a/libs/ardour/send.cc b/libs/ardour/send.cc index e4de26e864..852f27d38f 100644 --- a/libs/ardour/send.cc +++ b/libs/ardour/send.cc @@ -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; } diff --git a/libs/ardour/session.cc b/libs/ardour/session.cc index eebde5ffa7..db6063e7f4 100644 --- a/libs/ardour/session.cc +++ b/libs/ardour/session.cc @@ -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 (); diff --git a/libs/gtkmm2ext/gtkmm2ext/dndtreeview.h b/libs/gtkmm2ext/gtkmm2ext/dndtreeview.h index 085e500f21..cc9d1c1463 100644 --- a/libs/gtkmm2ext/gtkmm2ext/dndtreeview.h +++ b/libs/gtkmm2ext/gtkmm2ext/dndtreeview.h @@ -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); } }; |