startup assistant patch from tinman; cleanup fix backported from 2.X ; easy(ier) ways to create aux sends ; facility to subgroup (route via bus) for a route group ; fix up internal send/return operation ; fix internal send naming since it doesn't need to be unique - no JACK ports involved
git-svn-id: svn://localhost/ardour2/branches/3.0@5272 d708f5d6-7413-0410-9779-e7cbd77b26cf
This commit is contained in:
parent
94880f7cd1
commit
8e7a5d7741
|
@ -1863,6 +1863,8 @@ public:
|
|||
void build_route_group_menu (ARDOUR::RouteGroup *);
|
||||
void activate_all_route_groups ();
|
||||
void disable_all_route_groups ();
|
||||
void subgroup_route_group (ARDOUR::RouteGroup*);
|
||||
void unsubgroup_route_group (ARDOUR::RouteGroup*);
|
||||
|
||||
bool in_route_group_row_change;
|
||||
void route_group_row_change (const Gtk::TreeModel::Path&,const Gtk::TreeModel::iterator&);
|
||||
|
|
|
@ -559,6 +559,7 @@ Editor::embed_sndfiles (vector<Glib::ustring> paths, bool multifile,
|
|||
string linked_path;
|
||||
SoundFileInfo finfo;
|
||||
int ret = 0;
|
||||
Glib::ustring path_to_use;
|
||||
|
||||
track_canvas->get_window()->set_cursor (Gdk::Cursor (Gdk::WATCH));
|
||||
gdk_flush ();
|
||||
|
@ -571,6 +572,8 @@ Editor::embed_sndfiles (vector<Glib::ustring> paths, bool multifile,
|
|||
|
||||
sys::path tmp = session->session_directory().sound_path() / Glib::path_get_basename(path);
|
||||
linked_path = tmp.to_string();
|
||||
|
||||
path_to_use = linked_path;
|
||||
|
||||
if (link (path.c_str(), linked_path.c_str()) == 0) {
|
||||
|
||||
|
@ -581,6 +584,7 @@ Editor::embed_sndfiles (vector<Glib::ustring> paths, bool multifile,
|
|||
*/
|
||||
|
||||
path = linked_path;
|
||||
path_to_use = Glib::path_get_basename (path);
|
||||
|
||||
} else {
|
||||
|
||||
|
@ -592,6 +596,7 @@ Editor::embed_sndfiles (vector<Glib::ustring> paths, bool multifile,
|
|||
if (stat (linked_path.c_str(), &sb) == 0) {
|
||||
if (sb.st_nlink > 1) { // its a hard link, assume its the one we want
|
||||
path = linked_path;
|
||||
path_to_use = Glib::path_get_basename (path);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -673,7 +678,7 @@ Editor::embed_sndfiles (vector<Glib::ustring> paths, bool multifile,
|
|||
|
||||
source = boost::dynamic_pointer_cast<AudioFileSource> (
|
||||
SourceFactory::createReadable (DataType::AUDIO, *session,
|
||||
path, false, n,
|
||||
path_to_use, false, n,
|
||||
(mode == ImportAsTapeTrack
|
||||
? Source::Destructive
|
||||
: Source::Flag (0)),
|
||||
|
|
|
@ -66,12 +66,25 @@ Editor::build_route_group_menu (RouteGroup* g)
|
|||
if (g) {
|
||||
items.push_back (MenuElem (_("Edit..."), bind (mem_fun (*this, &Editor::edit_route_group), g)));
|
||||
items.push_back (MenuElem (_("Fit to Window"), bind (mem_fun (*this, &Editor::fit_route_group), g)));
|
||||
items.push_back (MenuElem (_("Subgroup"), bind (mem_fun (*this, &Editor::subgroup_route_group), g)));
|
||||
}
|
||||
items.push_back (SeparatorElem());
|
||||
items.push_back (MenuElem (_("Activate All"), mem_fun(*this, &Editor::activate_all_route_groups)));
|
||||
items.push_back (MenuElem (_("Disable All"), mem_fun(*this, &Editor::disable_all_route_groups)));
|
||||
}
|
||||
|
||||
void
|
||||
Editor::subgroup_route_group (RouteGroup* g)
|
||||
{
|
||||
g->make_subgroup ();
|
||||
}
|
||||
|
||||
void
|
||||
Editor::unsubgroup_route_group (RouteGroup* g)
|
||||
{
|
||||
g->destroy_subgroup ();
|
||||
}
|
||||
|
||||
void
|
||||
Editor::activate_all_route_groups ()
|
||||
{
|
||||
|
|
|
@ -173,6 +173,8 @@ MixerGroupTabs::get_menu (RouteGroup* g)
|
|||
|
||||
MenuList& items = _menu->items ();
|
||||
items.push_back (MenuElem (_("Edit..."), bind (mem_fun (*this, &MixerGroupTabs::edit_group), g)));
|
||||
items.push_back (MenuElem (_("Subgroup"), bind (mem_fun (*this, &MixerGroupTabs::make_subgroup), g)));
|
||||
items.push_back (SeparatorElem());
|
||||
items.push_back (MenuElem (_("Remove"), bind (mem_fun (*this, &MixerGroupTabs::remove_group), g)));
|
||||
|
||||
return _menu;
|
||||
|
@ -190,3 +192,15 @@ MixerGroupTabs::remove_group (RouteGroup *g)
|
|||
{
|
||||
_session->remove_route_group (*g);
|
||||
}
|
||||
|
||||
void
|
||||
MixerGroupTabs::make_subgroup (RouteGroup* g)
|
||||
{
|
||||
g->make_subgroup ();
|
||||
}
|
||||
|
||||
void
|
||||
MixerGroupTabs::destroy_subgroup (RouteGroup* g)
|
||||
{
|
||||
g->destroy_subgroup ();
|
||||
}
|
||||
|
|
|
@ -38,7 +38,9 @@ private:
|
|||
|
||||
void edit_group (ARDOUR::RouteGroup *);
|
||||
void remove_group (ARDOUR::RouteGroup *);
|
||||
|
||||
void make_subgroup (ARDOUR::RouteGroup *);
|
||||
void destroy_subgroup (ARDOUR::RouteGroup *);
|
||||
|
||||
Mixer_UI* _mixer;
|
||||
Gtk::Menu* _menu;
|
||||
};
|
||||
|
|
|
@ -517,9 +517,17 @@ RouteUI::build_sends_menu ()
|
|||
sends_menu->set_name ("ArdourContextMenu");
|
||||
MenuList& items = sends_menu->items();
|
||||
|
||||
items.push_back (MenuElem(_("Assign all tracks"), mem_fun (*this, &RouteUI::create_sends)));
|
||||
items.push_back (MenuElem(_("Copy track gains to sends"), mem_fun (*this, &RouteUI::set_sends_gain_from_track)));
|
||||
items.push_back (MenuElem(_("Set sends gain to -inf"), mem_fun (*this, &RouteUI::set_sends_gain_to_zero)));
|
||||
items.push_back (MenuElem(_("Set sends gain to 0dB"), mem_fun (*this, &RouteUI::set_sends_gain_to_unity)));
|
||||
|
||||
}
|
||||
|
||||
void
|
||||
RouteUI::create_sends ()
|
||||
{
|
||||
_session.globally_add_internal_sends (_route);
|
||||
}
|
||||
|
||||
void
|
||||
|
|
|
@ -118,6 +118,7 @@ class RouteUI : public virtual AxisView
|
|||
void set_sends_gain_from_track ();
|
||||
void set_sends_gain_to_zero ();
|
||||
void set_sends_gain_to_unity ();
|
||||
void create_sends ();
|
||||
|
||||
void solo_changed(void*);
|
||||
void solo_changed_so_update_mute ();
|
||||
|
|
|
@ -70,6 +70,7 @@ Ardour will play NO role in monitoring"))
|
|||
use_session_as_template_button.set_group (session_template_group);
|
||||
|
||||
set_keep_above (true);
|
||||
set_resizable (false);
|
||||
set_position (WIN_POS_CENTER);
|
||||
set_border_width (12);
|
||||
|
||||
|
@ -206,6 +207,8 @@ ArdourStartup::setup_audio_page ()
|
|||
{
|
||||
engine_dialog = manage (new EngineControl);
|
||||
|
||||
engine_dialog->set_border_width (12);
|
||||
|
||||
engine_dialog->show_all ();
|
||||
|
||||
audio_page_index = append_page (*engine_dialog);
|
||||
|
@ -235,11 +238,10 @@ using the program.</span>\
|
|||
HBox* hbox = manage (new HBox);
|
||||
HBox* vbox = manage (new HBox);
|
||||
|
||||
hbox->set_border_width (12);
|
||||
vbox->set_border_width (12);
|
||||
vbox->set_border_width (24);
|
||||
|
||||
hbox->pack_start (*foomatic, false, true);
|
||||
vbox->pack_start (*hbox, false, true);
|
||||
hbox->pack_start (*foomatic, true, true);
|
||||
vbox->pack_start (*hbox, true, true);
|
||||
|
||||
foomatic->show ();
|
||||
hbox->show ();
|
||||
|
@ -265,30 +267,29 @@ ArdourStartup::setup_first_time_config_page ()
|
|||
default_dir_chooser = manage (new FileChooserButton (_("Default folder for Ardour sessions"),
|
||||
FILE_CHOOSER_ACTION_SELECT_FOLDER));
|
||||
Gtk::Label* txt = manage (new Label);
|
||||
HBox* hbox1 = manage (new HBox);
|
||||
HBox* hbox = manage (new HBox);
|
||||
VBox* vbox = manage (new VBox);
|
||||
|
||||
txt->set_markup (_("\
|
||||
Each project that you work on with Ardour has its own folder.\n\
|
||||
These can require a lot of disk space if you are recording audio.\n\
|
||||
\n\
|
||||
Where would you like new Ardour sessions to be stored by default?\n\
|
||||
<i>(You can put new sessions anywhere - this is just a default)</i>"));
|
||||
Where would you like new Ardour sessions to be stored by default?\n\n\
|
||||
<i>(You can put new sessions anywhere, this is just a default)</i>"));
|
||||
txt->set_alignment (0.0, 0.0);
|
||||
|
||||
hbox1->set_border_width (6);
|
||||
vbox->set_border_width (6);
|
||||
vbox->set_spacing (18);
|
||||
vbox->set_border_width (24);
|
||||
|
||||
hbox1->pack_start (*default_dir_chooser, false, true);
|
||||
vbox->pack_start (*txt, false, true);
|
||||
vbox->pack_start (*hbox1, false, true);
|
||||
hbox->pack_start (*default_dir_chooser, false, true, 8);
|
||||
vbox->pack_start (*txt, false, false);
|
||||
vbox->pack_start (*hbox, false, true);
|
||||
|
||||
default_dir_chooser->set_current_folder (poor_mans_glob (Config->get_default_session_parent_dir()));
|
||||
default_dir_chooser->signal_current_folder_changed().connect (mem_fun (*this, &ArdourStartup::default_dir_changed));
|
||||
default_dir_chooser->show ();
|
||||
|
||||
txt->show ();
|
||||
hbox1->show ();
|
||||
vbox->show ();
|
||||
vbox->show_all ();
|
||||
|
||||
default_folder_page_index = append_page (*vbox);
|
||||
set_page_title (*vbox, _("Default folder for new sessions"));
|
||||
|
@ -303,9 +304,11 @@ Where would you like new Ardour sessions to be stored by default?\n\
|
|||
void
|
||||
ArdourStartup::setup_monitoring_choice_page ()
|
||||
{
|
||||
mon_vbox.set_spacing (6);
|
||||
mon_vbox.set_border_width (6);
|
||||
mon_vbox.set_spacing (18);
|
||||
mon_vbox.set_border_width (24);
|
||||
|
||||
HBox* hbox = manage (new HBox);
|
||||
VBox* vbox = manage (new VBox);
|
||||
RadioButton::Group g (monitor_via_hardware_button.get_group());
|
||||
monitor_via_ardour_button.set_group (g);
|
||||
|
||||
|
@ -315,16 +318,18 @@ signal as well as record it. This is called \"monitoring\". There are\n\
|
|||
different ways to do this depending on the equipment you have and the\n\
|
||||
configuration of that equipment. The two most common are presented here.\n\
|
||||
Please choose whichever one is right for your setup.\n\n\
|
||||
<i>You can change this preference at any time, via the Options menu</i>");
|
||||
<i>(You can change this preference at any time, via the Options menu)</i>");
|
||||
monitor_label.set_alignment (0.0, 0.0);
|
||||
|
||||
vbox->set_spacing (6);
|
||||
|
||||
vbox->pack_start (monitor_via_hardware_button, false, true);
|
||||
vbox->pack_start (monitor_via_ardour_button, false, true);
|
||||
hbox->pack_start (*vbox, true, true, 8);
|
||||
mon_vbox.pack_start (monitor_label, false, false);
|
||||
mon_vbox.pack_start (monitor_via_hardware_button, false, false);
|
||||
mon_vbox.pack_start (monitor_via_ardour_button, false, false);
|
||||
mon_vbox.pack_start (*hbox, false, false);
|
||||
|
||||
mon_vbox.show ();
|
||||
monitor_label.show ();
|
||||
monitor_via_ardour_button.show ();
|
||||
monitor_via_hardware_button.show ();
|
||||
mon_vbox.show_all ();
|
||||
|
||||
monitoring_page_index = append_page (mon_vbox);
|
||||
set_page_title (mon_vbox, _("Monitoring Choices"));
|
||||
|
@ -341,7 +346,7 @@ void
|
|||
ArdourStartup::setup_initial_choice_page ()
|
||||
{
|
||||
ic_vbox.set_spacing (6);
|
||||
ic_vbox.set_border_width (6);
|
||||
ic_vbox.set_border_width (24);
|
||||
|
||||
RadioButton::Group g (ic_new_session_button.get_group());
|
||||
ic_existing_session_button.set_group (g);
|
||||
|
@ -349,21 +354,19 @@ ArdourStartup::setup_initial_choice_page ()
|
|||
HBox* centering_hbox = manage (new HBox);
|
||||
VBox* centering_vbox = manage (new VBox);
|
||||
|
||||
centering_vbox->set_spacing (6);
|
||||
|
||||
centering_vbox->pack_start (ic_new_session_button, false, true);
|
||||
centering_vbox->pack_start (ic_existing_session_button, false, true);
|
||||
centering_vbox->show ();
|
||||
|
||||
centering_hbox->pack_start (*centering_vbox, true, true);
|
||||
centering_hbox->show ();
|
||||
|
||||
ic_vbox.pack_start (*centering_hbox, true, true);
|
||||
|
||||
ic_new_session_button.show ();
|
||||
ic_existing_session_button.show ();
|
||||
ic_vbox.show ();
|
||||
ic_vbox.show_all ();
|
||||
|
||||
initial_choice_index = append_page (ic_vbox);
|
||||
set_page_title (ic_vbox, _("What would you like to do?"));
|
||||
set_page_title (ic_vbox, _("What would you like to do ?"));
|
||||
set_page_header_image (ic_vbox, icon_pixbuf);
|
||||
|
||||
/* user could just click on "Forward" if default
|
||||
|
@ -376,12 +379,10 @@ ArdourStartup::setup_initial_choice_page ()
|
|||
void
|
||||
ArdourStartup::setup_session_page ()
|
||||
{
|
||||
session_hbox.set_border_width (12);
|
||||
session_vbox.set_border_width (12);
|
||||
session_vbox.set_border_width (24);
|
||||
|
||||
session_vbox.pack_start (session_hbox, true, true);
|
||||
session_vbox.show ();
|
||||
session_hbox.show ();
|
||||
session_vbox.show_all ();
|
||||
|
||||
session_page_index = append_page (session_vbox);
|
||||
/* initial setting */
|
||||
|
@ -483,22 +484,21 @@ ArdourStartup::setup_new_session_page ()
|
|||
session_hbox.remove (**session_hbox.get_children().begin());
|
||||
}
|
||||
|
||||
if (session_new_vbox.get_children().empty()) {
|
||||
|
||||
session_new_vbox.set_spacing (12);
|
||||
session_new_vbox.set_spacing (18);
|
||||
|
||||
if (session_new_vbox.get_children().empty()) {
|
||||
VBox *vbox1 = manage (new VBox);
|
||||
HBox* hbox1 = manage (new HBox);
|
||||
Label* label1 = manage (new Label);
|
||||
|
||||
vbox1->set_spacing (6);
|
||||
|
||||
hbox1->set_spacing (6);
|
||||
hbox1->pack_start (*label1, false, false);
|
||||
hbox1->pack_start (new_name_entry, true, true);
|
||||
|
||||
label1->set_text (_("Session name:"));
|
||||
|
||||
hbox1->show();
|
||||
label1->show();
|
||||
new_name_entry.show ();
|
||||
|
||||
if (!ARDOUR_COMMAND_LINE::session_name.empty()) {
|
||||
new_name_entry.set_text (Glib::path_get_basename (ARDOUR_COMMAND_LINE::session_name));
|
||||
|
@ -509,7 +509,7 @@ ArdourStartup::setup_new_session_page ()
|
|||
new_name_entry.signal_changed().connect (mem_fun (*this, &ArdourStartup::new_name_changed));
|
||||
new_name_entry.signal_activate().connect (mem_fun (*this, &ArdourStartup::move_along_now));
|
||||
|
||||
session_new_vbox.pack_start (*hbox1, false, false);
|
||||
vbox1->pack_start (*hbox1, true, true);
|
||||
|
||||
/* --- */
|
||||
|
||||
|
@ -528,30 +528,42 @@ ArdourStartup::setup_new_session_page ()
|
|||
new_folder_chooser.set_current_folder (poor_mans_glob (Config->get_default_session_parent_dir()));
|
||||
}
|
||||
new_folder_chooser.set_title (_("Select folder for session"));
|
||||
|
||||
hbox2->show();
|
||||
label2->show();
|
||||
new_folder_chooser.show ();
|
||||
|
||||
session_new_vbox.pack_start (*hbox2, false, false);
|
||||
vbox1->pack_start (*hbox2, false, false);
|
||||
|
||||
session_new_vbox.pack_start (*vbox1, false, false);
|
||||
|
||||
/* --- */
|
||||
|
||||
VBox *vbox2 = manage (new VBox);
|
||||
HBox* hbox3 = manage (new HBox);
|
||||
Label* label3 = manage (new Label);
|
||||
template_model = ListStore::create (session_template_columns);
|
||||
populate_session_templates ();
|
||||
|
||||
vbox2->set_spacing (6);
|
||||
|
||||
label3->set_markup (_("<b>Options</b>"));
|
||||
label3->set_alignment (0.0, 0.0);
|
||||
|
||||
vbox2->pack_start (*label3, false, true);
|
||||
|
||||
VBox *vbox3 = manage (new VBox);
|
||||
|
||||
vbox3->set_spacing (6);
|
||||
|
||||
if (!template_model->children().empty()) {
|
||||
|
||||
HBox* hbox3 = manage (new HBox);
|
||||
HBox* hbox4a = manage (new HBox);
|
||||
use_template_button.set_label (_("Use this template"));
|
||||
|
||||
TreeModel::Row row = *template_model->prepend ();
|
||||
row[session_template_columns.name] = (_("no template"));
|
||||
row[session_template_columns.path] = string();
|
||||
|
||||
hbox3->set_spacing (6);
|
||||
hbox3->pack_start (use_template_button, false, false);
|
||||
hbox3->pack_start (template_chooser, true, true);
|
||||
hbox4a->set_spacing (6);
|
||||
hbox4a->pack_start (use_template_button, false, false);
|
||||
hbox4a->pack_start (template_chooser, true, true);
|
||||
|
||||
template_chooser.set_model (template_model);
|
||||
|
||||
|
@ -562,11 +574,10 @@ ArdourStartup::setup_new_session_page ()
|
|||
template_chooser.add_attribute (text_renderer->property_text(), session_template_columns.name);
|
||||
template_chooser.set_active (0);
|
||||
|
||||
hbox3->show ();
|
||||
use_template_button.show();
|
||||
template_chooser.show ();
|
||||
|
||||
session_new_vbox.pack_start (*hbox3, false, false);
|
||||
vbox3->pack_start (*hbox4a, false, false);
|
||||
}
|
||||
|
||||
/* --- */
|
||||
|
@ -574,14 +585,13 @@ ArdourStartup::setup_new_session_page ()
|
|||
if (!new_user) {
|
||||
session_template_chooser.set_current_folder (poor_mans_glob (Config->get_default_session_parent_dir()));
|
||||
|
||||
HBox* hbox3a = manage (new HBox);
|
||||
HBox* hbox4b = manage (new HBox);
|
||||
use_session_as_template_button.set_label (_("Use an existing session as a template:"));
|
||||
|
||||
hbox3a->set_spacing (6);
|
||||
hbox3a->pack_start (use_session_as_template_button, false, false);
|
||||
hbox3a->pack_start (session_template_chooser, true, true);
|
||||
hbox4b->set_spacing (6);
|
||||
hbox4b->pack_start (use_session_as_template_button, false, false);
|
||||
hbox4b->pack_start (session_template_chooser, true, true);
|
||||
|
||||
hbox3a->show ();
|
||||
use_session_as_template_button.show ();
|
||||
session_template_chooser.show ();
|
||||
|
||||
|
@ -590,26 +600,30 @@ ArdourStartup::setup_new_session_page ()
|
|||
session_template_chooser.set_filter (*template_filter);
|
||||
session_template_chooser.set_title (_("Select template"));
|
||||
|
||||
session_new_vbox.pack_start (*hbox3a, false, false);
|
||||
vbox3->pack_start (*hbox4b, false, false);
|
||||
}
|
||||
|
||||
|
||||
/* --- */
|
||||
|
||||
HBox* hbox4 = manage (new HBox);
|
||||
HBox* hbox5 = manage (new HBox);
|
||||
|
||||
hbox4->set_spacing (6);
|
||||
hbox4->pack_start (more_new_session_options_button, false, false);
|
||||
hbox5->set_spacing (6);
|
||||
hbox5->pack_start (more_new_session_options_button, false, false);
|
||||
|
||||
hbox4->show ();
|
||||
more_new_session_options_button.show ();
|
||||
more_new_session_options_button.signal_clicked().connect (mem_fun (*this, &ArdourStartup::more_new_session_options_button_clicked));
|
||||
|
||||
session_new_vbox.pack_start (*hbox4, false, false);
|
||||
vbox3->pack_start (*hbox5, false, false);
|
||||
hbox3->pack_start (*vbox3, true, true, 8);
|
||||
vbox2->pack_start (*hbox3, false, false);
|
||||
|
||||
/* --- */
|
||||
|
||||
session_new_vbox.pack_start (*vbox2, false, false);
|
||||
}
|
||||
|
||||
session_new_vbox.show ();
|
||||
session_hbox.pack_start (session_new_vbox, false, false);
|
||||
session_new_vbox.show_all ();
|
||||
session_hbox.pack_start (session_new_vbox, true, true);
|
||||
set_page_title (session_vbox, _("New Session"));
|
||||
set_page_type (session_vbox, ASSISTANT_PAGE_CONFIRM);
|
||||
|
||||
|
@ -736,6 +750,7 @@ ArdourStartup::setup_existing_session_page ()
|
|||
|
||||
recent_scroller.add (recent_session_display);
|
||||
recent_scroller.set_policy (Gtk::POLICY_NEVER, Gtk::POLICY_AUTOMATIC);
|
||||
recent_scroller.set_shadow_type (Gtk::SHADOW_IN);
|
||||
|
||||
recent_session_display.show();
|
||||
}
|
||||
|
@ -765,7 +780,7 @@ ArdourStartup::more_new_session_options_button_clicked ()
|
|||
void
|
||||
ArdourStartup::setup_more_options_page ()
|
||||
{
|
||||
more_options_vbox.set_border_width (12);
|
||||
more_options_vbox.set_border_width (24);
|
||||
|
||||
_output_limit_count.set_adjustment (_output_limit_count_adj);
|
||||
_input_limit_count.set_adjustment (_input_limit_count_adj);
|
||||
|
|
|
@ -52,6 +52,10 @@ public:
|
|||
|
||||
static void set_search_path (DataType type, const Glib::ustring& path);
|
||||
|
||||
static bool find (DataType type, const Glib::ustring& path,
|
||||
bool must_exist, bool& is_new, uint16_t& chan,
|
||||
Glib::ustring& found_path);
|
||||
|
||||
protected:
|
||||
FileSource (Session& session, DataType type,
|
||||
const Glib::ustring& path, bool embedded,
|
||||
|
@ -63,9 +67,6 @@ protected:
|
|||
|
||||
virtual int move_dependents_to_trash() { return 0; }
|
||||
|
||||
bool find (DataType type, const Glib::ustring& path,
|
||||
bool must_exist, bool& is_new, uint16_t& chan);
|
||||
|
||||
bool removable () const;
|
||||
|
||||
Glib::ustring _path;
|
||||
|
|
|
@ -34,6 +34,8 @@ class InternalReturn : public Return
|
|||
InternalReturn (Session&);
|
||||
InternalReturn (Session&, const XMLNode&);
|
||||
|
||||
bool visible() const { return false; }
|
||||
|
||||
XMLNode& state(bool full);
|
||||
XMLNode& get_state(void);
|
||||
int set_state(const XMLNode& node);
|
||||
|
@ -50,7 +52,7 @@ class InternalReturn : public Return
|
|||
|
||||
private:
|
||||
BufferSet buffers;
|
||||
uint32_t user_count;
|
||||
gint user_count; /* atomic */
|
||||
void allocate_buffers (nframes_t);
|
||||
void cycle_start (nframes_t);
|
||||
};
|
||||
|
|
|
@ -32,6 +32,8 @@ class InternalSend : public Send
|
|||
InternalSend (Session&, boost::shared_ptr<MuteMaster>, const XMLNode&);
|
||||
virtual ~InternalSend ();
|
||||
|
||||
bool set_name (const std::string&);
|
||||
|
||||
XMLNode& state(bool full);
|
||||
XMLNode& get_state(void);
|
||||
int set_state(const XMLNode& node);
|
||||
|
|
|
@ -191,6 +191,7 @@ class Route : public SessionObject, public AutomatableControls
|
|||
boost::shared_ptr<Delivery> main_outs() const { return _main_outs; }
|
||||
boost::shared_ptr<InternalReturn> internal_return() const { return _intreturn; }
|
||||
boost::shared_ptr<Send> internal_send_for (boost::shared_ptr<const Route> target) const;
|
||||
void add_internal_return ();
|
||||
BufferSet* get_return_buffer () const;
|
||||
void release_return_buffer () const;
|
||||
void put_control_outs_at (Placement);
|
||||
|
|
|
@ -121,6 +121,9 @@ public:
|
|||
routes.clear ();
|
||||
changed();
|
||||
}
|
||||
|
||||
void make_subgroup ();
|
||||
void destroy_subgroup ();
|
||||
|
||||
const std::list<Route*>& route_list() { return routes; }
|
||||
|
||||
|
@ -134,6 +137,7 @@ public:
|
|||
private:
|
||||
Session& _session;
|
||||
std::list<Route *> routes;
|
||||
boost::shared_ptr<Route> subgroup_bus;
|
||||
std::string _name;
|
||||
Flag _flags;
|
||||
Property _properties;
|
||||
|
|
|
@ -738,6 +738,9 @@ class Session : public PBD::StatefulDestructible, public boost::noncopyable
|
|||
boost::shared_ptr<Route> control_out() const { return _control_out; }
|
||||
boost::shared_ptr<Route> master_out() const { return _master_out; }
|
||||
|
||||
void globally_add_internal_sends (boost::shared_ptr<Route> dest);
|
||||
void add_internal_sends (boost::shared_ptr<Route> dest, boost::shared_ptr<RouteList> senders);
|
||||
|
||||
static void set_disable_all_loaded_plugins (bool yn) {
|
||||
_disable_all_loaded_plugins = yn;
|
||||
}
|
||||
|
|
|
@ -50,18 +50,21 @@ Delivery::Delivery (Session& s, boost::shared_ptr<IO> io, boost::shared_ptr<Mute
|
|||
: IOProcessor(s, boost::shared_ptr<IO>(), (r == Listen ? boost::shared_ptr<IO>() : io), name)
|
||||
, _role (r)
|
||||
, _output_buffers (new BufferSet())
|
||||
, _current_gain (1.0)
|
||||
, _output_offset (0)
|
||||
, _no_outs_cuz_we_no_monitor (false)
|
||||
, _solo_level (0)
|
||||
, _solo_isolated (false)
|
||||
, _mute_master (mm)
|
||||
|
||||
{
|
||||
_output_offset = 0;
|
||||
_current_gain = 1.0;
|
||||
_panner = boost::shared_ptr<Panner>(new Panner (_name, _session));
|
||||
|
||||
if (_output) {
|
||||
_output->changed.connect (mem_fun (*this, &Delivery::output_changed));
|
||||
}
|
||||
|
||||
CycleStart.connect (mem_fun (*this, &Delivery::cycle_start));
|
||||
}
|
||||
|
||||
/* deliver to a new IO object */
|
||||
|
@ -70,17 +73,20 @@ Delivery::Delivery (Session& s, boost::shared_ptr<MuteMaster> mm, const string&
|
|||
: IOProcessor(s, false, (r == Listen ? false : true), name)
|
||||
, _role (r)
|
||||
, _output_buffers (new BufferSet())
|
||||
, _current_gain (1.0)
|
||||
, _output_offset (0)
|
||||
, _no_outs_cuz_we_no_monitor (false)
|
||||
, _solo_level (0)
|
||||
, _solo_isolated (false)
|
||||
, _mute_master (mm)
|
||||
{
|
||||
_output_offset = 0;
|
||||
_current_gain = 1.0;
|
||||
_panner = boost::shared_ptr<Panner>(new Panner (_name, _session));
|
||||
|
||||
if (_output) {
|
||||
_output->changed.connect (mem_fun (*this, &Delivery::output_changed));
|
||||
}
|
||||
|
||||
CycleStart.connect (mem_fun (*this, &Delivery::cycle_start));
|
||||
}
|
||||
|
||||
/* deliver to a new IO object, reconstruct from XML */
|
||||
|
@ -89,12 +95,13 @@ Delivery::Delivery (Session& s, boost::shared_ptr<MuteMaster> mm, const XMLNode&
|
|||
: IOProcessor (s, false, true, "reset")
|
||||
, _role (Role (0))
|
||||
, _output_buffers (new BufferSet())
|
||||
, _current_gain (1.0)
|
||||
, _output_offset (0)
|
||||
, _no_outs_cuz_we_no_monitor (false)
|
||||
, _solo_level (0)
|
||||
, _solo_isolated (false)
|
||||
, _mute_master (mm)
|
||||
{
|
||||
_output_offset = 0;
|
||||
_current_gain = 1.0;
|
||||
_panner = boost::shared_ptr<Panner>(new Panner (_name, _session));
|
||||
|
||||
if (set_state (node)) {
|
||||
|
@ -104,6 +111,8 @@ Delivery::Delivery (Session& s, boost::shared_ptr<MuteMaster> mm, const XMLNode&
|
|||
if (_output) {
|
||||
_output->changed.connect (mem_fun (*this, &Delivery::output_changed));
|
||||
}
|
||||
|
||||
CycleStart.connect (mem_fun (*this, &Delivery::cycle_start));
|
||||
}
|
||||
|
||||
/* deliver to an existing IO object, reconstruct from XML */
|
||||
|
@ -112,12 +121,13 @@ Delivery::Delivery (Session& s, boost::shared_ptr<IO> out, boost::shared_ptr<Mut
|
|||
: IOProcessor (s, boost::shared_ptr<IO>(), out, "reset")
|
||||
, _role (Role (0))
|
||||
, _output_buffers (new BufferSet())
|
||||
, _current_gain (1.0)
|
||||
, _output_offset (0)
|
||||
, _no_outs_cuz_we_no_monitor (false)
|
||||
, _solo_level (0)
|
||||
, _solo_isolated (false)
|
||||
, _mute_master (mm)
|
||||
{
|
||||
_output_offset = 0;
|
||||
_current_gain = 1.0;
|
||||
_panner = boost::shared_ptr<Panner>(new Panner (_name, _session));
|
||||
|
||||
if (set_state (node)) {
|
||||
|
@ -127,6 +137,8 @@ Delivery::Delivery (Session& s, boost::shared_ptr<IO> out, boost::shared_ptr<Mut
|
|||
if (_output) {
|
||||
_output->changed.connect (mem_fun (*this, &Delivery::output_changed));
|
||||
}
|
||||
|
||||
CycleStart.connect (mem_fun (*this, &Delivery::cycle_start));
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -395,6 +407,7 @@ Delivery::target_gain ()
|
|||
*/
|
||||
|
||||
if (_no_outs_cuz_we_no_monitor) {
|
||||
std::cerr << this << " no outs cuz we no monitor\n";
|
||||
return 0.0;
|
||||
}
|
||||
|
||||
|
|
|
@ -86,10 +86,16 @@ FileSource::init (const ustring& pathstr, bool must_exist)
|
|||
{
|
||||
_timeline_position = 0;
|
||||
|
||||
if (!find (_type, pathstr, must_exist, _file_is_new, _channel)) {
|
||||
if (!find (_type, pathstr, must_exist, _file_is_new, _channel, _path)) {
|
||||
throw MissingSource ();
|
||||
}
|
||||
|
||||
/* XXX is this necessary? or even wise? */
|
||||
|
||||
if (_is_embedded) {
|
||||
_name = Glib::path_get_basename (_name);
|
||||
}
|
||||
|
||||
if (_file_is_new && must_exist) {
|
||||
return -1;
|
||||
}
|
||||
|
@ -188,15 +194,16 @@ FileSource::move_to_trash (const ustring& trash_dir_name)
|
|||
return 0;
|
||||
}
|
||||
|
||||
/** Find the actual source file based on \a path.
|
||||
/** Find the actual source file based on \a filename.
|
||||
*
|
||||
* If the source is embedded, \a path should be a filename (no slashes).
|
||||
* If the source is external, \a path should be a full path.
|
||||
* In either case, _path is set to the complete absolute path of the source file.
|
||||
* If the source is embedded, \a filename should be a simple filename (no slashes).
|
||||
* If the source is external, \a filename should be a full path.
|
||||
* In either case, found_path is set to the complete absolute path of the source file.
|
||||
* \return true iff the file was found.
|
||||
*/
|
||||
bool
|
||||
FileSource::find (DataType type, const ustring& path, bool must_exist, bool& isnew, uint16_t& chan)
|
||||
FileSource::find (DataType type, const ustring& path, bool must_exist,
|
||||
bool& isnew, uint16_t& chan, ustring& found_path)
|
||||
{
|
||||
Glib::ustring search_path = search_paths[type];
|
||||
|
||||
|
@ -314,7 +321,7 @@ FileSource::find (DataType type, const ustring& path, bool must_exist, bool& isn
|
|||
}
|
||||
}
|
||||
|
||||
_path = keeppath;
|
||||
found_path = keeppath;
|
||||
|
||||
ret = true;
|
||||
|
||||
|
@ -334,7 +341,7 @@ FileSource::find (DataType type, const ustring& path, bool must_exist, bool& isn
|
|||
}
|
||||
}
|
||||
|
||||
_path = pathstr;
|
||||
found_path = pathstr;
|
||||
|
||||
if (!Glib::file_test (pathstr, Glib::FILE_TEST_EXISTS|Glib::FILE_TEST_IS_REGULAR)) {
|
||||
|
||||
|
@ -343,14 +350,14 @@ FileSource::find (DataType type, const ustring& path, bool must_exist, bool& isn
|
|||
if (must_exist) {
|
||||
error << string_compose(
|
||||
_("Filesource: cannot find required file (%1): %2"),
|
||||
_path, strerror (errno)) << endmsg;
|
||||
path, strerror (errno)) << endmsg;
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (errno != ENOENT) {
|
||||
error << string_compose(
|
||||
_("Filesource: cannot check for existing file (%1): %2"),
|
||||
_path, strerror (errno)) << endmsg;
|
||||
path, strerror (errno)) << endmsg;
|
||||
goto out;
|
||||
}
|
||||
|
||||
|
@ -365,10 +372,6 @@ FileSource::find (DataType type, const ustring& path, bool must_exist, bool& isn
|
|||
}
|
||||
}
|
||||
|
||||
if (_is_embedded) {
|
||||
_name = Glib::path_get_basename (_name);
|
||||
}
|
||||
|
||||
out:
|
||||
return ret;
|
||||
}
|
||||
|
|
|
@ -46,13 +46,13 @@ InternalReturn::InternalReturn (Session& s, const XMLNode& node)
|
|||
void
|
||||
InternalReturn::run (BufferSet& bufs, sframes_t start_frame, sframes_t end_frame, nframes_t nframes)
|
||||
{
|
||||
if (user_count == 0) {
|
||||
/* XXX no lock here, just atomic fetch */
|
||||
|
||||
if (g_atomic_int_get(&user_count) == 0) {
|
||||
/* nothing to do - nobody is feeding us anything */
|
||||
return;
|
||||
}
|
||||
|
||||
/* XXX this should be merge() */
|
||||
|
||||
bufs.merge_from (buffers, nframes);
|
||||
}
|
||||
|
||||
|
@ -81,7 +81,10 @@ BufferSet*
|
|||
InternalReturn::get_buffers ()
|
||||
{
|
||||
Glib::Mutex::Lock lm (_session.engine().process_lock());
|
||||
user_count++;
|
||||
/* use of g_atomic here is just for code consistency - its protected by the lock
|
||||
for writing.
|
||||
*/
|
||||
g_atomic_int_inc (&user_count);
|
||||
return &buffers;
|
||||
}
|
||||
|
||||
|
@ -90,7 +93,10 @@ InternalReturn::release_buffers ()
|
|||
{
|
||||
Glib::Mutex::Lock lm (_session.engine().process_lock());
|
||||
if (user_count) {
|
||||
user_count--;
|
||||
/* use of g_atomic here is just for code consistency - its protected by the lock
|
||||
for writing.
|
||||
*/
|
||||
(void) g_atomic_int_dec_and_test (&user_count);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -41,6 +41,8 @@ InternalSend::InternalSend (Session& s, boost::shared_ptr<MuteMaster> mm, boost:
|
|||
throw failed_constructor();
|
||||
}
|
||||
|
||||
set_name (sendto->name());
|
||||
|
||||
_send_to->GoingAway.connect (mem_fun (*this, &InternalSend::send_to_going_away));
|
||||
}
|
||||
|
||||
|
@ -100,7 +102,6 @@ InternalSend::run (BufferSet& bufs, sframes_t start_frame, sframes_t end_frame,
|
|||
|
||||
_meter->reset ();
|
||||
Amp::apply_simple_gain (sendbufs, nframes, 0.0);
|
||||
|
||||
return;
|
||||
|
||||
} else if (tgain != 1.0) {
|
||||
|
@ -108,6 +109,7 @@ InternalSend::run (BufferSet& bufs, sframes_t start_frame, sframes_t end_frame,
|
|||
/* target gain has not changed, but is not unity */
|
||||
Amp::apply_simple_gain (sendbufs, nframes, tgain);
|
||||
}
|
||||
|
||||
|
||||
// Can't automate gain for sends or returns yet because we need different buffers
|
||||
// so that we don't overwrite the main automation data for the route amp
|
||||
|
@ -213,3 +215,10 @@ InternalSend::can_support_io_configuration (const ChanCount& in, ChanCount& out)
|
|||
out = in;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
InternalSend::set_name (const std::string& str)
|
||||
{
|
||||
/* rules for external sends don't apply to us */
|
||||
return IOProcessor::set_name (str);
|
||||
}
|
||||
|
|
|
@ -899,19 +899,12 @@ IO::parse_gain_string (const string& str, vector<string>& ports)
|
|||
bool
|
||||
IO::set_name (const string& requested_name)
|
||||
{
|
||||
if (requested_name == _name) {
|
||||
string name = requested_name;
|
||||
|
||||
if (name == _name) {
|
||||
return true;
|
||||
}
|
||||
|
||||
string name;
|
||||
Route *rt;
|
||||
if ( (rt = dynamic_cast<Route *>(this))) {
|
||||
name = Route::ensure_track_or_route_name(requested_name, _session);
|
||||
} else {
|
||||
name = requested_name;
|
||||
}
|
||||
|
||||
|
||||
/* replace all colons in the name. i wish we didn't have to do this */
|
||||
|
||||
if (replace_all (name, ":", "-")) {
|
||||
|
@ -924,7 +917,7 @@ IO::set_name (const string& requested_name)
|
|||
i->set_name (current_name);
|
||||
}
|
||||
|
||||
bool const r = SessionObject::set_name(name);
|
||||
bool const r = SessionObject::set_name (name);
|
||||
|
||||
setup_bundles ();
|
||||
|
||||
|
|
|
@ -238,7 +238,7 @@ Port::reconnect ()
|
|||
return 0;
|
||||
}
|
||||
|
||||
/** @param n Short or long name */
|
||||
/** @param n Short port name (no JACK client name) */
|
||||
int
|
||||
Port::set_name (std::string const & n)
|
||||
{
|
||||
|
@ -246,12 +246,10 @@ Port::set_name (std::string const & n)
|
|||
return 0;
|
||||
}
|
||||
|
||||
string const s = _engine->make_port_name_non_relative (n);
|
||||
|
||||
int const r = jack_port_set_name (_jack_port, s.c_str());
|
||||
int const r = jack_port_set_name (_jack_port, n.c_str());
|
||||
|
||||
if (r == 0) {
|
||||
_name = n; // short form, probably
|
||||
_name = n;
|
||||
}
|
||||
|
||||
return r;
|
||||
|
|
|
@ -710,12 +710,6 @@ Route::add_processor (boost::shared_ptr<Processor> processor, ProcessorList::ite
|
|||
|
||||
}
|
||||
|
||||
if (_meter) {
|
||||
// Ensure peak vector sizes before the plugin is activated
|
||||
ChanCount potential_max_streams = ChanCount::max (processor->input_streams(), processor->output_streams());
|
||||
_meter->configure_io (potential_max_streams, potential_max_streams);
|
||||
}
|
||||
|
||||
// XXX: do we want to emit the signal here ? change call order.
|
||||
processor->activate ();
|
||||
processor->ActiveChanged.connect (bind (mem_fun (_session, &Session::update_latency_compensation), false, false));
|
||||
|
@ -947,9 +941,6 @@ Route::add_processors (const ProcessorList& others, ProcessorList::iterator iter
|
|||
potential_max_streams = m;
|
||||
}
|
||||
|
||||
// Ensure peak vector sizes before the plugin is activated
|
||||
_meter->configure_io (potential_max_streams, potential_max_streams);
|
||||
|
||||
_processors.insert (iter, *i);
|
||||
|
||||
if (configure_processors_unlocked (err)) {
|
||||
|
@ -1853,6 +1844,15 @@ Route::silence (nframes_t nframes)
|
|||
}
|
||||
}
|
||||
|
||||
void
|
||||
Route::add_internal_return ()
|
||||
{
|
||||
if (!_intreturn) {
|
||||
_intreturn.reset (new InternalReturn (_session));
|
||||
add_processor (_intreturn, PreFader);
|
||||
}
|
||||
}
|
||||
|
||||
BufferSet*
|
||||
Route::get_return_buffer () const
|
||||
{
|
||||
|
@ -1906,7 +1906,7 @@ Route::listen_via (boost::shared_ptr<Route> route, const string& listen_name)
|
|||
}
|
||||
|
||||
/* already listening via the specified IO: do nothing */
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
@ -1918,7 +1918,6 @@ Route::listen_via (boost::shared_ptr<Route> route, const string& listen_name)
|
|||
listener.reset (new InternalSend (_session, _mute_master, route));
|
||||
|
||||
} catch (failed_constructor& err) {
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
@ -2478,10 +2477,12 @@ Route::set_name (const string& str)
|
|||
{
|
||||
bool ret;
|
||||
string ioproc_name;
|
||||
string name;
|
||||
|
||||
name = Route::ensure_track_or_route_name (str, _session);
|
||||
SessionObject::set_name (name);
|
||||
|
||||
SessionObject::set_name (str);
|
||||
|
||||
ret = (_input->set_name(str) && _output->set_name(str));
|
||||
ret = (_input->set_name(name) && _output->set_name(name));
|
||||
|
||||
if (ret) {
|
||||
|
||||
|
@ -2494,7 +2495,7 @@ Route::set_name (const string& str)
|
|||
boost::shared_ptr<IOProcessor> iop = boost::dynamic_pointer_cast<IOProcessor> (*i);
|
||||
|
||||
if (iop) {
|
||||
string iop_name = str;
|
||||
string iop_name = name;
|
||||
iop_name += '[';
|
||||
iop_name += "XXX FIX ME XXX";
|
||||
iop_name += ']';
|
||||
|
|
|
@ -218,3 +218,46 @@ RouteGroup::audio_track_group (set<AudioTrack*>& ats)
|
|||
}
|
||||
}
|
||||
|
||||
void
|
||||
RouteGroup::make_subgroup ()
|
||||
{
|
||||
RouteList rl;
|
||||
uint32_t nin = 0;
|
||||
|
||||
for (list<Route*>::iterator i = routes.begin(); i != routes.end(); ++i) {
|
||||
nin = max (nin, (*i)->output()->n_ports().n_audio());
|
||||
}
|
||||
|
||||
try {
|
||||
/* use master bus etc. to determine default nouts */
|
||||
rl = _session.new_audio_route (nin, 2, 0, 1);
|
||||
} catch (...) {
|
||||
return;
|
||||
}
|
||||
|
||||
subgroup_bus = rl.front();
|
||||
subgroup_bus->set_name (_name);
|
||||
|
||||
boost::shared_ptr<Bundle> bundle = subgroup_bus->input()->bundle ();
|
||||
|
||||
for (list<Route*>::iterator i = routes.begin(); i != routes.end(); ++i) {
|
||||
(*i)->output()->disconnect (this);
|
||||
(*i)->output()->connect_ports_to_bundle (bundle, this);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
RouteGroup::destroy_subgroup ()
|
||||
{
|
||||
if (!subgroup_bus) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (list<Route*>::iterator i = routes.begin(); i != routes.end(); ++i) {
|
||||
(*i)->output()->disconnect (this);
|
||||
/* XXX find a new bundle to connect to */
|
||||
}
|
||||
|
||||
_session.remove_route (subgroup_bus);
|
||||
subgroup_bus.reset ();
|
||||
}
|
||||
|
|
|
@ -192,12 +192,16 @@ Send::make_unique (XMLNode &state, Session &session)
|
|||
bool
|
||||
Send::set_name (const std::string& new_name)
|
||||
{
|
||||
char buf[32];
|
||||
std::string unique_name;
|
||||
|
||||
snprintf (buf, sizeof (buf), "%u", _bitslot);
|
||||
unique_name = new_name;
|
||||
unique_name += buf;
|
||||
if (_role != Listen) {
|
||||
char buf[32];
|
||||
snprintf (buf, sizeof (buf), "%u", _bitslot);
|
||||
unique_name = new_name;
|
||||
unique_name += buf;
|
||||
} else {
|
||||
unique_name = new_name;
|
||||
}
|
||||
|
||||
return Delivery::set_name (unique_name);
|
||||
}
|
||||
|
|
|
@ -760,11 +760,11 @@ Session::hookup_io ()
|
|||
|
||||
for (RouteList::iterator x = r->begin(); x != r->end(); ++x) {
|
||||
|
||||
boost::shared_ptr<Track> t = boost::dynamic_pointer_cast<Track> (*x);
|
||||
|
||||
if (t) {
|
||||
t->listen_via (_control_out, X_("listen"));
|
||||
if ((*x)->is_control() || (*x)->is_master()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
(*x)->listen_via (_control_out, X_("listen"));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2053,6 +2053,13 @@ Session::add_routes (RouteList& new_routes, bool save)
|
|||
shared_ptr<RouteList> r = writer.get_copy ();
|
||||
r->insert (r->end(), new_routes.begin(), new_routes.end());
|
||||
|
||||
|
||||
/* if there is no control out and we're not in the middle of loading,
|
||||
resort the graph here. if there is a control out, we will resort
|
||||
toward the end of this method. if we are in the middle of loading,
|
||||
we will resort when done.
|
||||
*/
|
||||
|
||||
if (!_control_out && IO::connecting_legal) {
|
||||
resort_routes_using (r);
|
||||
}
|
||||
|
@ -2080,6 +2087,9 @@ Session::add_routes (RouteList& new_routes, bool save)
|
|||
if (_control_out && IO::connecting_legal) {
|
||||
|
||||
for (RouteList::iterator x = new_routes.begin(); x != new_routes.end(); ++x) {
|
||||
if ((*x)->is_control() || (*x)->is_master()) {
|
||||
continue;
|
||||
}
|
||||
(*x)->listen_via (_control_out, "control");
|
||||
}
|
||||
|
||||
|
@ -2095,6 +2105,44 @@ Session::add_routes (RouteList& new_routes, bool save)
|
|||
RouteAdded (new_routes); /* EMIT SIGNAL */
|
||||
}
|
||||
|
||||
void
|
||||
Session::globally_add_internal_sends (boost::shared_ptr<Route> dest)
|
||||
{
|
||||
boost::shared_ptr<RouteList> r = routes.reader ();
|
||||
boost::shared_ptr<RouteList> t (new RouteList);
|
||||
|
||||
/* only send tracks */
|
||||
|
||||
for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
|
||||
if (boost::dynamic_pointer_cast<Track>(*i)) {
|
||||
t->push_back (*i);
|
||||
}
|
||||
}
|
||||
|
||||
add_internal_sends (dest, t);
|
||||
}
|
||||
|
||||
void
|
||||
Session::add_internal_sends (boost::shared_ptr<Route> dest, boost::shared_ptr<RouteList> senders)
|
||||
{
|
||||
if (dest->is_control() || dest->is_master()) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!dest->internal_return()) {
|
||||
dest->add_internal_return();
|
||||
}
|
||||
|
||||
for (RouteList::iterator i = senders->begin(); i != senders->end(); ++i) {
|
||||
|
||||
if ((*i)->is_control() || (*i)->is_master() || (*i) == dest) {
|
||||
continue;
|
||||
}
|
||||
|
||||
(*i)->listen_via (dest, "aux");
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
Session::add_diskstream (boost::shared_ptr<Diskstream> dstream)
|
||||
{
|
||||
|
|
|
@ -2296,6 +2296,12 @@ Session::find_all_sources (string path, set<string>& result)
|
|||
|
||||
XMLProperty* prop;
|
||||
|
||||
if ((prop = (*niter)->property (X_("type"))) == 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
DataType type (prop->value());
|
||||
|
||||
if ((prop = (*niter)->property (X_("name"))) == 0) {
|
||||
continue;
|
||||
}
|
||||
|
@ -2304,12 +2310,14 @@ Session::find_all_sources (string path, set<string>& result)
|
|||
/* external file, ignore */
|
||||
continue;
|
||||
}
|
||||
|
||||
Glib::ustring found_path;
|
||||
bool is_new;
|
||||
uint16_t chan;
|
||||
|
||||
sys::path source_path = _session_dir->sound_path ();
|
||||
|
||||
source_path /= prop->value ();
|
||||
|
||||
result.insert (source_path.to_string ());
|
||||
if (FileSource::find (type, prop->value(), true, is_new, chan, found_path)) {
|
||||
result.insert (found_path);
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
|
Loading…
Reference in New Issue