summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gtk2_ardour/editor.h2
-rw-r--r--gtk2_ardour/editor_audio_import.cc7
-rw-r--r--gtk2_ardour/editor_edit_groups.cc13
-rw-r--r--gtk2_ardour/mixer_group_tabs.cc14
-rw-r--r--gtk2_ardour/mixer_group_tabs.h4
-rw-r--r--gtk2_ardour/route_ui.cc8
-rw-r--r--gtk2_ardour/route_ui.h1
-rw-r--r--gtk2_ardour/startup.cc151
-rw-r--r--libs/ardour/ardour/file_source.h7
-rw-r--r--libs/ardour/ardour/internal_return.h4
-rw-r--r--libs/ardour/ardour/internal_send.h2
-rw-r--r--libs/ardour/ardour/route.h1
-rw-r--r--libs/ardour/ardour/route_group.h4
-rw-r--r--libs/ardour/ardour/session.h3
-rw-r--r--libs/ardour/delivery.cc29
-rw-r--r--libs/ardour/file_source.cc31
-rw-r--r--libs/ardour/internal_return.cc16
-rw-r--r--libs/ardour/internal_send.cc11
-rw-r--r--libs/ardour/io.cc15
-rw-r--r--libs/ardour/port.cc8
-rw-r--r--libs/ardour/route.cc31
-rw-r--r--libs/ardour/route_group.cc43
-rw-r--r--libs/ardour/send.cc12
-rw-r--r--libs/ardour/session.cc56
-rw-r--r--libs/ardour/session_state.cc18
25 files changed, 345 insertions, 146 deletions
diff --git a/gtk2_ardour/editor.h b/gtk2_ardour/editor.h
index 10895dc5a6..a174a21ca4 100644
--- a/gtk2_ardour/editor.h
+++ b/gtk2_ardour/editor.h
@@ -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&);
diff --git a/gtk2_ardour/editor_audio_import.cc b/gtk2_ardour/editor_audio_import.cc
index 1c23fdf217..7762a42322 100644
--- a/gtk2_ardour/editor_audio_import.cc
+++ b/gtk2_ardour/editor_audio_import.cc
@@ -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)),
diff --git a/gtk2_ardour/editor_edit_groups.cc b/gtk2_ardour/editor_edit_groups.cc
index d0d450f120..54547b5a0d 100644
--- a/gtk2_ardour/editor_edit_groups.cc
+++ b/gtk2_ardour/editor_edit_groups.cc
@@ -66,6 +66,7 @@ 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)));
@@ -73,6 +74,18 @@ Editor::build_route_group_menu (RouteGroup* g)
}
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 ()
{
session->foreach_route_group (bind (mem_fun (*this, &Editor::set_route_group_activation), true));
diff --git a/gtk2_ardour/mixer_group_tabs.cc b/gtk2_ardour/mixer_group_tabs.cc
index a261fc8ec9..566671f027 100644
--- a/gtk2_ardour/mixer_group_tabs.cc
+++ b/gtk2_ardour/mixer_group_tabs.cc
@@ -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 ();
+}
diff --git a/gtk2_ardour/mixer_group_tabs.h b/gtk2_ardour/mixer_group_tabs.h
index 7caf981944..6f92c834e8 100644
--- a/gtk2_ardour/mixer_group_tabs.h
+++ b/gtk2_ardour/mixer_group_tabs.h
@@ -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;
};
diff --git a/gtk2_ardour/route_ui.cc b/gtk2_ardour/route_ui.cc
index ee7f1102b5..8877a5a823 100644
--- a/gtk2_ardour/route_ui.cc
+++ b/gtk2_ardour/route_ui.cc
@@ -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
diff --git a/gtk2_ardour/route_ui.h b/gtk2_ardour/route_ui.h
index 05eabab1f7..b44bf235b5 100644
--- a/gtk2_ardour/route_ui.h
+++ b/gtk2_ardour/route_ui.h
@@ -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 ();
diff --git a/gtk2_ardour/startup.cc b/gtk2_ardour/startup.cc
index 89bddf9869..bbfa173b41 100644
--- a/gtk2_ardour/startup.cc
+++ b/gtk2_ardour/startup.cc
@@ -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);
diff --git a/libs/ardour/ardour/file_source.h b/libs/ardour/ardour/file_source.h
index d5a4ce1d95..fdf7473c63 100644
--- a/libs/ardour/ardour/file_source.h
+++ b/libs/ardour/ardour/file_source.h
@@ -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;
diff --git a/libs/ardour/ardour/internal_return.h b/libs/ardour/ardour/internal_return.h
index 6aa8bfe7b4..a23b17adf8 100644
--- a/libs/ardour/ardour/internal_return.h
+++ b/libs/ardour/ardour/internal_return.h
@@ -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);
};
diff --git a/libs/ardour/ardour/internal_send.h b/libs/ardour/ardour/internal_send.h
index 0bbb75d685..3172176897 100644
--- a/libs/ardour/ardour/internal_send.h
+++ b/libs/ardour/ardour/internal_send.h
@@ -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);
diff --git a/libs/ardour/ardour/route.h b/libs/ardour/ardour/route.h
index dcdd306c5b..d346a22342 100644
--- a/libs/ardour/ardour/route.h
+++ b/libs/ardour/ardour/route.h
@@ -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);
diff --git a/libs/ardour/ardour/route_group.h b/libs/ardour/ardour/route_group.h
index f4ed001453..a038551244 100644
--- a/libs/ardour/ardour/route_group.h
+++ b/libs/ardour/ardour/route_group.h
@@ -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;
diff --git a/libs/ardour/ardour/session.h b/libs/ardour/ardour/session.h
index 1dd40affdb..39822de678 100644
--- a/libs/ardour/ardour/session.h
+++ b/libs/ardour/ardour/session.h
@@ -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;
}
diff --git a/libs/ardour/delivery.cc b/libs/ardour/delivery.cc
index 8a13a4b047..45e70eb4a2 100644
--- a/libs/ardour/delivery.cc
+++ b/libs/ardour/delivery.cc
@@ -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;
}
diff --git a/libs/ardour/file_source.cc b/libs/ardour/file_source.cc
index 0fbea94cc1..027701be09 100644
--- a/libs/ardour/file_source.cc
+++ b/libs/ardour/file_source.cc
@@ -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;
}
diff --git a/libs/ardour/internal_return.cc b/libs/ardour/internal_return.cc
index 409c87d93c..0a45228c67 100644
--- a/libs/ardour/internal_return.cc
+++ b/libs/ardour/internal_return.cc
@@ -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);
}
}
diff --git a/libs/ardour/internal_send.cc b/libs/ardour/internal_send.cc
index db0390e813..177df4222c 100644
--- a/libs/ardour/internal_send.cc
+++ b/libs/ardour/internal_send.cc
@@ -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);
+}
diff --git a/libs/ardour/io.cc b/libs/ardour/io.cc
index a1b1b592c5..2397999a26 100644
--- a/libs/ardour/io.cc
+++ b/libs/ardour/io.cc
@@ -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 ();
diff --git a/libs/ardour/port.cc b/libs/ardour/port.cc
index 247357d16b..19955d2530 100644
--- a/libs/ardour/port.cc
+++ b/libs/ardour/port.cc
@@ -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;
diff --git a/libs/ardour/route.cc b/libs/ardour/route.cc
index e55ad3e425..68f6107b45 100644
--- a/libs/ardour/route.cc
+++ b/libs/ardour/route.cc
@@ -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 += ']';
diff --git a/libs/ardour/route_group.cc b/libs/ardour/route_group.cc
index 3da55adeb7..826341092f 100644
--- a/libs/ardour/route_group.cc
+++ b/libs/ardour/route_group.cc
@@ -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 ();
+}
diff --git a/libs/ardour/send.cc b/libs/ardour/send.cc
index 307f83fa62..df6b87a686 100644
--- a/libs/ardour/send.cc
+++ b/libs/ardour/send.cc
@@ -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);
}
diff --git a/libs/ardour/session.cc b/libs/ardour/session.cc
index cfab50552d..24a40f4c31 100644
--- a/libs/ardour/session.cc
+++ b/libs/ardour/session.cc
@@ -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");
}
@@ -2096,6 +2106,44 @@ Session::add_routes (RouteList& new_routes, bool save)
}
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)
{
/* need to do this in case we're rolling at the time, to prevent false underruns */
diff --git a/libs/ardour/session_state.cc b/libs/ardour/session_state.cc
index 9b142a2ef9..32e31580af 100644
--- a/libs/ardour/session_state.cc
+++ b/libs/ardour/session_state.cc
@@ -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;