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:
Paul Davis 2009-06-25 20:46:39 +00:00
parent 94880f7cd1
commit 8e7a5d7741
25 changed files with 345 additions and 146 deletions

View File

@ -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&);

View File

@ -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)),

View File

@ -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 ()
{

View File

@ -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 ();
}

View File

@ -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;
};

View File

@ -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

View File

@ -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 ();

View File

@ -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);

View File

@ -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;

View File

@ -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);
};

View File

@ -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);

View File

@ -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);

View File

@ -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;

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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);
}
}

View File

@ -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);
}

View File

@ -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 ();

View File

@ -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;

View File

@ -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 += ']';

View File

@ -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 ();
}

View File

@ -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);
}

View File

@ -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)
{

View File

@ -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;