mirror of
https://github.com/Ardour/ardour.git
synced 2026-01-05 21:25:46 +01:00
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:
parent
86dda29be7
commit
ace07c80a8
18 changed files with 437 additions and 540 deletions
|
|
@ -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) {
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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 ();
|
||||
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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 ()
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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 ();
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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 ();
|
||||
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
||||
};
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue