Insert/Redirect refactoring, towards better MIDI support in mixer strip, and

http://ardour.org/node/1043 style things.


git-svn-id: svn://localhost/ardour2/trunk@2027 d708f5d6-7413-0410-9779-e7cbd77b26cf
This commit is contained in:
David Robillard 2007-06-23 20:13:13 +00:00
parent 05184ed52f
commit 49ee64ada7
77 changed files with 2052 additions and 1948 deletions

View file

@ -106,8 +106,8 @@ AudioTimeAxisView::AudioTimeAxisView (PublicEditor& ed, Session& sess, boost::sh
/* map current state of the route */
redirects_changed (0);
reset_redirect_automation_curves ();
inserts_changed ();
reset_insert_automation_curves ();
ensure_xml_node ();

View file

@ -250,7 +250,7 @@ IOSelector::IOSelector (Session& sess, boost::shared_ptr<IO> ior, bool input)
io->output_changed.connect (mem_fun(*this, &IOSelector::ports_changed));
}
io->name_changed.connect (mem_fun(*this, &IOSelector::name_changed));
io->NameChanged.connect (mem_fun(*this, &IOSelector::name_changed));
}
IOSelector::~IOSelector ()
@ -298,9 +298,9 @@ IOSelector::set_button_sensitivity ()
void
IOSelector::name_changed (void* src)
IOSelector::name_changed ()
{
ENSURE_GUI_THREAD(bind (mem_fun(*this, &IOSelector::name_changed), src));
ENSURE_GUI_THREAD(mem_fun(*this, &IOSelector::name_changed));
display_ports ();
}
@ -765,8 +765,8 @@ IOSelector::redisplay ()
}
PortInsertUI::PortInsertUI (Session& sess, boost::shared_ptr<PortInsert> pi)
: input_selector (sess, pi, true),
output_selector (sess, pi, false)
: input_selector (sess, pi->io(), true),
output_selector (sess, pi->io(), false)
{
hbox.pack_start (output_selector, true, true);
hbox.pack_start (input_selector, true, true);

View file

@ -119,7 +119,7 @@ class IOSelector : public Gtk::VBox {
bool port_selection_changed(GdkEventButton *, Gtk::TreeView*);
void ports_changed (ARDOUR::IOChange, void *);
void name_changed (void*);
void name_changed ();
void add_port ();
void remove_port ();

View file

@ -103,7 +103,8 @@ LadspaPluginUI::LadspaPluginUI (boost::shared_ptr<PluginInsert> pi, bool scrolla
pack_start (hpacker, false, false);
}
insert->active_changed.connect (mem_fun(*this, &LadspaPluginUI::redirect_active_changed));
insert->ActiveChanged.connect (bind(mem_fun(*this, &LadspaPluginUI::insert_active_changed),
boost::weak_ptr<Insert>(insert)));
bypass_button.set_active (!insert->active());
build ();
@ -671,11 +672,13 @@ LadspaPluginUI::control_combo_changed (ControlUI* cui)
}
void
LadspaPluginUI::redirect_active_changed (Redirect* r, void* src)
LadspaPluginUI::insert_active_changed (boost::weak_ptr<Insert> weak_insert)
{
ENSURE_GUI_THREAD(bind (mem_fun(*this, &LadspaPluginUI::redirect_active_changed), r, src));
ENSURE_GUI_THREAD(bind (mem_fun(*this, &LadspaPluginUI::insert_active_changed), weak_insert));
bypass_button.set_active (!r->active());
boost::shared_ptr<Insert> insert = weak_insert.lock();
bypass_button.set_active (!insert || !insert->active());
}
bool

View file

@ -98,13 +98,13 @@ MidiTimeAxisView::MidiTimeAxisView (PublicEditor& ed, Session& sess, boost::shar
/* map current state of the route */
redirects_changed (0);
inserts_changed ();
ensure_xml_node ();
set_state (*xml_node);
_route->redirects_changed.connect (mem_fun(*this, &MidiTimeAxisView::redirects_changed));
_route->inserts_changed.connect (mem_fun(*this, &MidiTimeAxisView::inserts_changed));
if (is_track()) {
@ -174,25 +174,6 @@ MidiTimeAxisView::set_state (const XMLNode& node)
}
}
// FIXME: duplicated in audio_time_axis.cc
/*static string
legalize_for_xml_node (string str)
{
string::size_type pos;
string legal_chars = "abcdefghijklmnopqrtsuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_+=:";
string legal;
legal = str;
pos = 0;
while ((pos = legal.find_first_not_of (legal_chars, pos)) != string::npos) {
legal.replace (pos, 1, "_");
pos += 1;
}
return legal;
}*/
void
MidiTimeAxisView::route_active_changed ()
{

View file

@ -44,21 +44,13 @@ namespace ARDOUR {
class Session;
class MidiDiskstream;
class RouteGroup;
class Redirect;
class Insert;
class Insert;
class Location;
class MidiPlaylist;
}
class PublicEditor;
class Selection;
class Selectable;
class AutomationLine;
class AutomationGainLine;
class AutomationPanLine;
class RedirectAutomationLine;
class TimeSelection;
class AutomationTimeAxisView;
class MidiTimeAxisView : public RouteTimeAxisView
{
@ -76,9 +68,7 @@ class MidiTimeAxisView : public RouteTimeAxisView
private:
void route_active_changed ();
//void redirects_changed (void *); FIXME?
void add_redirect_to_subplugin_menu (ARDOUR::Redirect *);
void add_insert_to_subplugin_menu (ARDOUR::Insert *);
Gtk::Menu subplugin_menu;
};

View file

@ -303,7 +303,7 @@ MixerStrip::MixerStrip (Mixer_UI& mx, Session& sess, boost::shared_ptr<Route> rt
get_diskstream()->SpeedChanged.connect (mem_fun(*this, &MixerStrip::speed_changed));
}
_route->name_changed.connect (mem_fun(*this, &RouteUI::name_changed));
_route->NameChanged.connect (mem_fun(*this, &RouteUI::name_changed));
_route->comment_changed.connect (mem_fun(*this, &MixerStrip::comment_changed));
_route->gui_changed.connect (mem_fun(*this, &MixerStrip::route_gui_changed));
@ -336,7 +336,7 @@ MixerStrip::MixerStrip (Mixer_UI& mx, Session& sess, boost::shared_ptr<Route> rt
post_redirect_box.update();
mute_changed (0);
solo_changed (0);
name_changed (0);
name_changed ();
comment_changed (0);
mix_group_changed (0);
@ -469,7 +469,7 @@ MixerStrip::set_width (Width w, void* owner)
update_input_display ();
update_output_display ();
mix_group_changed (0);
name_changed (0);
name_changed ();
}
@ -1078,11 +1078,11 @@ MixerStrip::set_selected (bool yn)
}
void
MixerStrip::name_changed (void *src)
MixerStrip::name_changed ()
{
switch (_width) {
case Wide:
RouteUI::name_changed (src);
RouteUI::name_changed ();
break;
case Narrow:
name_label.set_text (PBD::short_version (_route->name(), 5));
@ -1149,13 +1149,13 @@ MixerStrip::map_frozen ()
break;
}
}
_route->foreach_redirect (this, &MixerStrip::hide_redirect_editor);
_route->foreach_insert (this, &MixerStrip::hide_insert_editor);
}
void
MixerStrip::hide_redirect_editor (boost::shared_ptr<Redirect> redirect)
MixerStrip::hide_insert_editor (boost::shared_ptr<Insert> insert)
{
void* gui = redirect->get_gui ();
void* gui = insert->get_gui ();
if (gui) {
static_cast<Gtk::Widget*>(gui)->hide ();

View file

@ -236,10 +236,10 @@ class MixerStrip : public RouteUI, public Gtk::EventBox
void speed_adjustment_changed ();
void speed_changed ();
void name_changed (void *src);
void name_changed ();
void update_speed_display ();
void map_frozen ();
void hide_redirect_editor (boost::shared_ptr<ARDOUR::Redirect> redirect);
void hide_insert_editor (boost::shared_ptr<ARDOUR::Insert> insert);
bool ignore_speed_adjustment;

View file

@ -292,7 +292,7 @@ Mixer_UI::add_strip (Session::RouteList& routes)
no_track_list_redisplay = false;
redisplay_track_list ();
route->name_changed.connect (bind (mem_fun(*this, &Mixer_UI::strip_name_changed), strip));
route->NameChanged.connect (bind (mem_fun(*this, &Mixer_UI::strip_name_changed), strip));
strip->GoingAway.connect (bind (mem_fun(*this, &Mixer_UI::remove_strip), strip));
strip->signal_button_release_event().connect (bind (mem_fun(*this, &Mixer_UI::strip_button_release_event), strip));
@ -738,9 +738,9 @@ Mixer_UI::build_track_menu ()
}
void
Mixer_UI::strip_name_changed (void* src, MixerStrip* mx)
Mixer_UI::strip_name_changed (MixerStrip* mx)
{
ENSURE_GUI_THREAD(bind (mem_fun(*this, &Mixer_UI::strip_name_changed), src, mx));
ENSURE_GUI_THREAD(bind (mem_fun(*this, &Mixer_UI::strip_name_changed), mx));
TreeModel::Children rows = track_model->children();
TreeModel::Children::iterator i;

View file

@ -178,7 +178,7 @@ class Mixer_UI : public Gtk::Window
PluginSelector *_plugin_selector;
void strip_name_changed (void *src, MixerStrip *);
void strip_name_changed (MixerStrip *);
void group_flags_changed (void *src, ARDOUR::RouteGroup *);

View file

@ -208,6 +208,6 @@ PlugUIBase::bypass_toggled ()
bool x;
if ((x = bypass_button.get_active()) == insert->active()) {
insert->set_active (!x, this);
insert->set_active (!x);
}
}

View file

@ -180,7 +180,7 @@ class LadspaPluginUI : public PlugUIBase, public Gtk::VBox
void control_port_toggled (ControlUI* cui);
void control_combo_changed (ControlUI* cui);
void redirect_active_changed (ARDOUR::Redirect*, void*);
void insert_active_changed (boost::weak_ptr<ARDOUR::Insert>);
void astate_clicked (ControlUI*, uint32_t parameter);
void automation_state_changed (ControlUI*);

View file

@ -33,7 +33,7 @@ using namespace std;
using namespace ARDOUR;
using namespace PBD;
RedirectAutomationLine::RedirectAutomationLine (const string & name, Redirect& rd, uint32_t port, Session& s,
RedirectAutomationLine::RedirectAutomationLine (const string & name, Insert& i, uint32_t port, Session& s,
TimeAxisView& tv, ArdourCanvas::Group& parent,
@ -41,16 +41,16 @@ RedirectAutomationLine::RedirectAutomationLine (const string & name, Redirect& r
: AutomationLine (name, tv, parent, l),
session (s),
_redirect (rd),
_insert (i),
_port (port)
{
set_verbose_cursor_uses_gain_mapping (false);
set_verbose_cursor_uses_gain_mapping (false);
PluginInsert *pi;
Plugin::ParameterDescriptor desc;
if ((pi = dynamic_cast<PluginInsert*>(&_redirect)) == 0) {
fatal << _("redirect automation created for non-plugin") << endmsg;
if ((pi = dynamic_cast<PluginInsert*>(&_insert)) == 0) {
fatal << _("insert automation created for non-plugin") << endmsg;
/*NOTREACHED*/
}

View file

@ -26,7 +26,7 @@
namespace ARDOUR {
class Session;
class Redirect;
class Insert;
}
class TimeAxisView;
@ -34,17 +34,17 @@ class TimeAxisView;
class RedirectAutomationLine : public AutomationLine
{
public:
RedirectAutomationLine (const string & name, ARDOUR::Redirect&, uint32_t port, ARDOUR::Session&, TimeAxisView&,
RedirectAutomationLine (const string & name, ARDOUR::Insert&, uint32_t port, ARDOUR::Session&, TimeAxisView&,
ArdourCanvas::Group& parent, ARDOUR::AutomationList&);
uint32_t port() const { return _port; }
ARDOUR::Redirect& redirect() const { return _redirect; }
ARDOUR::Insert& insert() const { return _insert; }
string get_verbose_cursor_string (float);
private:
ARDOUR::Session& session;
ARDOUR::Redirect& _redirect;
ARDOUR::Insert& _insert;
uint32_t _port;
float upper;
float lower;

View file

@ -17,7 +17,7 @@
*/
#include <ardour/redirect.h>
#include <ardour/insert.h>
#include <ardour/session.h>
#include <cstdlib>
#include <pbd/memento_command.h>
@ -34,11 +34,11 @@ using namespace Gtk;
RedirectAutomationTimeAxisView::RedirectAutomationTimeAxisView (Session& s, boost::shared_ptr<Route> r,
PublicEditor& e, TimeAxisView& parent, Canvas& canvas, std::string n,
uint32_t prt, Redirect& rd, string state_name)
uint32_t prt, Insert& i, string state_name)
: AxisView (s),
AutomationTimeAxisView (s, r, e, parent, canvas, n, state_name, rd.name()),
redirect (rd),
AutomationTimeAxisView (s, r, e, parent, canvas, n, state_name, i.name()),
insert (i),
port (prt)
{
@ -91,9 +91,9 @@ RedirectAutomationTimeAxisView::add_automation_event (ArdourCanvas::Item* item,
/* map to model space */
if (!lines.empty()) {
AutomationList& alist (redirect.automation_list(port));
AutomationList& alist (insert.automation_list(port));
string description = _("add automation event to ");
description += redirect.describe_parameter (port);
description += insert.describe_parameter (port);
lines.front()->view_to_model_y (y);
@ -111,9 +111,9 @@ void
RedirectAutomationTimeAxisView::ensure_xml_node ()
{
if (xml_node == 0) {
if ((xml_node = redirect.extra_xml ("GUI")) == 0) {
if ((xml_node = insert.extra_xml ("GUI")) == 0) {
xml_node = new XMLNode ("GUI");
redirect.add_extra_xml (*xml_node);
insert.add_extra_xml (*xml_node);
}
}
}
@ -168,6 +168,6 @@ void
RedirectAutomationTimeAxisView::set_automation_state (AutoState state)
{
if (!ignore_state_request) {
redirect.automation_list (port).set_automation_state (state);
insert.automation_list (port).set_automation_state (state);
}
}

View file

@ -39,7 +39,7 @@ class RedirectAutomationTimeAxisView : public AutomationTimeAxisView
ArdourCanvas::Canvas& canvas,
std::string name,
uint32_t port,
ARDOUR::Redirect& rd,
ARDOUR::Insert& i,
std::string state_name);
~RedirectAutomationTimeAxisView();
@ -51,7 +51,7 @@ class RedirectAutomationTimeAxisView : public AutomationTimeAxisView
private:
ARDOUR::Redirect& redirect;
ARDOUR::Insert& insert;
uint32_t port;
XMLNode *xml_node;

File diff suppressed because it is too large Load diff

View file

@ -62,6 +62,8 @@ namespace ARDOUR {
class Session;
}
// FIXME: change name to InsertBox
class RedirectBox : public Gtk::HBox
{
public:
@ -73,14 +75,13 @@ class RedirectBox : public Gtk::HBox
void update();
void select_all_redirects ();
void deselect_all_redirects ();
void select_all_plugins ();
void select_all_inserts ();
void deselect_all_inserts ();
void select_all_plugins ();
void select_all_sends ();
sigc::signal<void,boost::shared_ptr<ARDOUR::Redirect> > RedirectSelected;
sigc::signal<void,boost::shared_ptr<ARDOUR::Redirect> > RedirectUnselected;
sigc::signal<void,boost::shared_ptr<ARDOUR::Insert> > InsertSelected;
sigc::signal<void,boost::shared_ptr<ARDOUR::Insert> > InsertUnselected;
static void register_actions();
@ -103,11 +104,11 @@ class RedirectBox : public Gtk::HBox
struct ModelColumns : public Gtk::TreeModel::ColumnRecord {
ModelColumns () {
add (text);
add (redirect);
add (insert);
add (color);
}
Gtk::TreeModelColumn<std::string> text;
Gtk::TreeModelColumn<boost::shared_ptr<ARDOUR::Redirect> > redirect;
Gtk::TreeModelColumn<boost::shared_ptr<ARDOUR::Insert> > insert;
Gtk::TreeModelColumn<Gdk::Color> color;
};
@ -117,15 +118,15 @@ class RedirectBox : public Gtk::HBox
void selection_changed ();
static bool get_colors;
static Gdk::Color* active_redirect_color;
static Gdk::Color* inactive_redirect_color;
static Gdk::Color* active_insert_color;
static Gdk::Color* inactive_insert_color;
Gtk::EventBox redirect_eventbox;
Gtk::HBox redirect_hpacker;
Gtkmm2ext::DnDTreeView<boost::shared_ptr<ARDOUR::Redirect> > redirect_display;
Gtk::ScrolledWindow redirect_scroller;
Gtk::EventBox insert_eventbox;
Gtk::HBox insert_hpacker;
Gtkmm2ext::DnDTreeView<boost::shared_ptr<ARDOUR::Insert> > insert_display;
Gtk::ScrolledWindow insert_scroller;
void object_drop (std::string type, uint32_t cnt, const boost::shared_ptr<ARDOUR::Redirect>*);
void object_drop (std::string type, uint32_t cnt, const boost::shared_ptr<ARDOUR::Insert>*);
Width _width;
@ -135,72 +136,71 @@ class RedirectBox : public Gtk::HBox
void new_send ();
void show_send_controls ();
Gtk::Menu *redirect_menu;
gint redirect_menu_map_handler (GdkEventAny *ev);
Gtk::Menu * build_redirect_menu ();
void build_redirect_tooltip (Gtk::EventBox&, string);
void show_redirect_menu (gint arg);
Gtk::Menu *insert_menu;
gint insert_menu_map_handler (GdkEventAny *ev);
Gtk::Menu * build_insert_menu ();
void build_insert_tooltip (Gtk::EventBox&, string);
void show_insert_menu (gint arg);
void choose_send ();
void send_io_finished (IOSelector::Result, boost::weak_ptr<ARDOUR::Redirect>, IOSelectorWindow*);
void send_io_finished (IOSelector::Result, boost::shared_ptr<ARDOUR::Send>, IOSelectorWindow*);
void choose_insert ();
void choose_plugin ();
void insert_plugin_chosen (boost::shared_ptr<ARDOUR::Plugin>);
bool no_redirect_redisplay;
bool no_insert_redisplay;
bool ignore_delete;
bool redirect_button_press_event (GdkEventButton *);
bool redirect_button_release_event (GdkEventButton *);
void redisplay_redirects (void* src);
void add_redirect_to_display (boost::shared_ptr<ARDOUR::Redirect>);
bool insert_button_press_event (GdkEventButton *);
bool insert_button_release_event (GdkEventButton *);
void redisplay_inserts ();
void add_insert_to_display (boost::shared_ptr<ARDOUR::Insert>);
void row_deleted (const Gtk::TreeModel::Path& path);
void show_redirect_active_r (ARDOUR::Redirect*, void *, boost::weak_ptr<ARDOUR::Redirect>);
void show_redirect_active (boost::weak_ptr<ARDOUR::Redirect>);
void show_redirect_name (void* src, boost::weak_ptr<ARDOUR::Redirect>);
string redirect_name (boost::weak_ptr<ARDOUR::Redirect>);
void show_insert_active (boost::weak_ptr<ARDOUR::Insert>);
void show_insert_name (boost::weak_ptr<ARDOUR::Insert>);
string insert_name (boost::weak_ptr<ARDOUR::Insert>);
void remove_redirect_gui (boost::shared_ptr<ARDOUR::Redirect>);
void remove_insert_gui (boost::shared_ptr<ARDOUR::Insert>);
void redirects_reordered (const Gtk::TreeModel::Path&, const Gtk::TreeModel::iterator&, int*);
void compute_redirect_sort_keys ();
vector<sigc::connection> redirect_active_connections;
vector<sigc::connection> redirect_name_connections;
void inserts_reordered (const Gtk::TreeModel::Path&, const Gtk::TreeModel::iterator&, int*);
void compute_insert_sort_keys ();
vector<sigc::connection> insert_active_connections;
vector<sigc::connection> insert_name_connections;
bool redirect_drag_in_progress;
void redirect_drag_begin (GdkDragContext*);
void redirect_drag_end (GdkDragContext*);
void all_redirects_active(bool state);
bool insert_drag_in_progress;
void insert_drag_begin (GdkDragContext*);
void insert_drag_end (GdkDragContext*);
void all_inserts_active(bool state);
void all_plugins_active(bool state);
void ab_plugins ();
void cut_redirects ();
void copy_redirects ();
void paste_redirects ();
void delete_redirects ();
void clear_redirects ();
void clone_redirects ();
void rename_redirects ();
void cut_inserts ();
void copy_inserts ();
void paste_inserts ();
void delete_inserts ();
void clear_inserts ();
void clone_inserts ();
void rename_inserts ();
void for_selected_redirects (void (RedirectBox::*pmf)(boost::shared_ptr<ARDOUR::Redirect>));
void get_selected_redirects (vector<boost::shared_ptr<ARDOUR::Redirect> >&);
void for_selected_inserts (void (RedirectBox::*pmf)(boost::shared_ptr<ARDOUR::Insert>));
void get_selected_inserts (vector<boost::shared_ptr<ARDOUR::Insert> >&);
static Glib::RefPtr<Gtk::Action> paste_action;
void paste_redirect_list (std::list<boost::shared_ptr<ARDOUR::Redirect> >& redirects);
void paste_insert_list (std::list<boost::shared_ptr<ARDOUR::Insert> >& inserts);
void activate_redirect (boost::shared_ptr<ARDOUR::Redirect>);
void deactivate_redirect (boost::shared_ptr<ARDOUR::Redirect>);
void cut_redirect (boost::shared_ptr<ARDOUR::Redirect>);
void copy_redirect (boost::shared_ptr<ARDOUR::Redirect>);
void edit_redirect (boost::shared_ptr<ARDOUR::Redirect>);
void hide_redirect_editor (boost::shared_ptr<ARDOUR::Redirect>);
void rename_redirect (boost::shared_ptr<ARDOUR::Redirect>);
void activate_insert (boost::shared_ptr<ARDOUR::Insert>);
void deactivate_insert (boost::shared_ptr<ARDOUR::Insert>);
void cut_insert (boost::shared_ptr<ARDOUR::Insert>);
void copy_insert (boost::shared_ptr<ARDOUR::Insert>);
void edit_insert (boost::shared_ptr<ARDOUR::Insert>);
void hide_insert_editor (boost::shared_ptr<ARDOUR::Insert>);
void rename_insert (boost::shared_ptr<ARDOUR::Insert>);
gint idle_delete_redirect (boost::weak_ptr<ARDOUR::Redirect>);
gint idle_delete_insert (boost::weak_ptr<ARDOUR::Insert>);
void weird_plugin_dialog (ARDOUR::Plugin& p, ARDOUR::Route::InsertStreams streams, boost::shared_ptr<ARDOUR::IO> io);
static RedirectBox* _current_redirect_box;
static RedirectBox* _current_insert_box;
static bool enter_box (GdkEventCrossing*, RedirectBox*);
static bool leave_box (GdkEventCrossing*, RedirectBox*);
@ -223,8 +223,8 @@ class RedirectBox : public Gtk::HBox
static void rb_ab_plugins ();
static void rb_deactivate_plugins ();
void route_name_changed (void* src, PluginUIWindow* plugin_ui, boost::weak_ptr<ARDOUR::PluginInsert> pi);
std::string generate_redirect_title (boost::shared_ptr<ARDOUR::PluginInsert> pi);
void route_name_changed (PluginUIWindow* plugin_ui, boost::weak_ptr<ARDOUR::PluginInsert> pi);
std::string generate_insert_title (boost::shared_ptr<ARDOUR::PluginInsert> pi);
};
#endif /* __ardour_gtk_redirect_box__ */

View file

@ -24,9 +24,9 @@
#include <boost/shared_ptr.hpp>
namespace ARDOUR {
class Redirect;
class Insert;
}
struct RedirectSelection : list<boost::shared_ptr<ARDOUR::Redirect> > {};
struct InsertSelection : list<boost::shared_ptr<ARDOUR::Insert> > {};
#endif /* __ardour_gtk_redirect_selection_h__ */

View file

@ -60,8 +60,8 @@ RouteParams_UI::RouteParams_UI ()
: ArdourDialog ("track/bus inspector"),
track_menu(0)
{
pre_redirect_box = 0;
post_redirect_box = 0;
pre_insert_box = 0;
post_insert_box = 0;
_input_iosel = 0;
_output_iosel = 0;
_active_pre_view = 0;
@ -178,16 +178,16 @@ RouteParams_UI::add_routes (Session::RouteList& routes)
//route_select_list.rows().back().select ();
route->name_changed.connect (bind (mem_fun(*this, &RouteParams_UI::route_name_changed), route));
route->NameChanged.connect (bind (mem_fun(*this, &RouteParams_UI::route_name_changed), route));
route->GoingAway.connect (bind (mem_fun(*this, &RouteParams_UI::route_removed), route));
}
}
void
RouteParams_UI::route_name_changed (void *src, boost::shared_ptr<Route> route)
RouteParams_UI::route_name_changed (boost::shared_ptr<Route> route)
{
ENSURE_GUI_THREAD(bind (mem_fun(*this, &RouteParams_UI::route_name_changed), src, route));
ENSURE_GUI_THREAD(bind (mem_fun(*this, &RouteParams_UI::route_name_changed), route));
bool found = false ;
TreeModel::Children rows = route_display_model->children();
@ -219,16 +219,16 @@ RouteParams_UI::setup_redirect_boxes()
cleanup_redirect_boxes();
// construct new redirect boxes
pre_redirect_box = new RedirectBox(PreFader, *session, _route, *_plugin_selector, _rr_selection);
post_redirect_box = new RedirectBox(PostFader, *session, _route, *_plugin_selector, _rr_selection);
pre_insert_box = new RedirectBox(PreFader, *session, _route, *_plugin_selector, _rr_selection);
post_insert_box = new RedirectBox(PostFader, *session, _route, *_plugin_selector, _rr_selection);
pre_redir_hpane.pack1 (*pre_redirect_box);
post_redir_hpane.pack1 (*post_redirect_box);
pre_redir_hpane.pack1 (*pre_insert_box);
post_redir_hpane.pack1 (*post_insert_box);
pre_redirect_box->RedirectSelected.connect (bind (mem_fun(*this, &RouteParams_UI::redirect_selected), PreFader));
pre_redirect_box->RedirectUnselected.connect (bind (mem_fun(*this, &RouteParams_UI::redirect_selected), PreFader));
post_redirect_box->RedirectSelected.connect (bind (mem_fun(*this, &RouteParams_UI::redirect_selected), PostFader));
post_redirect_box->RedirectUnselected.connect (bind (mem_fun(*this, &RouteParams_UI::redirect_selected), PostFader));
pre_insert_box->InsertSelected.connect (bind (mem_fun(*this, &RouteParams_UI::redirect_selected), PreFader));
pre_insert_box->InsertUnselected.connect (bind (mem_fun(*this, &RouteParams_UI::redirect_selected), PreFader));
post_insert_box->InsertSelected.connect (bind (mem_fun(*this, &RouteParams_UI::redirect_selected), PostFader));
post_insert_box->InsertUnselected.connect (bind (mem_fun(*this, &RouteParams_UI::redirect_selected), PostFader));
pre_redir_hpane.show_all();
post_redir_hpane.show_all();
@ -239,16 +239,16 @@ RouteParams_UI::setup_redirect_boxes()
void
RouteParams_UI::cleanup_redirect_boxes()
{
if (pre_redirect_box) {
pre_redir_hpane.remove(*pre_redirect_box);
delete pre_redirect_box;
pre_redirect_box = 0;
if (pre_insert_box) {
pre_redir_hpane.remove(*pre_insert_box);
delete pre_insert_box;
pre_insert_box = 0;
}
if (post_redirect_box) {
post_redir_hpane.remove(*post_redirect_box);
delete post_redirect_box;
post_redirect_box = 0;
if (post_insert_box) {
post_redir_hpane.remove(*post_insert_box);
delete post_insert_box;
post_insert_box = 0;
}
}
@ -347,8 +347,8 @@ RouteParams_UI::route_removed (boost::shared_ptr<Route> route)
cleanup_redirect_boxes();
_route.reset ((Route*) 0);
_pre_redirect.reset ((Redirect*) 0);
_post_redirect.reset ((Redirect*) 0);
_pre_insert.reset ((Redirect*) 0);
_post_insert.reset ((Redirect*) 0);
update_title();
}
}
@ -389,8 +389,8 @@ RouteParams_UI::session_gone ()
cleanup_redirect_boxes();
_route.reset ((Route*) 0);
_pre_redirect.reset ((Redirect*) 0);
_post_redirect.reset ((Redirect*) 0);
_pre_insert.reset ((Redirect*) 0);
_post_insert.reset ((Redirect*) 0);
update_title();
ArdourDialog::session_gone();
@ -429,7 +429,7 @@ RouteParams_UI::route_selected()
setup_redirect_boxes();
// bind to redirects changed event for this route
_route_conn = route->redirects_changed.connect (mem_fun(*this, &RouteParams_UI::redirects_changed));
_route_conn = route->inserts_changed.connect (mem_fun(*this, &RouteParams_UI::inserts_changed));
track_input_label.set_text (_route->name());
@ -446,8 +446,8 @@ RouteParams_UI::route_selected()
cleanup_redirect_boxes();
_route.reset ((Route*) 0);
_pre_redirect.reset ((Redirect*) 0);
_post_redirect.reset ((Redirect *) 0);
_pre_insert.reset ((Redirect*) 0);
_post_insert.reset ((Redirect *) 0);
track_input_label.set_text(_("NO TRACK"));
update_title();
}
@ -467,34 +467,34 @@ RouteParams_UI::route_selected()
// cleanup_redirect_boxes();
// _route.reset ((Route*)0);
// _pre_redirect = 0;
// _post_redirect = 0;
// _pre_insert = 0;
// _post_insert = 0;
// track_input_label.set_text(_("NO TRACK"));
// update_title();
// }
//}
void
RouteParams_UI::redirects_changed (void *src)
RouteParams_UI::inserts_changed ()
{
ENSURE_GUI_THREAD(bind (mem_fun(*this, &RouteParams_UI::redirects_changed), src));
ENSURE_GUI_THREAD(mem_fun(*this, &RouteParams_UI::inserts_changed));
// pre_redirect_list.freeze ();
// pre_redirect_list.clear ();
// post_redirect_list.freeze ();
// post_redirect_list.clear ();
// pre_insert_list.freeze ();
// pre_insert_list.clear ();
// post_insert_list.freeze ();
// post_insert_list.clear ();
// if (_route) {
// _route->foreach_redirect (this, &RouteParams_UI::add_redirect_to_display);
// }
// pre_redirect_list.thaw ();
// post_redirect_list.thaw ();
// pre_insert_list.thaw ();
// post_insert_list.thaw ();
cleanup_pre_view();
cleanup_post_view();
_pre_redirect.reset ((Redirect*) 0);
_post_redirect.reset ((Redirect*) 0);
_pre_insert.reset ((Redirect*) 0);
_post_insert.reset ((Redirect*) 0);
//update_title();
}
@ -518,98 +518,84 @@ RouteParams_UI::show_track_menu()
void
RouteParams_UI::redirect_selected (boost::shared_ptr<ARDOUR::Redirect> redirect, ARDOUR::Placement place)
RouteParams_UI::redirect_selected (boost::shared_ptr<ARDOUR::Insert> insert, ARDOUR::Placement place)
{
boost::shared_ptr<Insert> insert;
if ((place == PreFader && _pre_redirect == redirect)
|| (place == PostFader && _post_redirect == redirect)){
if ((place == PreFader && _pre_insert == insert)
|| (place == PostFader && _post_insert == insert)){
return;
}
if ((insert = boost::dynamic_pointer_cast<Insert> (redirect)) == 0) {
boost::shared_ptr<Send> send;
boost::shared_ptr<PluginInsert> plugin_insert;
boost::shared_ptr<PortInsert> port_insert;
if ((send = boost::dynamic_pointer_cast<Send> (insert)) != 0) {
boost::shared_ptr<Send> send;
if ((send = boost::dynamic_pointer_cast<Send> (redirect)) != 0) {
SendUI *send_ui = new SendUI (send, *session);
/* its a send */
if (place == PreFader) {
cleanup_pre_view();
_pre_plugin_conn = send->GoingAway.connect (bind (mem_fun(*this, &RouteParams_UI::redirect_going_away), insert));
_active_pre_view = send_ui;
pre_redir_hpane.add2 (*_active_pre_view);
pre_redir_hpane.show_all();
}
else {
cleanup_post_view();
_post_plugin_conn = send->GoingAway.connect (bind (mem_fun(*this, &RouteParams_UI::redirect_going_away), insert));
_active_post_view = send_ui;
post_redir_hpane.add2 (*_active_post_view);
post_redir_hpane.show_all();
}
} else if ((plugin_insert = boost::dynamic_pointer_cast<PluginInsert> (insert)) != 0) {
SendUI *send_ui = new SendUI (send, *session);
LadspaPluginUI *plugin_ui = new LadspaPluginUI (plugin_insert, true);
if (place == PreFader) {
cleanup_pre_view();
_pre_plugin_conn = send->GoingAway.connect (bind (mem_fun(*this, &RouteParams_UI::redirect_going_away), redirect));
_active_pre_view = send_ui;
pre_redir_hpane.add2 (*_active_pre_view);
pre_redir_hpane.show_all();
}
else {
cleanup_post_view();
_post_plugin_conn = send->GoingAway.connect (bind (mem_fun(*this, &RouteParams_UI::redirect_going_away), redirect));
_active_post_view = send_ui;
post_redir_hpane.add2 (*_active_post_view);
post_redir_hpane.show_all();
}
if (place == PreFader) {
cleanup_pre_view();
_pre_plugin_conn = plugin_insert->plugin()->GoingAway.connect (bind (mem_fun(*this, &RouteParams_UI::plugin_going_away), PreFader));
plugin_ui->start_updating (0);
_active_pre_view = plugin_ui;
pre_redir_hpane.pack2 (*_active_pre_view);
pre_redir_hpane.show_all();
}
else {
cleanup_post_view();
_post_plugin_conn = plugin_insert->plugin()->GoingAway.connect (bind (mem_fun(*this, &RouteParams_UI::plugin_going_away), PostFader));
plugin_ui->start_updating (0);
_active_post_view = plugin_ui;
post_redir_hpane.pack2 (*_active_post_view);
post_redir_hpane.show_all();
}
} else {
/* its an insert, though we don't know what kind yet. */
} else if ((port_insert = boost::dynamic_pointer_cast<PortInsert> (insert)) != 0) {
boost::shared_ptr<PluginInsert> plugin_insert;
boost::shared_ptr<PortInsert> port_insert;
PortInsertUI *portinsert_ui = new PortInsertUI (*session, port_insert);
if ((plugin_insert = boost::dynamic_pointer_cast<PluginInsert> (insert)) != 0) {
LadspaPluginUI *plugin_ui = new LadspaPluginUI (plugin_insert, true);
if (place == PreFader) {
cleanup_pre_view();
_pre_plugin_conn = plugin_insert->plugin()->GoingAway.connect (bind (mem_fun(*this, &RouteParams_UI::plugin_going_away), PreFader));
plugin_ui->start_updating (0);
_active_pre_view = plugin_ui;
pre_redir_hpane.pack2 (*_active_pre_view);
pre_redir_hpane.show_all();
}
else {
cleanup_post_view();
_post_plugin_conn = plugin_insert->plugin()->GoingAway.connect (bind (mem_fun(*this, &RouteParams_UI::plugin_going_away), PostFader));
plugin_ui->start_updating (0);
_active_post_view = plugin_ui;
post_redir_hpane.pack2 (*_active_post_view);
post_redir_hpane.show_all();
}
} else if ((port_insert = boost::dynamic_pointer_cast<PortInsert> (insert)) != 0) {
PortInsertUI *portinsert_ui = new PortInsertUI (*session, port_insert);
if (place == PreFader) {
cleanup_pre_view();
_pre_plugin_conn = port_insert->GoingAway.connect (bind (mem_fun(*this, &RouteParams_UI::redirect_going_away), redirect));
_active_pre_view = portinsert_ui;
pre_redir_hpane.pack2 (*_active_pre_view);
portinsert_ui->redisplay();
pre_redir_hpane.show_all();
}
else {
cleanup_post_view();
_post_plugin_conn = port_insert->GoingAway.connect (bind (mem_fun(*this, &RouteParams_UI::redirect_going_away), redirect));
_active_post_view = portinsert_ui;
post_redir_hpane.pack2 (*_active_post_view);
portinsert_ui->redisplay();
post_redir_hpane.show_all();
}
if (place == PreFader) {
cleanup_pre_view();
_pre_plugin_conn = port_insert->GoingAway.connect (bind (mem_fun(*this, &RouteParams_UI::redirect_going_away), insert));
_active_pre_view = portinsert_ui;
pre_redir_hpane.pack2 (*_active_pre_view);
portinsert_ui->redisplay();
pre_redir_hpane.show_all();
}
else {
cleanup_post_view();
_post_plugin_conn = port_insert->GoingAway.connect (bind (mem_fun(*this, &RouteParams_UI::redirect_going_away), insert));
_active_post_view = portinsert_ui;
post_redir_hpane.pack2 (*_active_post_view);
portinsert_ui->redisplay();
post_redir_hpane.show_all();
}
}
if (place == PreFader) {
_pre_redirect = redirect;
_pre_insert = insert;
} else {
_post_redirect = redirect;
_post_insert = insert;
}
update_title();
@ -625,28 +611,28 @@ RouteParams_UI::plugin_going_away (Placement place)
if (place == PreFader) {
cleanup_pre_view (false);
_pre_redirect.reset ((Redirect*) 0);
_pre_insert.reset ((Redirect*) 0);
}
else {
cleanup_post_view (false);
_post_redirect.reset ((Redirect*) 0);
_post_insert.reset ((Redirect*) 0);
}
}
void
RouteParams_UI::redirect_going_away (boost::shared_ptr<ARDOUR::Redirect> redirect)
RouteParams_UI::redirect_going_away (boost::shared_ptr<ARDOUR::Insert> insert)
{
ENSURE_GUI_THREAD(bind (mem_fun(*this, &RouteParams_UI::redirect_going_away), redirect));
ENSURE_GUI_THREAD(bind (mem_fun(*this, &RouteParams_UI::redirect_going_away), insert));
printf ("redirect going away\n");
// delete the current view without calling finish
if (redirect == _pre_redirect) {
if (insert == _pre_insert) {
cleanup_pre_view (false);
_pre_redirect.reset ((Redirect*) 0);
} else if (redirect == _post_redirect) {
_pre_insert.reset ((Redirect*) 0);
} else if (insert == _post_insert) {
cleanup_post_view (false);
_post_redirect.reset ((Redirect*) 0);
_post_insert.reset ((Redirect*) 0);
}
}

View file

@ -89,8 +89,8 @@ class RouteParams_UI : public ArdourDialog
Gtk::HBox route_hpacker;
Gtk::VBox route_vpacker;
RedirectBox * pre_redirect_box;
RedirectBox * post_redirect_box;
RedirectBox * pre_insert_box;
RedirectBox * post_insert_box;
Gtk::HPaned list_hpane;
@ -121,11 +121,11 @@ class RouteParams_UI : public ArdourDialog
sigc::connection _route_conn;
sigc::connection _route_ds_conn;
boost::shared_ptr<ARDOUR::Redirect> _pre_redirect;
sigc::connection _pre_plugin_conn;
boost::shared_ptr<ARDOUR::Insert> _pre_insert;
sigc::connection _pre_plugin_conn;
boost::shared_ptr<ARDOUR::Redirect> _post_redirect;
sigc::connection _post_plugin_conn;
boost::shared_ptr<ARDOUR::Insert> _post_insert;
sigc::connection _post_plugin_conn;
enum ConfigView {
@ -157,7 +157,7 @@ class RouteParams_UI : public ArdourDialog
void add_routes (ARDOUR::Session::RouteList&);
void route_name_changed (void *src, boost::shared_ptr<ARDOUR::Route> route);
void route_name_changed (boost::shared_ptr<ARDOUR::Route> route);
void route_removed (boost::shared_ptr<ARDOUR::Route> route);
@ -171,15 +171,15 @@ class RouteParams_UI : public ArdourDialog
void redirects_changed (void *src);
void inserts_changed ();
void setup_redirect_boxes();
void cleanup_redirect_boxes();
void redirect_selected (boost::shared_ptr<ARDOUR::Redirect>, ARDOUR::Placement);
void redirect_selected (boost::shared_ptr<ARDOUR::Insert>, ARDOUR::Placement);
void plugin_going_away (ARDOUR::Placement);
void redirect_going_away (boost::shared_ptr<ARDOUR::Redirect>);
void redirect_going_away (boost::shared_ptr<ARDOUR::Insert>);
gint edit_input_configuration (GdkEventButton *ev);
gint edit_output_configuration (GdkEventButton *ev);

View file

@ -22,7 +22,7 @@
#include <pbd/error.h>
#include <ardour/playlist.h>
#include <ardour/redirect.h>
#include <ardour/insert.h>
#include <ardour/route.h>
#include "route_redirect_selection.h"
@ -37,7 +37,7 @@ RouteRedirectSelection&
RouteRedirectSelection::operator= (const RouteRedirectSelection& other)
{
if (&other != this) {
redirects = other.redirects;
inserts = other.inserts;
routes = other.routes;
}
return *this;
@ -46,22 +46,22 @@ RouteRedirectSelection::operator= (const RouteRedirectSelection& other)
bool
operator== (const RouteRedirectSelection& a, const RouteRedirectSelection& b)
{
return a.redirects == b.redirects &&
return a.inserts == b.inserts &&
a.routes == b.routes;
}
void
RouteRedirectSelection::clear ()
{
clear_redirects ();
clear_inserts ();
clear_routes ();
}
void
RouteRedirectSelection::clear_redirects ()
RouteRedirectSelection::clear_inserts ()
{
redirects.clear ();
RedirectsChanged ();
inserts.clear ();
InsertsChanged ();
}
void
@ -72,27 +72,27 @@ RouteRedirectSelection::clear_routes ()
}
void
RouteRedirectSelection::add (boost::shared_ptr<Redirect> r)
RouteRedirectSelection::add (boost::shared_ptr<Insert> r)
{
if (find (redirects.begin(), redirects.end(), r) == redirects.end()) {
redirects.push_back (r);
if (find (inserts.begin(), inserts.end(), r) == inserts.end()) {
inserts.push_back (r);
// XXX SHAREDPTR FIXME
// void (RouteRedirectSelection::*pmf)(Redirect*) = &RouteRedirectSelection::remove;
// r->GoingAway.connect (mem_fun(*this, pmf));
RedirectsChanged();
InsertsChanged();
}
}
void
RouteRedirectSelection::add (const vector<boost::shared_ptr<Redirect> >& rlist)
RouteRedirectSelection::add (const vector<boost::shared_ptr<Insert> >& rlist)
{
bool changed = false;
for (vector<boost::shared_ptr<Redirect> >::const_iterator i = rlist.begin(); i != rlist.end(); ++i) {
if (find (redirects.begin(), redirects.end(), *i) == redirects.end()) {
redirects.push_back (*i);
for (vector<boost::shared_ptr<Insert> >::const_iterator i = rlist.begin(); i != rlist.end(); ++i) {
if (find (inserts.begin(), inserts.end(), *i) == inserts.end()) {
inserts.push_back (*i);
// XXX SHAREDPTR FIXME
@ -103,31 +103,31 @@ RouteRedirectSelection::add (const vector<boost::shared_ptr<Redirect> >& rlist)
}
if (changed) {
RedirectsChanged();
InsertsChanged();
}
}
void
RouteRedirectSelection::remove (boost::shared_ptr<Redirect> r)
RouteRedirectSelection::remove (boost::shared_ptr<Insert> r)
{
list<boost::shared_ptr<Redirect> >::iterator i;
if ((i = find (redirects.begin(), redirects.end(), r)) != redirects.end()) {
redirects.erase (i);
RedirectsChanged ();
list<boost::shared_ptr<Insert> >::iterator i;
if ((i = find (inserts.begin(), inserts.end(), r)) != inserts.end()) {
inserts.erase (i);
InsertsChanged ();
}
}
void
RouteRedirectSelection::set (boost::shared_ptr<Redirect> r)
RouteRedirectSelection::set (boost::shared_ptr<Insert> r)
{
clear_redirects ();
clear_inserts ();
add (r);
}
void
RouteRedirectSelection::set (const vector<boost::shared_ptr<Redirect> >& rlist)
RouteRedirectSelection::set (const vector<boost::shared_ptr<Insert> >& rlist)
{
clear_redirects ();
clear_inserts ();
add (rlist);
}
@ -171,6 +171,6 @@ RouteRedirectSelection::selected (boost::shared_ptr<Route> r)
bool
RouteRedirectSelection::empty ()
{
return redirects.empty () && routes.empty ();
return inserts.empty () && routes.empty ();
}

View file

@ -29,30 +29,30 @@
class RouteRedirectSelection : public sigc::trackable
{
public:
RedirectSelection redirects;
InsertSelection inserts;
RouteSelection routes;
RouteRedirectSelection() {}
RouteRedirectSelection& operator= (const RouteRedirectSelection& other);
sigc::signal<void> RedirectsChanged;
sigc::signal<void> InsertsChanged;
sigc::signal<void> RoutesChanged;
void clear ();
bool empty();
void set (boost::shared_ptr<ARDOUR::Redirect>);
void set (const std::vector<boost::shared_ptr<ARDOUR::Redirect> >&);
void add (boost::shared_ptr<ARDOUR::Redirect>);
void add (const std::vector<boost::shared_ptr<ARDOUR::Redirect> >&);
void remove (boost::shared_ptr<ARDOUR::Redirect>);
void set (boost::shared_ptr<ARDOUR::Insert>);
void set (const std::vector<boost::shared_ptr<ARDOUR::Insert> >&);
void add (boost::shared_ptr<ARDOUR::Insert>);
void add (const std::vector<boost::shared_ptr<ARDOUR::Insert> >&);
void remove (boost::shared_ptr<ARDOUR::Insert>);
void set (boost::shared_ptr<ARDOUR::Route>);
void add (boost::shared_ptr<ARDOUR::Route>);
void remove (boost::shared_ptr<ARDOUR::Route>);
void clear_redirects ();
void clear_inserts ();
void clear_routes ();
bool selected (boost::shared_ptr<ARDOUR::Route>);

View file

@ -179,8 +179,8 @@ RouteTimeAxisView::RouteTimeAxisView (PublicEditor& ed, Session& sess, boost::sh
_route->mute_changed.connect (mem_fun(*this, &RouteUI::mute_changed));
_route->solo_changed.connect (mem_fun(*this, &RouteUI::solo_changed));
_route->redirects_changed.connect (mem_fun(*this, &RouteTimeAxisView::redirects_changed));
_route->name_changed.connect (mem_fun(*this, &RouteTimeAxisView::route_name_changed));
_route->inserts_changed.connect (mem_fun(*this, &RouteTimeAxisView::inserts_changed));
_route->NameChanged.connect (mem_fun(*this, &RouteTimeAxisView::route_name_changed));
_route->solo_safe_changed.connect (mem_fun(*this, &RouteUI::solo_changed));
@ -204,9 +204,9 @@ RouteTimeAxisView::~RouteTimeAxisView ()
{
GoingAway (); /* EMIT_SIGNAL */
vector_delete (&redirect_automation_curves);
vector_delete (&insert_automation_curves);
for (list<RedirectAutomationInfo*>::iterator i = redirect_automation.begin(); i != redirect_automation.end(); ++i) {
for (list<InsertAutomationInfo*>::iterator i = insert_automation.begin(); i != insert_automation.end(); ++i) {
delete *i;
}
@ -232,9 +232,9 @@ RouteTimeAxisView::post_construct ()
/* map current state of the route */
update_diskstream_display ();
_route->foreach_redirect (this, &RouteTimeAxisView::add_redirect_to_subplugin_menu);
_route->foreach_redirect (this, &RouteTimeAxisView::add_existing_redirect_automation_curves);
reset_redirect_automation_curves ();
_route->foreach_insert (this, &RouteTimeAxisView::add_insert_to_subplugin_menu);
_route->foreach_insert (this, &RouteTimeAxisView::add_existing_insert_automation_curves);
reset_insert_automation_curves ();
}
void
@ -322,7 +322,7 @@ RouteTimeAxisView::label_view ()
}
void
RouteTimeAxisView::route_name_changed (void *src)
RouteTimeAxisView::route_name_changed ()
{
editor.route_name_changed (this);
label_view ();
@ -1135,7 +1135,7 @@ RouteTimeAxisView::name_entry_changed ()
}
if (_session.route_name_unique (x)) {
_route->set_name (x, this);
_route->set_name (x);
} else {
ARDOUR_UI::instance()->popup_error (_("A track already exists with that name"));
name_entry.set_text (_route->name());
@ -1253,8 +1253,7 @@ RouteTimeAxisView::paste (nframes_t pos, float times, Selection& selection, size
list<TimeAxisView*>
RouteTimeAxisView::get_child_list()
{
list<TimeAxisView*>redirect_children;
list<TimeAxisView*> redirect_children;
for (vector<TimeAxisView*>::iterator i = children.begin(); i != children.end(); ++i) {
if (!(*i)->hidden()) {
@ -1385,10 +1384,10 @@ RouteTimeAxisView::show_all_automation ()
{
no_redraw = true;
for (list<RedirectAutomationInfo*>::iterator i = redirect_automation.begin(); i != redirect_automation.end(); ++i) {
for (vector<RedirectAutomationNode*>::iterator ii = (*i)->lines.begin(); ii != (*i)->lines.end(); ++ii) {
for (list<InsertAutomationInfo*>::iterator i = insert_automation.begin(); i != insert_automation.end(); ++i) {
for (vector<InsertAutomationNode*>::iterator ii = (*i)->lines.begin(); ii != (*i)->lines.end(); ++ii) {
if ((*ii)->view == 0) {
add_redirect_automation_curve ((*i)->redirect, (*ii)->what);
add_insert_automation_curve ((*i)->insert, (*ii)->what);
}
(*ii)->menu_item->set_active (true);
@ -1405,8 +1404,8 @@ RouteTimeAxisView::show_existing_automation ()
{
no_redraw = true;
for (list<RedirectAutomationInfo*>::iterator i = redirect_automation.begin(); i != redirect_automation.end(); ++i) {
for (vector<RedirectAutomationNode*>::iterator ii = (*i)->lines.begin(); ii != (*i)->lines.end(); ++ii) {
for (list<InsertAutomationInfo*>::iterator i = insert_automation.begin(); i != insert_automation.end(); ++i) {
for (vector<InsertAutomationNode*>::iterator ii = (*i)->lines.begin(); ii != (*i)->lines.end(); ++ii) {
if ((*ii)->view != 0) {
(*ii)->menu_item->set_active (true);
}
@ -1423,8 +1422,8 @@ RouteTimeAxisView::hide_all_automation ()
{
no_redraw = true;
for (list<RedirectAutomationInfo*>::iterator i = redirect_automation.begin(); i != redirect_automation.end(); ++i) {
for (vector<RedirectAutomationNode*>::iterator ii = (*i)->lines.begin(); ii != (*i)->lines.end(); ++ii) {
for (list<InsertAutomationInfo*>::iterator i = insert_automation.begin(); i != insert_automation.end(); ++i) {
for (vector<InsertAutomationNode*>::iterator ii = (*i)->lines.begin(); ii != (*i)->lines.end(); ++ii) {
(*ii)->menu_item->set_active (false);
}
}
@ -1447,20 +1446,20 @@ RouteTimeAxisView::region_view_added (RegionView* rv)
}
void
RouteTimeAxisView::add_ghost_to_redirect (RegionView* rv, AutomationTimeAxisView* atv)
RouteTimeAxisView::add_ghost_to_insert (RegionView* rv, AutomationTimeAxisView* atv)
{
rv->add_ghost (*atv);
}
RouteTimeAxisView::RedirectAutomationInfo::~RedirectAutomationInfo ()
RouteTimeAxisView::InsertAutomationInfo::~InsertAutomationInfo ()
{
for (vector<RedirectAutomationNode*>::iterator i = lines.begin(); i != lines.end(); ++i) {
for (vector<InsertAutomationNode*>::iterator i = lines.begin(); i != lines.end(); ++i) {
delete *i;
}
}
RouteTimeAxisView::RedirectAutomationNode::~RedirectAutomationNode ()
RouteTimeAxisView::InsertAutomationNode::~InsertAutomationNode ()
{
parent.remove_ran (this);
@ -1470,21 +1469,21 @@ RouteTimeAxisView::RedirectAutomationNode::~RedirectAutomationNode ()
}
void
RouteTimeAxisView::remove_ran (RedirectAutomationNode* ran)
RouteTimeAxisView::remove_ran (InsertAutomationNode* ran)
{
if (ran->view) {
remove_child (ran->view);
}
}
RouteTimeAxisView::RedirectAutomationNode*
RouteTimeAxisView::find_redirect_automation_node (boost::shared_ptr<Redirect> redirect, uint32_t what)
RouteTimeAxisView::InsertAutomationNode*
RouteTimeAxisView::find_insert_automation_node (boost::shared_ptr<Insert> insert, uint32_t what)
{
for (list<RedirectAutomationInfo*>::iterator i = redirect_automation.begin(); i != redirect_automation.end(); ++i) {
for (list<InsertAutomationInfo*>::iterator i = insert_automation.begin(); i != insert_automation.end(); ++i) {
if ((*i)->redirect == redirect) {
if ((*i)->insert == insert) {
for (vector<RedirectAutomationNode*>::iterator ii = (*i)->lines.begin(); ii != (*i)->lines.end(); ++ii) {
for (vector<InsertAutomationNode*>::iterator ii = (*i)->lines.begin(); ii != (*i)->lines.end(); ++ii) {
if ((*ii)->what == what) {
return *ii;
}
@ -1495,7 +1494,6 @@ RouteTimeAxisView::find_redirect_automation_node (boost::shared_ptr<Redirect> re
return 0;
}
// FIXME: duplicated in midi_time_axis.cc
static string
legalize_for_xml_node (string str)
{
@ -1516,16 +1514,16 @@ legalize_for_xml_node (string str)
void
RouteTimeAxisView::add_redirect_automation_curve (boost::shared_ptr<Redirect> redirect, uint32_t what)
RouteTimeAxisView::add_insert_automation_curve (boost::shared_ptr<Insert> insert, uint32_t what)
{
RedirectAutomationLine* ral;
string name;
RedirectAutomationNode* ran;
InsertAutomationNode* ran;
if ((ran = find_redirect_automation_node (redirect, what)) == 0) {
if ((ran = find_insert_automation_node (insert, what)) == 0) {
fatal << _("programming error: ")
<< string_compose (X_("redirect automation curve for %1:%2 not registered with audio track!"),
redirect->name(), what)
<< string_compose (X_("insert automation curve for %1:%2 not registered with audio track!"),
insert->name(), what)
<< endmsg;
/*NOTREACHED*/
return;
@ -1535,25 +1533,25 @@ RouteTimeAxisView::add_redirect_automation_curve (boost::shared_ptr<Redirect> re
return;
}
name = redirect->describe_parameter (what);
name = insert->describe_parameter (what);
/* create a string that is a legal XML node name that can be used to refer to this redirect+port combination */
char state_name[256];
snprintf (state_name, sizeof (state_name), "Redirect-%s-%" PRIu32, legalize_for_xml_node (redirect->name()).c_str(), what);
snprintf (state_name, sizeof (state_name), "Redirect-%s-%" PRIu32, legalize_for_xml_node (insert->name()).c_str(), what);
ran->view = new RedirectAutomationTimeAxisView (_session, _route, editor, *this, parent_canvas, name, what, *redirect, state_name);
ran->view = new RedirectAutomationTimeAxisView (_session, _route, editor, *this, parent_canvas, name, what, *insert, state_name);
ral = new RedirectAutomationLine (name,
*redirect, what, _session, *ran->view,
*ran->view->canvas_display, redirect->automation_list (what));
*insert, what, _session, *ran->view,
*ran->view->canvas_display, insert->automation_list (what));
ral->set_line_color (Config->canvasvar_RedirectAutomationLine.get());
ral->queue_reset ();
ran->view->add_line (*ral);
ran->view->Hiding.connect (bind (mem_fun(*this, &RouteTimeAxisView::redirect_automation_track_hidden), ran, redirect));
ran->view->Hiding.connect (bind (mem_fun(*this, &RouteTimeAxisView::insert_automation_track_hidden), ran, insert));
if (!ran->view->marked_for_display()) {
ran->view->hide ();
@ -1564,68 +1562,68 @@ RouteTimeAxisView::add_redirect_automation_curve (boost::shared_ptr<Redirect> re
add_child (ran->view);
if (_view) {
_view->foreach_regionview (bind (mem_fun(*this, &RouteTimeAxisView::add_ghost_to_redirect), ran->view));
_view->foreach_regionview (bind (mem_fun(*this, &RouteTimeAxisView::add_ghost_to_insert), ran->view));
}
redirect->mark_automation_visible (what, true);
insert->mark_automation_visible (what, true);
}
void
RouteTimeAxisView::redirect_automation_track_hidden (RouteTimeAxisView::RedirectAutomationNode* ran, boost::shared_ptr<Redirect> r)
RouteTimeAxisView::insert_automation_track_hidden (RouteTimeAxisView::InsertAutomationNode* ran, boost::shared_ptr<Insert> i)
{
if (!_hidden) {
ran->menu_item->set_active (false);
}
r->mark_automation_visible (ran->what, false);
i->mark_automation_visible (ran->what, false);
_route->gui_changed ("track_height", (void *) 0); /* EMIT_SIGNAL */
}
void
RouteTimeAxisView::add_existing_redirect_automation_curves (boost::shared_ptr<Redirect> redirect)
RouteTimeAxisView::add_existing_insert_automation_curves (boost::shared_ptr<Insert> insert)
{
set<uint32_t> s;
RedirectAutomationLine *ral;
redirect->what_has_visible_automation (s);
insert->what_has_visible_automation (s);
for (set<uint32_t>::iterator i = s.begin(); i != s.end(); ++i) {
if ((ral = find_redirect_automation_curve (redirect, *i)) != 0) {
if ((ral = find_insert_automation_curve (insert, *i)) != 0) {
ral->queue_reset ();
} else {
add_redirect_automation_curve (redirect, (*i));
add_insert_automation_curve (insert, (*i));
}
}
}
void
RouteTimeAxisView::add_redirect_to_subplugin_menu (boost::shared_ptr<Redirect> r)
RouteTimeAxisView::add_insert_to_subplugin_menu (boost::shared_ptr<Insert> insert)
{
using namespace Menu_Helpers;
RedirectAutomationInfo *rai;
list<RedirectAutomationInfo*>::iterator x;
InsertAutomationInfo *rai;
list<InsertAutomationInfo*>::iterator x;
const std::set<uint32_t>& automatable = r->what_can_be_automated ();
const std::set<uint32_t>& automatable = insert->what_can_be_automated ();
std::set<uint32_t> has_visible_automation;
r->what_has_visible_automation(has_visible_automation);
insert->what_has_visible_automation(has_visible_automation);
if (automatable.empty()) {
return;
}
for (x = redirect_automation.begin(); x != redirect_automation.end(); ++x) {
if ((*x)->redirect == r) {
for (x = insert_automation.begin(); x != insert_automation.end(); ++x) {
if ((*x)->insert == insert) {
break;
}
}
if (x == redirect_automation.end()) {
if (x == insert_automation.end()) {
rai = new RedirectAutomationInfo (r);
redirect_automation.push_back (rai);
rai = new InsertAutomationInfo (insert);
insert_automation.push_back (rai);
} else {
@ -1633,7 +1631,7 @@ RouteTimeAxisView::add_redirect_to_subplugin_menu (boost::shared_ptr<Redirect> r
}
/* any older menu was deleted at the top of redirects_changed()
/* any older menu was deleted at the top of inserts_changed()
when we cleared the subplugin menu.
*/
@ -1645,10 +1643,10 @@ RouteTimeAxisView::add_redirect_to_subplugin_menu (boost::shared_ptr<Redirect> r
for (std::set<uint32_t>::const_iterator i = automatable.begin(); i != automatable.end(); ++i) {
RedirectAutomationNode* ran;
InsertAutomationNode* ran;
CheckMenuItem* mitem;
string name = r->describe_parameter (*i);
string name = insert->describe_parameter (*i);
items.push_back (CheckMenuElem (name));
mitem = dynamic_cast<CheckMenuItem*> (&items.back());
@ -1657,11 +1655,11 @@ RouteTimeAxisView::add_redirect_to_subplugin_menu (boost::shared_ptr<Redirect> r
mitem->set_active(true);
}
if ((ran = find_redirect_automation_node (r, *i)) == 0) {
if ((ran = find_insert_automation_node (insert, *i)) == 0) {
/* new item */
ran = new RedirectAutomationNode (*i, mitem, *this);
ran = new InsertAutomationNode (*i, mitem, *this);
rai->lines.push_back (ran);
@ -1671,28 +1669,28 @@ RouteTimeAxisView::add_redirect_to_subplugin_menu (boost::shared_ptr<Redirect> r
}
mitem->signal_toggled().connect (bind (mem_fun(*this, &RouteTimeAxisView::redirect_menu_item_toggled), rai, ran));
mitem->signal_toggled().connect (bind (mem_fun(*this, &RouteTimeAxisView::insert_menu_item_toggled), rai, ran));
}
/* add the menu for this redirect, because the subplugin
menu is always cleared at the top of redirects_changed().
/* add the menu for this insert, because the subplugin
menu is always cleared at the top of inserts_changed().
this is the result of some poor design in gtkmm and/or
GTK+.
*/
subplugin_menu.items().push_back (MenuElem (r->name(), *rai->menu));
subplugin_menu.items().push_back (MenuElem (insert->name(), *rai->menu));
rai->valid = true;
}
void
RouteTimeAxisView::redirect_menu_item_toggled (RouteTimeAxisView::RedirectAutomationInfo* rai,
RouteTimeAxisView::RedirectAutomationNode* ran)
RouteTimeAxisView::insert_menu_item_toggled (RouteTimeAxisView::InsertAutomationInfo* rai,
RouteTimeAxisView::InsertAutomationNode* ran)
{
bool showit = ran->menu_item->get_active();
bool redraw = false;
if (ran->view == 0 && showit) {
add_redirect_automation_curve (rai->redirect, ran->what);
add_insert_automation_curve (rai->insert, ran->what);
redraw = true;
}
@ -1702,7 +1700,7 @@ RouteTimeAxisView::redirect_menu_item_toggled (RouteTimeAxisView::RedirectAutoma
ran->view->set_marked_for_display (true);
ran->view->canvas_display->show();
} else {
rai->redirect->mark_automation_visible (ran->what, true);
rai->insert->mark_automation_visible (ran->what, true);
ran->view->set_marked_for_display (false);
ran->view->hide ();
}
@ -1721,22 +1719,22 @@ RouteTimeAxisView::redirect_menu_item_toggled (RouteTimeAxisView::RedirectAutoma
}
void
RouteTimeAxisView::redirects_changed (void *src)
RouteTimeAxisView::inserts_changed ()
{
using namespace Menu_Helpers;
for (list<RedirectAutomationInfo*>::iterator i = redirect_automation.begin(); i != redirect_automation.end(); ++i) {
for (list<InsertAutomationInfo*>::iterator i = insert_automation.begin(); i != insert_automation.end(); ++i) {
(*i)->valid = false;
}
subplugin_menu.items().clear ();
_route->foreach_redirect (this, &RouteTimeAxisView::add_redirect_to_subplugin_menu);
_route->foreach_redirect (this, &RouteTimeAxisView::add_existing_redirect_automation_curves);
_route->foreach_insert (this, &RouteTimeAxisView::add_insert_to_subplugin_menu);
_route->foreach_insert (this, &RouteTimeAxisView::add_existing_insert_automation_curves);
for (list<RedirectAutomationInfo*>::iterator i = redirect_automation.begin(); i != redirect_automation.end(); ) {
for (list<InsertAutomationInfo*>::iterator i = insert_automation.begin(); i != insert_automation.end(); ) {
list<RedirectAutomationInfo*>::iterator tmp;
list<InsertAutomationInfo*>::iterator tmp;
tmp = i;
++tmp;
@ -1744,7 +1742,7 @@ RouteTimeAxisView::redirects_changed (void *src)
if (!(*i)->valid) {
delete *i;
redirect_automation.erase (i);
insert_automation.erase (i);
}
@ -1757,11 +1755,11 @@ RouteTimeAxisView::redirects_changed (void *src)
}
RedirectAutomationLine *
RouteTimeAxisView::find_redirect_automation_curve (boost::shared_ptr<Redirect> redirect, uint32_t what)
RouteTimeAxisView::find_insert_automation_curve (boost::shared_ptr<Insert> insert, uint32_t what)
{
RedirectAutomationNode* ran;
InsertAutomationNode* ran;
if ((ran = find_redirect_automation_node (redirect, what)) != 0) {
if ((ran = find_insert_automation_node (insert, what)) != 0) {
if (ran->view) {
return dynamic_cast<RedirectAutomationLine*> (ran->view->lines.front());
}
@ -1771,9 +1769,9 @@ RouteTimeAxisView::find_redirect_automation_curve (boost::shared_ptr<Redirect> r
}
void
RouteTimeAxisView::reset_redirect_automation_curves ()
RouteTimeAxisView::reset_insert_automation_curves ()
{
for (vector<RedirectAutomationLine*>::iterator i = redirect_automation_curves.begin(); i != redirect_automation_curves.end(); ++i) {
for (vector<RedirectAutomationLine*>::iterator i = insert_automation_curves.begin(); i != insert_automation_curves.end(); ++i) {
(*i)->reset();
}
}

View file

@ -103,28 +103,28 @@ public:
protected:
friend class StreamView;
struct RedirectAutomationNode {
struct InsertAutomationNode {
uint32_t what;
Gtk::CheckMenuItem* menu_item;
AutomationTimeAxisView* view;
RouteTimeAxisView& parent;
RedirectAutomationNode (uint32_t w, Gtk::CheckMenuItem* mitem, RouteTimeAxisView& p)
InsertAutomationNode (uint32_t w, Gtk::CheckMenuItem* mitem, RouteTimeAxisView& p)
: what (w), menu_item (mitem), view (0), parent (p) {}
~RedirectAutomationNode ();
~InsertAutomationNode ();
};
struct RedirectAutomationInfo {
boost::shared_ptr<ARDOUR::Redirect> redirect;
bool valid;
Gtk::Menu* menu;
vector<RedirectAutomationNode*> lines;
struct InsertAutomationInfo {
boost::shared_ptr<ARDOUR::Insert> insert;
bool valid;
Gtk::Menu* menu;
vector<InsertAutomationNode*> lines;
RedirectAutomationInfo (boost::shared_ptr<ARDOUR::Redirect> r)
: redirect (r), valid (true), menu (0) {}
InsertAutomationInfo (boost::shared_ptr<ARDOUR::Insert> i)
: insert (i), valid (true), menu (0) {}
~RedirectAutomationInfo ();
~InsertAutomationInfo ();
};
@ -133,30 +133,30 @@ protected:
gint edit_click (GdkEventButton *);
void redirects_changed (void *);
void inserts_changed ();
void add_redirect_to_subplugin_menu (boost::shared_ptr<ARDOUR::Redirect>);
void remove_ran (RedirectAutomationNode* ran);
void add_insert_to_subplugin_menu (boost::shared_ptr<ARDOUR::Insert>);
void remove_ran (InsertAutomationNode* ran);
void redirect_menu_item_toggled (RouteTimeAxisView::RedirectAutomationInfo*,
RouteTimeAxisView::RedirectAutomationNode*);
void insert_menu_item_toggled (RouteTimeAxisView::InsertAutomationInfo*,
RouteTimeAxisView::InsertAutomationNode*);
void redirect_automation_track_hidden (RedirectAutomationNode*,
boost::shared_ptr<ARDOUR::Redirect>);
void insert_automation_track_hidden (InsertAutomationNode*,
boost::shared_ptr<ARDOUR::Insert>);
RedirectAutomationNode*
find_redirect_automation_node (boost::shared_ptr<ARDOUR::Redirect> r, uint32_t);
InsertAutomationNode*
find_insert_automation_node (boost::shared_ptr<ARDOUR::Insert> i, uint32_t);
RedirectAutomationLine*
find_redirect_automation_curve (boost::shared_ptr<ARDOUR::Redirect> r, uint32_t);
find_insert_automation_curve (boost::shared_ptr<ARDOUR::Insert> i, uint32_t);
void add_redirect_automation_curve (boost::shared_ptr<ARDOUR::Redirect> r, uint32_t);
void add_existing_redirect_automation_curves (boost::shared_ptr<ARDOUR::Redirect>);
void add_insert_automation_curve (boost::shared_ptr<ARDOUR::Insert> r, uint32_t);
void add_existing_insert_automation_curves (boost::shared_ptr<ARDOUR::Insert>);
void reset_redirect_automation_curves ();
void reset_insert_automation_curves ();
void take_name_changed (void *);
void route_name_changed (void *);
void take_name_changed (void *src);
void route_name_changed ();
void name_entry_changed ();
void update_rec_display ();
@ -202,7 +202,7 @@ protected:
void color_handler ();
void region_view_added (RegionView*);
void add_ghost_to_redirect (RegionView*, AutomationTimeAxisView*);
void add_ghost_to_insert (RegionView*, AutomationTimeAxisView*);
StreamView* _view;
@ -211,7 +211,7 @@ protected:
Gtk::HBox other_button_hbox;
Gtk::Table button_table;
Gtk::Button redirect_button;
Gtk::Button insert_button;
Gtk::Button edit_group_button;
Gtk::Button playlist_button;
Gtk::Button size_button;
@ -238,8 +238,8 @@ protected:
void _set_track_mode (ARDOUR::Track* track, ARDOUR::TrackMode mode, Gtk::RadioMenuItem* reset_item);
void track_mode_changed ();
list<RedirectAutomationInfo*> redirect_automation;
vector<RedirectAutomationLine*> redirect_automation_curves;
list<InsertAutomationInfo*> insert_automation;
vector<RedirectAutomationLine*> insert_automation_curves;
sigc::connection modified_connection;

View file

@ -817,7 +817,7 @@ RouteUI::route_rename ()
case Gtk::RESPONSE_ACCEPT:
name_prompter.get_result (result);
if (result.length()) {
_route->set_name (result, this);
_route->set_name (result);
}
break;
}
@ -827,9 +827,9 @@ RouteUI::route_rename ()
}
void
RouteUI::name_changed (void *src)
RouteUI::name_changed ()
{
ENSURE_GUI_THREAD(bind (mem_fun (*this, &RouteUI::name_changed), src));
ENSURE_GUI_THREAD(sigc::mem_fun(*this, &RouteUI::name_changed));
name_label.set_text (_route->name());
}

View file

@ -98,7 +98,7 @@ class RouteUI : public virtual AxisView
void solo_changed(void*);
void solo_changed_so_update_mute ();
void mute_changed(void*);
virtual void redirects_changed (void *) {}
virtual void inserts_changed () {}
void route_rec_enable_changed();
void session_rec_enable_changed();
@ -133,7 +133,7 @@ class RouteUI : public virtual AxisView
void route_rename();
virtual void name_changed (void *src);
virtual void name_changed ();
void route_removed ();
Gtk::CheckMenuItem *route_active_menu_item;

View file

@ -64,7 +64,7 @@ operator== (const Selection& a, const Selection& b)
a.time == b.time &&
a.lines == b.lines &&
a.playlists == b.playlists &&
a.redirects == b.redirects;
a.inserts == b.inserts;
}
/** Clear everything from the Selection */
@ -77,7 +77,7 @@ Selection::clear ()
clear_lines();
clear_time ();
clear_playlists ();
clear_redirects ();
clear_inserts ();
}
void
@ -91,11 +91,11 @@ Selection::dump_region_layers()
void
Selection::clear_redirects ()
Selection::clear_inserts ()
{
if (!redirects.empty()) {
redirects.clear ();
RedirectsChanged ();
if (!inserts.empty()) {
inserts.clear ();
InsertsChanged ();
}
}
@ -154,16 +154,16 @@ Selection::clear_lines ()
}
void
Selection::toggle (boost::shared_ptr<Redirect> r)
Selection::toggle (boost::shared_ptr<Insert> r)
{
RedirectSelection::iterator i;
InsertSelection::iterator i;
if ((i = find (redirects.begin(), redirects.end(), r)) == redirects.end()) {
redirects.push_back (r);
if ((i = find (inserts.begin(), inserts.end(), r)) == inserts.end()) {
inserts.push_back (r);
} else {
redirects.erase (i);
inserts.erase (i);
}
RedirectsChanged();
InsertsChanged();
}
@ -254,11 +254,11 @@ Selection::toggle (nframes_t start, nframes_t end)
void
Selection::add (boost::shared_ptr<Redirect> r)
Selection::add (boost::shared_ptr<Insert> i)
{
if (find (redirects.begin(), redirects.end(), r) == redirects.end()) {
redirects.push_back (r);
RedirectsChanged();
if (find (inserts.begin(), inserts.end(), i) == inserts.end()) {
inserts.push_back (i);
InsertsChanged();
}
}
@ -395,12 +395,12 @@ Selection::add (AutomationList* ac)
}
void
Selection::remove (boost::shared_ptr<Redirect> r)
Selection::remove (boost::shared_ptr<Insert> r)
{
RedirectSelection::iterator i;
if ((i = find (redirects.begin(), redirects.end(), r)) != redirects.end()) {
redirects.erase (i);
RedirectsChanged ();
InsertSelection::iterator i;
if ((i = find (inserts.begin(), inserts.end(), r)) != inserts.end()) {
inserts.erase (i);
InsertsChanged ();
}
}
@ -510,10 +510,10 @@ Selection::remove (AutomationList *ac)
}
void
Selection::set (boost::shared_ptr<Redirect> r)
Selection::set (boost::shared_ptr<Insert> i)
{
clear_redirects ();
add (r);
clear_inserts ();
add (i);
}
void
@ -625,7 +625,7 @@ Selection::empty ()
lines.empty () &&
time.empty () &&
playlists.empty () &&
redirects.empty ()
inserts.empty ()
;
}

View file

@ -41,7 +41,7 @@ namespace ARDOUR {
class Region;
class AudioRegion;
class Playlist;
class Redirect;
class Insert;
class AutomationList;
}
@ -69,7 +69,7 @@ class Selection : public sigc::trackable
TimeSelection time;
AutomationSelection lines;
PlaylistSelection playlists;
RedirectSelection redirects;
InsertSelection inserts;
PointSelection points;
Selection() {
@ -84,7 +84,7 @@ class Selection : public sigc::trackable
sigc::signal<void> TimeChanged;
sigc::signal<void> LinesChanged;
sigc::signal<void> PlaylistsChanged;
sigc::signal<void> RedirectsChanged;
sigc::signal<void> InsertsChanged;
sigc::signal<void> PointsChanged;
void clear ();
@ -107,7 +107,7 @@ class Selection : public sigc::trackable
void set (ARDOUR::AutomationList*);
void set (boost::shared_ptr<ARDOUR::Playlist>);
void set (const std::list<boost::shared_ptr<ARDOUR::Playlist> >&);
void set (boost::shared_ptr<ARDOUR::Redirect>);
void set (boost::shared_ptr<ARDOUR::Insert>);
void set (AutomationSelectable*);
void toggle (TimeAxisView*);
@ -118,7 +118,7 @@ class Selection : public sigc::trackable
void toggle (ARDOUR::AutomationList*);
void toggle (boost::shared_ptr<ARDOUR::Playlist>);
void toggle (const std::list<boost::shared_ptr<ARDOUR::Playlist> >&);
void toggle (boost::shared_ptr<ARDOUR::Redirect>);
void toggle (boost::shared_ptr<ARDOUR::Insert>);
void toggle (const std::vector<AutomationSelectable*>&);
void add (TimeAxisView*);
@ -129,7 +129,7 @@ class Selection : public sigc::trackable
void add (ARDOUR::AutomationList*);
void add (boost::shared_ptr<ARDOUR::Playlist>);
void add (const std::list<boost::shared_ptr<ARDOUR::Playlist> >&);
void add (boost::shared_ptr<ARDOUR::Redirect>);
void add (boost::shared_ptr<ARDOUR::Insert>);
void remove (TimeAxisView*);
void remove (const std::list<TimeAxisView*>&);
@ -139,7 +139,7 @@ class Selection : public sigc::trackable
void remove (ARDOUR::AutomationList*);
void remove (boost::shared_ptr<ARDOUR::Playlist>);
void remove (const std::list<boost::shared_ptr<ARDOUR::Playlist> >&);
void remove (boost::shared_ptr<ARDOUR::Redirect>);
void remove (boost::shared_ptr<ARDOUR::Insert>);
void remove (const list<Selectable*>&);
void replace (uint32_t time_index, nframes_t start, nframes_t end);
@ -149,7 +149,7 @@ class Selection : public sigc::trackable
void clear_time();
void clear_lines ();
void clear_playlists ();
void clear_redirects ();
void clear_inserts ();
void clear_points ();
void foreach_region (void (ARDOUR::Region::*method)(void));

View file

@ -32,8 +32,8 @@ using namespace PBD;
SendUI::SendUI (boost::shared_ptr<Send> s, Session& se)
: _send (s),
_session (se),
gpm (s, se),
panners (s, se)
gpm (s->io(), se),
panners (s->io(), se)
{
hbox.pack_start (gpm, true, true);
set_name ("SendUIFrame");
@ -44,7 +44,7 @@ SendUI::SendUI (boost::shared_ptr<Send> s, Session& se)
vbox.pack_start (hbox, false, false, false);
vbox.pack_start (panners, false,false);
io = new IOSelector (se, s, false);
io = new IOSelector (se, s->io(), false);
pack_start (vbox, false, false);
@ -54,8 +54,8 @@ SendUI::SendUI (boost::shared_ptr<Send> s, Session& se)
_send->set_metering (true);
_send->output_changed.connect (mem_fun (*this, &SendUI::ins_changed));
_send->output_changed.connect (mem_fun (*this, &SendUI::outs_changed));
_send->io()->output_changed.connect (mem_fun (*this, &SendUI::ins_changed));
_send->io()->output_changed.connect (mem_fun (*this, &SendUI::outs_changed));
panners.set_width (Wide);
panners.setup_pan ();

View file

@ -74,6 +74,7 @@ gain.cc
gdither.cc
globals.cc
import.cc
automatable.cc
insert.cc
plugin_insert.cc
port_insert.cc

View file

@ -28,6 +28,8 @@ class BufferSet;
/** Applies a declick operation to all audio inputs, passing the same number of
* audio outputs, and passing through any other types unchanged.
*
* FIXME: make this an insert.
*/
class Amp {
public:

View file

@ -56,7 +56,8 @@ class AudioFileSource : public AudioSource {
virtual ~AudioFileSource ();
int set_name (Glib::ustring newname, bool destructive);
bool set_name (const std::string& newname) { return (set_source_name(newname, destructive()) == 0); }
int set_source_name (Glib::ustring newname, bool destructive);
Glib::ustring path() const { return _path; }
Glib::ustring peak_path (Glib::ustring audio_path);

View file

@ -0,0 +1,78 @@
/*
Copyright (C) 2000,2007 Paul Davis
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#ifndef __ardour_automatable_h__
#define __ardour_automatable_h__
#include <set>
#include <map>
#include <ardour/session_object.h>
#include <ardour/automation_event.h>
namespace ARDOUR {
class Session;
class Automatable : public SessionObject
{
public:
Automatable(Session&, const std::string& name);
virtual ~Automatable() {}
virtual AutomationList& automation_list(uint32_t n);
virtual void automation_snapshot (nframes_t now) {};
virtual bool find_next_event(nframes_t start, nframes_t end, ControlEvent& ev) const;
virtual string describe_parameter(uint32_t which);
virtual float default_parameter_value(uint32_t which) { return 1.0f; }
void what_has_automation(std::set<uint32_t>&) const;
void what_has_visible_automation(std::set<uint32_t>&) const;
const std::set<uint32_t>& what_can_be_automated() const { return _can_automate_list; }
void mark_automation_visible(uint32_t, bool);
protected:
void can_automate(uint32_t);
virtual void automation_list_creation_callback(uint32_t, AutomationList&) {}
int set_automation_state(const XMLNode&);
XMLNode& get_automation_state();
int load_automation (const std::string& path);
int old_set_automation_state(const XMLNode&);
mutable Glib::Mutex _automation_lock;
// FIXME: map with int keys is a bit silly. this could be O(1)
std::map<uint32_t,AutomationList*> _parameter_automation;
std::set<uint32_t> _visible_parameter_automation;
std::set<uint32_t> _can_automate_list;
nframes_t _last_automation_snapshot;
};
} // namespace ARDOUR
#endif /* __ardour_automatable_h__ */

View file

@ -114,10 +114,10 @@ class AutomationList : public PBD::StatefulDestructible
AutoStyle automation_style() const { return _style; }
sigc::signal<void> automation_state_changed;
bool automation_playback() {
bool automation_playback() const {
return (_state & Play) || ((_state & Touch) && !_touching);
}
bool automation_write () {
bool automation_write () const {
return (_state & Write) || ((_state & Touch) && _touching);
}

View file

@ -60,7 +60,7 @@ class Curve : public AutomationList
void solve ();
static sigc::signal<void, Curve*> CurveCreated;
static sigc::signal<void, Curve*> CurveCreated;
protected:
ControlEvent* point_factory (double,double) const;

View file

@ -53,7 +53,7 @@ class Session;
class Playlist;
class IO;
class Diskstream : public PBD::StatefulDestructible
class Diskstream : public SessionObject
{
public:
enum Flag {
@ -65,9 +65,8 @@ class Diskstream : public PBD::StatefulDestructible
Diskstream (Session &, const string& name, Flag f = Recordable);
Diskstream (Session &, const XMLNode&);
virtual ~Diskstream();
string name () const { return _name; }
virtual int set_name (string str);
bool set_name (const string& str);
ARDOUR::IO* io() const { return _io; }
void set_io (ARDOUR::IO& io);
@ -238,8 +237,6 @@ class Diskstream : public PBD::StatefulDestructible
uint32_t i_am_the_modifier;
string _name;
ARDOUR::Session& _session;
ARDOUR::IO* _io;
ChanCount _n_channels;

View file

@ -24,11 +24,16 @@
#include <string>
#include <exception>
#include <pbd/statefuldestructible.h>
#include <sigc++/signal.h>
#include <ardour/ardour.h>
#include <ardour/redirect.h>
#include <ardour/plugin_state.h>
#include <ardour/types.h>
#include <ardour/ardour.h>
#include <ardour/plugin_state.h>
#include <ardour/buffer_set.h>
#include <ardour/automatable.h>
class XMLNode;
@ -36,26 +41,71 @@ namespace ARDOUR {
class Session;
class Insert : public Redirect
/* A mixer strip element - plugin, send, meter, etc.
*/
class Insert : public Automatable
{
public:
Insert(Session& s, std::string name, Placement p);
Insert(Session& s, std::string name, Placement p, int imin, int imax, int omin, int omax);
static const string state_node_name;
Insert(Session&, const string& name, Placement p); // TODO: remove placement in favour of sort key
virtual ~Insert() { }
static boost::shared_ptr<Insert> clone (boost::shared_ptr<const Insert>);
uint32_t sort_key() const { return _sort_key; }
void set_sort_key (uint32_t key);
Placement placement() const { return _placement; }
void set_placement (Placement);
bool active () const { return _active; }
void set_active (bool yn);
bool get_next_ab_is_active () const { return _next_ab_is_active; }
void set_next_ab_is_active (bool yn) { _next_ab_is_active = yn; }
virtual nframes_t latency() { return 0; }
virtual void transport_stopped (nframes_t frame) {}
virtual void set_block_size (nframes_t nframes) {}
virtual void run (BufferSet& bufs, nframes_t start_frame, nframes_t end_frame, nframes_t nframes, nframes_t offset) = 0;
virtual void silence (nframes_t nframes, nframes_t offset) {}
virtual void activate () {}
virtual void deactivate () {}
virtual void activate () { _active = true; ActiveChanged.emit(); }
virtual void deactivate () { _active = false; ActiveChanged.emit(); }
virtual bool configure_io (ChanCount in, ChanCount out) { _configured_input = in; return (_configured = true); }
virtual bool can_support_input_configuration (ChanCount in) const = 0;
virtual ChanCount output_for_input_configuration (ChanCount in) const = 0;
virtual bool configure_io (ChanCount in, ChanCount out) = 0;
/* Act as a pass through, if not overridden */
virtual bool can_support_input_configuration (ChanCount in) const { return true; }
virtual ChanCount output_for_input_configuration (ChanCount in) const { return in; }
virtual ChanCount output_streams() const { return _configured_input; }
virtual ChanCount input_streams () const { return _configured_input; }
virtual XMLNode& state (bool full);
virtual XMLNode& get_state (void);
virtual int set_state (const XMLNode&);
void *get_gui () const { return _gui; }
void set_gui (void *p) { _gui = p; }
static sigc::signal<void,Insert*> InsertCreated;
sigc::signal<void> ActiveChanged;
sigc::signal<void> PlacementChanged;
protected:
bool _active;
bool _next_ab_is_active;
bool _configured;
ChanCount _configured_input;
Placement _placement;
uint32_t _sort_key;
void* _gui; /* generic, we don't know or care what this is */
};
} // namespace ARDOUR

View file

@ -34,6 +34,7 @@
#include <pbd/controllable.h>
#include <ardour/ardour.h>
#include <ardour/session_object.h>
#include <ardour/utils.h>
#include <ardour/curve.h>
#include <ardour/types.h>
@ -63,13 +64,13 @@ class BufferSet;
* An IO can contain ports of varying types, making routes/inserts/etc with
* varied combinations of types (eg MIDI and audio) possible.
*/
class IO : public PBD::StatefulDestructible
class IO : public SessionObject
{
public:
static const string state_node_name;
IO (Session&, string name,
IO (Session&, const string& name,
int input_min = -1, int input_max = -1,
int output_min = -1, int output_max = -1,
DataType default_type = DataType::AUDIO);
@ -90,10 +91,9 @@ class IO : public PBD::StatefulDestructible
DataType default_type() const { return _default_type; }
void set_default_type(DataType t) { _default_type = t; }
const string& name() const { return _name; }
virtual int set_name (string str, void *src);
bool set_name (const string& str);
virtual void silence (nframes_t, nframes_t offset);
void collect_input (BufferSet& bufs, nframes_t nframes, nframes_t offset);
@ -179,7 +179,6 @@ class IO : public PBD::StatefulDestructible
sigc::signal<void,IOChange,void*> output_changed;
sigc::signal<void,void*> gain_changed;
sigc::signal<void,void*> name_changed;
virtual XMLNode& state (bool full);
XMLNode& get_state (void);
@ -229,26 +228,16 @@ class IO : public PBD::StatefulDestructible
void clear_automation ();
bool gain_automation_recording() const {
return (_gain_automation_curve.automation_state() & (Write|Touch));
}
bool gain_automation_playback() const {
return (_gain_automation_curve.automation_state() & Play) ||
((_gain_automation_curve.automation_state() & Touch) &&
!_gain_automation_curve.touching());
}
virtual void set_gain_automation_state (AutoState);
AutoState gain_automation_state() const { return _gain_automation_curve.automation_state(); }
sigc::signal<void> gain_automation_state_changed;
//sigc::signal<void> gain_automation_state_changed;
virtual void set_gain_automation_style (AutoStyle);
AutoStyle gain_automation_style () const { return _gain_automation_curve.automation_style(); }
sigc::signal<void> gain_automation_style_changed;
//sigc::signal<void> gain_automation_style_changed;
virtual void transport_stopped (nframes_t now);
void automation_snapshot (nframes_t now);
virtual void transport_stopped (nframes_t now); // interface: matches Insert
void automation_snapshot (nframes_t now); // interface: matches Automatable
ARDOUR::Curve& gain_automation_curve () { return _gain_automation_curve; }
@ -272,7 +261,6 @@ class IO : public PBD::StatefulDestructible
mutable Glib::Mutex io_lock;
protected:
Session& _session;
Panner* _panner;
BufferSet* _output_buffers; //< Set directly to output port buffers
gain_t _gain;
@ -282,7 +270,6 @@ class IO : public PBD::StatefulDestructible
PortSet _outputs;
PortSet _inputs;
PeakMeter* _meter;
string _name;
Bundle* _input_bundle;
Bundle* _output_bundle;
bool no_panner_reset;
@ -336,6 +323,8 @@ class IO : public PBD::StatefulDestructible
private:
friend class Send;
/* are these the best variable names ever, or what? */
sigc::connection input_bundle_configuration_connection;

View file

@ -21,6 +21,7 @@
#include <vector>
#include <ardour/types.h>
#include <ardour/insert.h>
#include <pbd/fastlog.h>
namespace ARDOUR {
@ -32,16 +33,17 @@ class Session;
/** Meters peaks on the input and stores them for access.
*/
class PeakMeter {
class PeakMeter : public Insert {
public:
PeakMeter(Session& s) : _session(s) {}
PeakMeter(Session& s) : Insert(s, "meter", PreFader) {}
void setup (const ChanCount& in);
void reset ();
void reset_max ();
bool configure_io (ChanCount in, ChanCount out);
/** Compute peaks */
void run (BufferSet& bufs, nframes_t nframes, nframes_t offset=0);
void run (BufferSet& bufs, nframes_t start_frame, nframes_t end_frame, nframes_t nframes, nframes_t offset);
float peak_power (uint32_t n) {
if (n < _visible_peak_power.size()) {
@ -64,7 +66,6 @@ private:
friend class IO;
void meter();
Session& _session;
std::vector<float> _peak_power;
std::vector<float> _visible_peak_power;
std::vector<float> _max_peak_power;

View file

@ -37,8 +37,6 @@ public:
MidiTrack (Session&, const XMLNode&);
~MidiTrack ();
int set_name (string str, void *src);
int roll (nframes_t nframes, nframes_t start_frame, nframes_t end_frame,
nframes_t offset, int declick, bool can_record, bool rec_monitors_input);

View file

@ -38,6 +38,7 @@
#include <pbd/statefuldestructible.h>
#include <ardour/ardour.h>
#include <ardour/session_object.h>
#include <ardour/crossfade_compare.h>
#include <ardour/location.h>
#include <ardour/data_type.h>
@ -47,7 +48,7 @@ namespace ARDOUR {
class Session;
class Region;
class Playlist : public PBD::StatefulDestructible, public boost::enable_shared_from_this<Playlist> {
class Playlist : public SessionObject, public boost::enable_shared_from_this<Playlist> {
public:
typedef list<boost::shared_ptr<Region> > RegionList;
@ -67,8 +68,7 @@ class Playlist : public PBD::StatefulDestructible, public boost::enable_shared_f
void release();
bool used () const { return _refcnt != 0; }
std::string name() const { return _name; }
void set_name (std::string str);
bool set_name (const string& str);
const DataType& data_type() const { return _type; }
@ -130,8 +130,6 @@ class Playlist : public PBD::StatefulDestructible, public boost::enable_shared_f
uint32_t read_data_count() const { return _read_data_count; }
Session& session() { return _session; }
const PBD::ID& get_orig_diskstream_id () const { return _orig_diskstream_id; }
void set_orig_diskstream_id (const PBD::ID& did) { _orig_diskstream_id = did; }
@ -170,8 +168,6 @@ class Playlist : public PBD::StatefulDestructible, public boost::enable_shared_f
RegionList regions; /* the current list of regions in the playlist */
std::set<boost::shared_ptr<Region> > all_regions; /* all regions ever added to this playlist */
string _name;
Session& _session;
DataType _type;
mutable gint block_notifications;
mutable gint ignore_state_changes;

View file

@ -22,13 +22,13 @@
#include <vector>
#include <string>
#include <exception>
#include <sigc++/signal.h>
#include <ardour/ardour.h>
#include <ardour/plugin_state.h>
#include <ardour/types.h>
#include <ardour/insert.h>
#include <ardour/automation_event.h>
class XMLNode;
@ -105,7 +105,7 @@ class PluginInsert : public Insert
void parameter_changed (uint32_t, float);
vector<boost::shared_ptr<Plugin> > _plugins;
std::vector<boost::shared_ptr<Plugin> > _plugins;
void automation_run (BufferSet& bufs, nframes_t nframes, nframes_t offset);
void connect_and_run (BufferSet& bufs, nframes_t nframes, nframes_t offset, bool with_auto, nframes_t now = 0);

View file

@ -26,7 +26,7 @@
#include <sigc++/signal.h>
#include <ardour/ardour.h>
#include <ardour/insert.h>
#include <ardour/redirect.h>
#include <ardour/plugin_state.h>
#include <ardour/types.h>
@ -37,8 +37,10 @@ namespace ARDOUR {
class Session;
/** Port inserts: send output to a Jack port, pick up input at a Jack port
*
* PortInsert IS-A Redirect IS-A Insert, IO
*/
class PortInsert : public Insert
class PortInsert : public Redirect
{
public:
PortInsert (Session&, Placement);

View file

@ -32,6 +32,7 @@
#include <pbd/undo.h>
#include <ardour/ardour.h>
#include <ardour/insert.h>
#include <ardour/io.h>
#include <ardour/automation_event.h>
@ -46,97 +47,37 @@ namespace ARDOUR {
class Session;
class Redirect : public IO
/** A mixer strip element (Insert) with Jack ports (IO).
*/
class Redirect : public Insert
{
public:
static const string state_node_name;
Redirect (Session&, const string& name, Placement,
int input_min = -1, int input_max = -1, int output_min = -1, int output_max = -1);
Redirect (const Redirect&);
virtual ~Redirect ();
virtual ChanCount output_streams() const { return _io->n_outputs(); }
virtual ChanCount input_streams () const { return _io->n_inputs(); }
virtual ChanCount natural_output_streams() const { return _io->n_outputs(); }
virtual ChanCount natural_input_streams () const { return _io->n_inputs(); }
static boost::shared_ptr<Redirect> clone (boost::shared_ptr<const Redirect>);
bool active () const { return _active; }
void set_active (bool yn, void *src);
virtual ChanCount output_streams() const { return n_outputs(); }
virtual ChanCount input_streams () const { return n_inputs(); }
virtual ChanCount natural_output_streams() const { return n_outputs(); }
virtual ChanCount natural_input_streams () const { return n_inputs(); }
uint32_t sort_key() const { return _sort_key; }
void set_sort_key (uint32_t key);
Placement placement() const { return _placement; }
void set_placement (Placement, void *src);
boost::shared_ptr<IO> io() { return _io; }
boost::shared_ptr<const IO> io() const { return _io; }
virtual void automation_snapshot (nframes_t now) { _io->automation_snapshot(now); }
virtual void run (BufferSet& bufs, nframes_t start_frame, nframes_t end_frame, nframes_t nframes, nframes_t offset) = 0;
virtual void activate () = 0;
virtual void deactivate () = 0;
virtual nframes_t latency() { return 0; }
void silence (nframes_t nframes, nframes_t offset);
virtual void set_block_size (nframes_t nframes) {}
sigc::signal<void,Redirect*,void*> active_changed;
sigc::signal<void,Redirect*,void*> placement_changed;
sigc::signal<void,Redirect*,bool> AutomationPlaybackChanged;
sigc::signal<void,Redirect*,bool> AutomationPlaybackChanged;
sigc::signal<void,Redirect*,uint32_t> AutomationChanged;
static sigc::signal<void,Redirect*> RedirectCreated;
XMLNode& state (bool full);
XMLNode& get_state (void);
XMLNode& state (bool full_state);
int set_state (const XMLNode&);
void *get_gui () const { return _gui; }
void set_gui (void *p) { _gui = p; }
virtual string describe_parameter (uint32_t which);
virtual float default_parameter_value (uint32_t which) {
return 1.0f;
}
void what_has_automation (set<uint32_t>&) const;
void what_has_visible_automation (set<uint32_t>&) const;
const set<uint32_t>& what_can_be_automated () const { return can_automate_list; }
void mark_automation_visible (uint32_t, bool);
AutomationList& automation_list (uint32_t);
bool find_next_event (nframes_t, nframes_t, ControlEvent&) const;
virtual void transport_stopped (nframes_t frame) {};
bool get_next_ab_is_active () const { return _next_ab_is_active; }
void set_next_ab_is_active (bool yn);
protected:
/* children may use this stuff as they see fit */
map<uint32_t,AutomationList*> parameter_automation;
set<uint32_t> visible_parameter_automation;
mutable Glib::Mutex _automation_lock;
void can_automate (uint32_t);
set<uint32_t> can_automate_list;
virtual void automation_list_creation_callback (uint32_t, AutomationList&) {}
int set_automation_state (const XMLNode&);
XMLNode& get_automation_state ();
private:
bool _active;
bool _next_ab_is_active;
Placement _placement;
uint32_t _sort_key;
void* _gui; /* generic, we don't know or care what this is */
int old_set_automation_state (const XMLNode&);
int load_automation (std::string path);
boost::shared_ptr<IO> _io;
};
} // namespace ARDOUR

View file

@ -59,7 +59,8 @@ class Route : public IO
{
protected:
typedef list<boost::shared_ptr<Redirect> > RedirectList;
typedef list<boost::shared_ptr<Insert> > InsertList;
public:
enum Flag {
@ -99,7 +100,7 @@ class Route : public IO
virtual bool can_record() { return false; }
virtual void set_record_enable (bool yn, void *src) {}
virtual bool record_enabled() const { return false; }
virtual void handle_transport_stopped (bool abort, bool did_locate, bool flush_redirects);
virtual void handle_transport_stopped (bool abort, bool did_locate, bool flush_inserts);
virtual void set_pending_declick (int);
/* end of vfunc-based API */
@ -136,54 +137,54 @@ class Route : public IO
virtual void set_meter_point (MeterPoint, void *src);
MeterPoint meter_point() const { return _meter_point; }
/* Redirects */
/* Inserts */
void flush_redirects ();
void flush_inserts ();
template<class T> void foreach_redirect (T *obj, void (T::*func)(boost::shared_ptr<Redirect>)) {
Glib::RWLock::ReaderLock lm (redirect_lock);
for (RedirectList::iterator i = _redirects.begin(); i != _redirects.end(); ++i) {
template<class T> void foreach_insert (T *obj, void (T::*func)(boost::shared_ptr<Insert>)) {
Glib::RWLock::ReaderLock lm (insert_lock);
for (InsertList::iterator i = _inserts.begin(); i != _inserts.end(); ++i) {
(obj->*func) (*i);
}
}
boost::shared_ptr<Redirect> nth_redirect (uint32_t n) {
Glib::RWLock::ReaderLock lm (redirect_lock);
RedirectList::iterator i;
for (i = _redirects.begin(); i != _redirects.end() && n; ++i, --n);
if (i == _redirects.end()) {
boost::shared_ptr<Insert> nth_insert (uint32_t n) {
Glib::RWLock::ReaderLock lm (insert_lock);
InsertList::iterator i;
for (i = _inserts.begin(); i != _inserts.end() && n; ++i, --n);
if (i == _inserts.end()) {
return boost::shared_ptr<Redirect> ();
} else {
return *i;
}
}
ChanCount max_redirect_outs () const { return redirect_max_outs; }
ChanCount max_insert_outs () const { return insert_max_outs; }
ChanCount pre_fader_streams() const;
/** A record of the stream configuration at some point in the redirect list.
* Used to return where and why a redirect list configuration request failed.
/** A record of the stream configuration at some point in the insert list.
* Used to return where and why an insert list configuration request failed.
*/
struct InsertStreams {
InsertStreams(size_t i=0, ChanCount c=ChanCount()) : index(i), count(c) {}
size_t index; ///< Index of redirect where configuration failed
ChanCount count; ///< Input requested of redirect
size_t index; ///< Index of insert where configuration failed
ChanCount count; ///< Input requested of insert
};
int add_redirect (boost::shared_ptr<Redirect>, void *src, InsertStreams* err = 0);
int add_redirects (const RedirectList&, void *src, InsertStreams* err = 0);
int remove_redirect (boost::shared_ptr<Redirect>, void *src, InsertStreams* err = 0);
int copy_redirects (const Route&, Placement, InsertStreams* err = 0);
int sort_redirects (InsertStreams* err = 0);
void disable_redirects (Placement);
void disable_redirects ();
int add_insert (boost::shared_ptr<Insert>, InsertStreams* err = 0);
int add_inserts (const InsertList&, InsertStreams* err = 0);
int remove_insert (boost::shared_ptr<Insert>, InsertStreams* err = 0);
int copy_inserts (const Route&, Placement, InsertStreams* err = 0);
int sort_inserts (InsertStreams* err = 0);
void disable_inserts (Placement);
void disable_inserts ();
void disable_plugins (Placement);
void disable_plugins ();
void ab_plugins (bool forward);
void clear_redirects (Placement, void *src);
void all_redirects_flip();
void all_redirects_active (Placement, bool state);
void clear_inserts (Placement);
void all_inserts_flip();
void all_inserts_active (Placement, bool state);
virtual nframes_t update_total_latency();
nframes_t signal_latency() const { return _own_latency; }
@ -197,7 +198,7 @@ class Route : public IO
sigc::signal<void,void*> post_fader_changed;
sigc::signal<void,void*> control_outs_changed;
sigc::signal<void,void*> main_outs_changed;
sigc::signal<void,void*> redirects_changed;
sigc::signal<void> inserts_changed;
sigc::signal<void,void*> record_enable_changed;
sigc::signal<void,void*> edit_group_changed;
sigc::signal<void,void*> mix_group_changed;
@ -214,8 +215,8 @@ class Route : public IO
int set_state(const XMLNode& node);
virtual XMLNode& get_template();
XMLNode& get_redirect_state ();
int set_redirect_state (const XMLNode&);
XMLNode& get_insert_state ();
int set_insert_state (const XMLNode&);
sigc::signal<void,void*> SelectedChanged;
@ -294,8 +295,8 @@ class Route : public IO
nframes_t _initial_delay;
nframes_t _roll_delay;
nframes_t _own_latency;
RedirectList _redirects;
Glib::RWLock redirect_lock;
InsertList _inserts;
Glib::RWLock insert_lock;
IO *_control_outs;
Glib::Mutex control_outs_lock;
RouteGroup *_edit_group;
@ -311,7 +312,7 @@ class Route : public IO
virtual void process_output_buffers (BufferSet& bufs,
nframes_t start_frame, nframes_t end_frame,
nframes_t nframes, nframes_t offset, bool with_redirects, int declick,
nframes_t nframes, nframes_t offset, bool with_inserts, int declick,
bool meter);
protected:
@ -326,14 +327,14 @@ class Route : public IO
sigc::connection input_signal_connection;
ChanCount redirect_max_outs;
ChanCount insert_max_outs;
uint32_t _remote_control_id;
uint32_t pans_required() const;
ChanCount n_process_buffers ();
virtual int _set_state (const XMLNode&, bool call_base);
virtual void _set_redirect_states (const XMLNodeList&);
virtual void _set_insert_states (const XMLNodeList&);
private:
void init ();
@ -354,7 +355,6 @@ class Route : public IO
void input_change_handler (IOChange, void *src);
void output_change_handler (IOChange, void *src);
bool legal_redirect (Redirect&);
int reset_plugin_counts (InsertStreams*); /* locked */
int _reset_plugin_counts (InsertStreams*); /* unlocked */
@ -372,8 +372,7 @@ class Route : public IO
bool check_some_plugin_counts (std::list<InsertCount>& iclist, ChanCount required_inputs, InsertStreams* err_streams);
void set_deferred_state ();
void add_redirect_from_xml (const XMLNode&);
void redirect_active_proxy (Redirect*, void*);
void add_insert_from_xml (const XMLNode&);
};
} // namespace ARDOUR

View file

@ -42,6 +42,9 @@ class Send : public Redirect
uint32_t bit_slot() const { return bitslot; }
ChanCount output_streams() const;
ChanCount input_streams () const;
void run (BufferSet& bufs, nframes_t start_frame, nframes_t end_frame, nframes_t nframes, nframes_t offset);
void activate() {}
@ -54,7 +57,10 @@ class Send : public Redirect
int set_state(const XMLNode& node);
uint32_t pans_required() const { return _expected_inputs.n_audio(); }
void expect_inputs (const ChanCount&);
virtual bool can_support_input_configuration (ChanCount in) const;
virtual ChanCount output_for_input_configuration (ChanCount in) const;
virtual bool configure_io (ChanCount in, ChanCount out);
static uint32_t how_many_sends();

View file

@ -1374,7 +1374,7 @@ class Session : public PBD::StatefulDestructible
void set_play_loop (bool yn);
void overwrite_some_buffers (Diskstream*);
void flush_all_redirects ();
void flush_all_inserts ();
void locate (nframes_t, bool with_roll, bool with_flush, bool with_loop=false);
void start_locate (nframes_t, bool with_roll, bool with_flush, bool with_loop=false);
void force_locate (nframes_t frame, bool with_roll = false);
@ -1521,8 +1521,8 @@ class Session : public PBD::StatefulDestructible
uint32_t insert_cnt;
void add_redirect (Redirect *);
void remove_redirect (Redirect *);
void add_insert (Insert *);
void remove_insert (Insert *);
/* S/W RAID */

View file

@ -61,7 +61,8 @@ class SMFSource : public MidiSource {
virtual void mark_capture_end () {}
virtual void clear_capture_marks() {}
int set_name (string newname, bool destructive);
bool set_name (const std::string& newname) { return (set_source_name(newname, false) == 0); }
int set_source_name (string newname, bool destructive);
string path() const { return _path; }

View file

@ -28,6 +28,7 @@
#include <pbd/statefuldestructible.h>
#include <ardour/ardour.h>
#include <ardour/session_object.h>
#include <ardour/data_type.h>
namespace ARDOUR {
@ -35,17 +36,14 @@ namespace ARDOUR {
class Session;
class Playlist;
class Source : public PBD::StatefulDestructible
class Source : public SessionObject
{
public:
Source (Session&, std::string name, DataType type);
Source (Session&, const std::string& name, DataType type);
Source (Session&, const XMLNode&);
virtual ~Source ();
std::string name() const { return _name; }
int set_name (std::string str, bool destructive);
DataType type() { return _type; }
time_t timestamp() const { return _timestamp; }
@ -76,8 +74,6 @@ class Source : public PBD::StatefulDestructible
protected:
void update_length (nframes_t pos, nframes_t cnt);
Session& _session;
string _name;
DataType _type;
time_t _timestamp;
nframes_t _length;

View file

@ -37,7 +37,7 @@ class Track : public Route
virtual ~Track ();
int set_name (string str, void *src);
bool set_name (const std::string& str);
TrackMode mode () const { return _mode; }
virtual int set_mode (TrackMode m) { return false; }

View file

@ -2024,7 +2024,7 @@ AudioDiskstream::rename_write_sources ()
for (chan = c->begin(), n = 0; chan != c->end(); ++chan, ++n) {
if ((*chan)->write_source != 0) {
(*chan)->write_source->set_name (_name, destructive());
(*chan)->write_source->set_source_name (_name, destructive());
/* XXX what to do if one of them fails ? */
}
}

View file

@ -515,7 +515,7 @@ AudioTrack::roll (nframes_t nframes, nframes_t start_frame, nframes_t end_frame,
boost::shared_ptr<AudioDiskstream> diskstream = audio_diskstream();
{
Glib::RWLock::ReaderLock lm (redirect_lock, Glib::TRY_LOCK);
Glib::RWLock::ReaderLock lm (insert_lock, Glib::TRY_LOCK);
if (lm.locked()) {
// automation snapshot can also be called from the non-rt context
// and it uses the redirect list, so we take the lock out here
@ -524,7 +524,7 @@ AudioTrack::roll (nframes_t nframes, nframes_t start_frame, nframes_t end_frame,
}
if (n_outputs().n_total() == 0 && _redirects.empty()) {
if (n_outputs().n_total() == 0 && _inserts.empty()) {
return 0;
}
@ -601,7 +601,7 @@ AudioTrack::roll (nframes_t nframes, nframes_t start_frame, nframes_t end_frame,
if (!diskstream->record_enabled() && _session.transport_rolling()) {
Glib::Mutex::Lock am (automation_lock, Glib::TRY_LOCK);
if (am.locked() && gain_automation_playback()) {
if (am.locked() && _gain_automation_curve.automation_playback()) {
apply_gain_automation = _gain_automation_curve.rt_safe_get_vector (start_frame, end_frame, _session.gain_automation_buffer(), nframes);
}
}
@ -620,7 +620,7 @@ int
AudioTrack::silent_roll (nframes_t nframes, nframes_t start_frame, nframes_t end_frame, nframes_t offset,
bool can_record, bool rec_monitors_input)
{
if (n_outputs().n_total() == 0 && _redirects.empty()) {
if (n_outputs().n_total() == 0 && _inserts.empty()) {
return 0;
}
@ -643,12 +643,12 @@ AudioTrack::export_stuff (BufferSet& buffers, nframes_t start, nframes_t nframes
gain_t gain_automation[nframes];
gain_t gain_buffer[nframes];
float mix_buffer[nframes];
RedirectList::iterator i;
InsertList::iterator i;
bool post_fader_work = false;
gain_t this_gain = _gain;
boost::shared_ptr<AudioDiskstream> diskstream = audio_diskstream();
Glib::RWLock::ReaderLock rlock (redirect_lock);
Glib::RWLock::ReaderLock rlock (insert_lock);
boost::shared_ptr<AudioPlaylist> apl = boost::dynamic_pointer_cast<AudioPlaylist>(diskstream->playlist());
assert(apl);
@ -681,7 +681,7 @@ AudioTrack::export_stuff (BufferSet& buffers, nframes_t start, nframes_t nframes
will already have checked that there are no external port inserts.
*/
for (i = _redirects.begin(); i != _redirects.end(); ++i) {
for (i = _inserts.begin(); i != _inserts.end(); ++i) {
boost::shared_ptr<Insert> insert;
if ((insert = boost::dynamic_pointer_cast<Insert>(*i)) != 0) {
@ -719,7 +719,7 @@ AudioTrack::export_stuff (BufferSet& buffers, nframes_t start, nframes_t nframes
if (post_fader_work) {
for (i = _redirects.begin(); i != _redirects.end(); ++i) {
for (i = _inserts.begin(); i != _inserts.end(); ++i) {
boost::shared_ptr<PluginInsert> insert;
if ((insert = boost::dynamic_pointer_cast<PluginInsert>(*i)) != 0) {
@ -800,9 +800,9 @@ AudioTrack::freeze (InterThreadInfo& itt)
_freeze_record.have_mementos = true;
{
Glib::RWLock::ReaderLock lm (redirect_lock);
Glib::RWLock::ReaderLock lm (insert_lock);
for (RedirectList::iterator r = _redirects.begin(); r != _redirects.end(); ++r) {
for (InsertList::iterator r = _inserts.begin(); r != _inserts.end(); ++r) {
boost::shared_ptr<Insert> insert;
@ -816,7 +816,8 @@ AudioTrack::freeze (InterThreadInfo& itt)
/* now deactivate the insert */
insert->set_active (false, this);
insert->set_active (false);
_session.set_dirty ();
}
}
}
@ -857,8 +858,8 @@ AudioTrack::unfreeze ()
} else {
Glib::RWLock::ReaderLock lm (redirect_lock); // should this be a write lock? jlc
for (RedirectList::iterator i = _redirects.begin(); i != _redirects.end(); ++i) {
Glib::RWLock::ReaderLock lm (insert_lock); // should this be a write lock? jlc
for (InsertList::iterator i = _inserts.begin(); i != _inserts.end(); ++i) {
for (vector<FreezeRecordInsertInfo*>::iterator ii = _freeze_record.insert_info.begin(); ii != _freeze_record.insert_info.end(); ++ii) {
if ((*ii)->id == (*i)->id()) {
(*i)->set_state (((*ii)->state));

View file

@ -573,7 +573,7 @@ AudioFileSource::set_allow_remove_if_empty (bool yn)
}
int
AudioFileSource::set_name (ustring newname, bool destructive)
AudioFileSource::set_source_name (ustring newname, bool destructive)
{
Glib::Mutex::Lock lm (_lock);
ustring oldpath = _path;

267
libs/ardour/automatable.cc Normal file
View file

@ -0,0 +1,267 @@
/*
Copyright (C) 2001,2007 Paul Davis
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include <ardour/ardour.h>
#include <fstream>
#include <inttypes.h>
#include <cstdio>
#include <errno.h>
#include <pbd/error.h>
#include <pbd/enumwriter.h>
#include <ardour/session.h>
#include <ardour/automatable.h>
#include "i18n.h"
using namespace std;
using namespace ARDOUR;
using namespace PBD;
Automatable::Automatable(Session& _session, const string& name)
: SessionObject(_session, name)
, _last_automation_snapshot(0)
{}
int
Automatable::old_set_automation_state (const XMLNode& node)
{
const XMLProperty *prop;
if ((prop = node.property ("path")) != 0) {
load_automation (prop->value());
} else {
warning << string_compose(_("%1: Automation node has no path property"), _name) << endmsg;
}
if ((prop = node.property ("visible")) != 0) {
uint32_t what;
stringstream sstr;
_visible_parameter_automation.clear ();
sstr << prop->value();
while (1) {
sstr >> what;
if (sstr.fail()) {
break;
}
mark_automation_visible (what, true);
}
}
return 0;
}
int
Automatable::load_automation (const string& path)
{
string fullpath;
if (path[0] == '/') { // legacy
fullpath = path;
} else {
fullpath = _session.automation_dir();
fullpath += path;
}
ifstream in (fullpath.c_str());
if (!in) {
warning << string_compose(_("%1: cannot open %2 to load automation data (%3)"), _name, fullpath, strerror (errno)) << endmsg;
return 1;
}
Glib::Mutex::Lock lm (_automation_lock);
set<uint32_t> tosave;
_parameter_automation.clear ();
while (in) {
double when;
double value;
uint32_t port;
in >> port; if (!in) break;
in >> when; if (!in) goto bad;
in >> value; if (!in) goto bad;
AutomationList& al = automation_list (port);
al.add (when, value);
tosave.insert (port);
}
return 0;
bad:
error << string_compose(_("%1: cannot load automation data from %2"), _name, fullpath) << endmsg;
_parameter_automation.clear ();
return -1;
}
void
Automatable::what_has_automation (set<uint32_t>& s) const
{
Glib::Mutex::Lock lm (_automation_lock);
map<uint32_t,AutomationList*>::const_iterator li;
for (li = _parameter_automation.begin(); li != _parameter_automation.end(); ++li) {
s.insert ((*li).first);
}
}
void
Automatable::what_has_visible_automation (set<uint32_t>& s) const
{
Glib::Mutex::Lock lm (_automation_lock);
set<uint32_t>::const_iterator li;
for (li = _visible_parameter_automation.begin(); li != _visible_parameter_automation.end(); ++li) {
s.insert (*li);
}
}
AutomationList&
Automatable::automation_list (uint32_t parameter)
{
AutomationList* al = _parameter_automation[parameter];
if (al == 0) {
al = _parameter_automation[parameter] = new AutomationList (default_parameter_value (parameter));
/* let derived classes do whatever they need with this */
automation_list_creation_callback (parameter, *al);
}
return *al;
}
string
Automatable::describe_parameter (uint32_t which)
{
/* derived classes will override this */
return "";
}
void
Automatable::can_automate (uint32_t what)
{
_can_automate_list.insert (what);
}
void
Automatable::mark_automation_visible (uint32_t what, bool yn)
{
if (yn) {
_visible_parameter_automation.insert (what);
} else {
set<uint32_t>::iterator i;
if ((i = _visible_parameter_automation.find (what)) != _visible_parameter_automation.end()) {
_visible_parameter_automation.erase (i);
}
}
}
bool
Automatable::find_next_event (nframes_t now, nframes_t end, ControlEvent& next_event) const
{
map<uint32_t,AutomationList*>::const_iterator li;
AutomationList::TimeComparator cmp;
next_event.when = max_frames;
for (li = _parameter_automation.begin(); li != _parameter_automation.end(); ++li) {
AutomationList::const_iterator i;
const AutomationList& alist (*((*li).second));
ControlEvent cp (now, 0.0f);
for (i = lower_bound (alist.const_begin(), alist.const_end(), &cp, cmp); i != alist.const_end() && (*i)->when < end; ++i) {
if ((*i)->when > now) {
break;
}
}
if (i != alist.const_end() && (*i)->when < end) {
if ((*i)->when < next_event.when) {
next_event.when = (*i)->when;
}
}
}
return next_event.when != max_frames;
}
int
Automatable::set_automation_state (const XMLNode& node)
{
Glib::Mutex::Lock lm (_automation_lock);
_parameter_automation.clear ();
XMLNodeList nlist = node.children();
XMLNodeIterator niter;
for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
uint32_t param;
if (sscanf ((*niter)->name().c_str(), "parameter-%" PRIu32, &param) != 1) {
error << string_compose (_("%2: badly formatted node name in XML automation state, ignored"), _name) << endmsg;
continue;
}
AutomationList& al = automation_list (param);
if (al.set_state (*(*niter)->children().front())) {
goto bad;
}
}
return 0;
bad:
error << string_compose(_("%1: cannot load automation data from XML"), _name) << endmsg;
_parameter_automation.clear ();
return -1;
}
XMLNode&
Automatable::get_automation_state ()
{
Glib::Mutex::Lock lm (_automation_lock);
XMLNode* node = new XMLNode (X_("Automation"));
string fullpath;
if (_parameter_automation.empty()) {
return *node;
}
map<uint32_t,AutomationList*>::iterator li;
for (li = _parameter_automation.begin(); li != _parameter_automation.end(); ++li) {
XMLNode* child;
char buf[64];
stringstream str;
snprintf (buf, sizeof (buf), "parameter-%" PRIu32, li->first);
child = new XMLNode (buf);
child->add_child_nocopy (li->second->get_state ());
}
return *node;
}

View file

@ -67,14 +67,13 @@ sigc::signal<void> Diskstream::DiskOverrun;
sigc::signal<void> Diskstream::DiskUnderrun;
Diskstream::Diskstream (Session &sess, const string &name, Flag flag)
: _name (name)
, _session (sess)
: SessionObject(sess, name)
{
init (flag);
}
Diskstream::Diskstream (Session& sess, const XMLNode& node)
: _session (sess)
: SessionObject(sess, "unnamed diskstream")
{
init (Recordable);
}
@ -377,23 +376,24 @@ Diskstream::playlist_deleted (boost::weak_ptr<Playlist> wpl)
}
}
int
Diskstream::set_name (string str)
bool
Diskstream::set_name (const string& str)
{
if (str != _name) {
assert(playlist());
playlist()->set_name (str);
_name = str;
SessionObject::set_name(str);
if (!in_set_state && recordable()) {
/* rename existing capture files so that they have the correct name */
return rename_write_sources ();
} else {
return -1;
return false;
}
}
return 0;
return true;
}
void

View file

@ -22,6 +22,7 @@
#include <sigc++/bind.h>
#include <pbd/failed_constructor.h>
#include <pbd/enumwriter.h>
#include <pbd/xml++.h>
#include <ardour/insert.h>
@ -30,6 +31,9 @@
#include <ardour/route.h>
#include <ardour/ladspa_plugin.h>
#include <ardour/buffer_set.h>
#include <ardour/send.h>
#include <ardour/port_insert.h>
#include <ardour/plugin_insert.h>
#ifdef VST_SUPPORT
#include <ardour/vst_plugin.h>
@ -49,17 +53,214 @@ using namespace std;
using namespace ARDOUR;
using namespace PBD;
Insert::Insert(Session& s, string name, Placement p)
: Redirect (s, name, p)
sigc::signal<void,Insert*> Insert::InsertCreated;
// Always saved as Insert, but may be Redirect in legacy sessions
const string Insert::state_node_name = "Insert";
Insert::Insert(Session& session, const string& name, Placement p)
: Automatable(session, name)
, _active(false)
, _next_ab_is_active(false)
, _configured(false)
, _placement(p)
, _gui(0)
{
// FIXME: default type?
}
Insert::Insert(Session& s, string name, Placement p, int imin, int imax, int omin, int omax)
: Redirect (s, name, p, imin, imax, omin, omax)
, _configured(false)
boost::shared_ptr<Insert>
Insert::clone (boost::shared_ptr<const Insert> other)
{
// FIXME: default type?
boost::shared_ptr<const Send> send;
boost::shared_ptr<const PortInsert> port_insert;
boost::shared_ptr<const PluginInsert> plugin_insert;
if ((send = boost::dynamic_pointer_cast<const Send>(other)) != 0) {
return boost::shared_ptr<Insert> (new Send (*send));
} else if ((port_insert = boost::dynamic_pointer_cast<const PortInsert>(other)) != 0) {
return boost::shared_ptr<Insert> (new PortInsert (*port_insert));
} else if ((plugin_insert = boost::dynamic_pointer_cast<const PluginInsert>(other)) != 0) {
return boost::shared_ptr<Insert> (new PluginInsert (*plugin_insert));
} else {
fatal << _("programming error: unknown Insert type in Insert::Clone!\n")
<< endmsg;
/*NOTREACHED*/
}
return boost::shared_ptr<Insert>();
}
void
Insert::set_sort_key (uint32_t key)
{
_sort_key = key;
}
void
Insert::set_placement (Placement p)
{
if (_placement != p) {
_placement = p;
PlacementChanged (); /* EMIT SIGNAL */
}
}
void
Insert::set_active (bool yn)
{
_active = yn;
ActiveChanged ();
}
XMLNode&
Insert::get_state (void)
{
return state (true);
}
/* NODE STRUCTURE
<Automation [optionally with visible="...." ]>
<parameter-N>
<AutomationList id=N>
<events>
X1 Y1
X2 Y2
....
</events>
</parameter-N>
<Automation>
*/
XMLNode&
Insert::state (bool full_state)
{
XMLNode* node = new XMLNode (state_node_name);
stringstream sstr;
// FIXME: This conflicts with "id" used by plugin for name in legacy sessions (ugh).
// Do we need to serialize this?
/*
char buf[64];
id().print (buf, sizeof (buf));
node->add_property("id", buf);
*/
node->add_property("name", _name);
node->add_property("active", active() ? "yes" : "no");
node->add_property("placement", enum_2_string (_placement));
if (_extra_xml){
node->add_child_copy (*_extra_xml);
}
if (full_state) {
XMLNode& automation = Automatable::get_automation_state();
for (set<uint32_t>::iterator x = _visible_parameter_automation.begin(); x != _visible_parameter_automation.end(); ++x) {
if (x != _visible_parameter_automation.begin()) {
sstr << ' ';
}
sstr << *x;
}
automation.add_property ("visible", sstr.str());
node->add_child_nocopy (automation);
}
return *node;
}
int
Insert::set_state (const XMLNode& node)
{
const XMLProperty *prop;
if (node.name() != state_node_name) {
error << string_compose(_("incorrect XML node \"%1\" passed to Redirect object"), node.name()) << endmsg;
return -1;
}
if ((prop = node.property ("name")) == 0) {
warning << _("XML node describing an insert is missing the `name' field") << endmsg;
} else {
set_name(prop->value());
}
XMLNodeList nlist = node.children();
XMLNodeIterator niter;
bool have_io = false;
for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
if ((*niter)->name() == X_("Automation")) {
XMLProperty *prop;
if ((prop = (*niter)->property ("path")) != 0) {
old_set_automation_state (*(*niter));
} else {
Automatable::set_automation_state (*(*niter));
}
if ((prop = (*niter)->property ("visible")) != 0) {
uint32_t what;
stringstream sstr;
_visible_parameter_automation.clear ();
sstr << prop->value();
while (1) {
sstr >> what;
if (sstr.fail()) {
break;
}
mark_automation_visible (what, true);
}
}
} else if ((*niter)->name() == "extra") {
_extra_xml = new XMLNode (*(*niter));
}
}
if (!have_io && dynamic_cast<IO*>(this)) {
error << _("XML node describing a redirect is missing an IO node") << endmsg;
return -1;
}
if ((prop = node.property ("active")) == 0) {
error << _("XML node describing an insert is missing the `active' field") << endmsg;
return -1;
}
if (_active != (prop->value() == "yes")) {
_active = !_active;
ActiveChanged (); /* EMIT_SIGNAL */
}
if ((prop = node.property ("placement")) == 0) {
error << _("XML node describing an insert is missing the `placement' field") << endmsg;
return -1;
}
/* hack to handle older sessions before we only used EnumWriter */
string pstr;
if (prop->value() == "pre") {
pstr = "PreFader";
} else if (prop->value() == "post") {
pstr = "PostFader";
} else {
pstr = prop->value();
}
Placement p = Placement (string_2_enum (pstr, p));
set_placement (p);
return 0;
}

View file

@ -98,12 +98,11 @@ static double direct_gain_to_control (gain_t gain) {
/** @param default_type The type of port that will be created by ensure_io
* and friends if no type is explicitly requested (to avoid breakage).
*/
IO::IO (Session& s, string name,
IO::IO (Session& s, const string& name,
int input_min, int input_max, int output_min, int output_max,
DataType default_type)
: _session (s),
: SessionObject(s, name),
_output_buffers(new BufferSet()),
_name (name),
_default_type(default_type),
_gain_control (X_("gaincontrol"), *this),
_gain_automation_curve (0.0, 2.0, 1.0),
@ -158,7 +157,7 @@ IO::IO (Session& s, string name,
}
IO::IO (Session& s, const XMLNode& node, DataType dt)
: _session (s),
: SessionObject(s, "unnamed io"),
_output_buffers(new BufferSet()),
_default_type (dt),
_gain_control (X_("gaincontrol"), *this),
@ -324,7 +323,7 @@ IO::just_meter_input (nframes_t start_frame, nframes_t end_frame,
collect_input (bufs, nframes, offset);
_meter->run(bufs, nframes);
_meter->run(bufs, start_frame, end_frame, nframes, offset);
}
void
@ -1130,7 +1129,7 @@ IO::ensure_outputs (ChanCount count, bool clear, bool lockit, void* src)
gain_t
IO::effective_gain () const
{
if (gain_automation_playback()) {
if (_gain_automation_curve.automation_playback()) {
return _effective_gain;
} else {
return _desired_gain;
@ -1826,14 +1825,15 @@ IO::parse_gain_string (const string& str, vector<string>& ports)
return ports.size();
}
int
IO::set_name (string name, void* src)
bool
IO::set_name (const string& str)
{
if (name == _name) {
return 0;
if (str == _name) {
return true;
}
/* replace all colons in the name. i wish we didn't have to do this */
string name = str;
if (replace_all (name, ":", "-")) {
warning << _("you cannot use colons to name objects with I/O connections") << endmsg;
@ -1851,10 +1851,7 @@ IO::set_name (string name, void* src)
i->set_name (current_name);
}
_name = name;
name_changed (src); /* EMIT SIGNAL */
return 0;
return SessionObject::set_name(name);
}
void
@ -2169,7 +2166,8 @@ IO::GainControllable::get_value (void) const
void
IO::setup_peak_meters()
{
_meter->setup(std::max(_inputs.count(), _outputs.count()));
ChanCount max_streams = std::max(_inputs.count(), _outputs.count());
_meter->configure_io(max_streams, max_streams);
}
/**
@ -2226,28 +2224,17 @@ IO::set_gain_automation_state (AutoState state)
if (changed) {
_session.set_dirty ();
gain_automation_state_changed (); /* EMIT SIGNAL */
//gain_automation_state_changed (); /* EMIT SIGNAL */
}
}
void
IO::set_gain_automation_style (AutoStyle style)
{
bool changed = false;
{
Glib::Mutex::Lock lm (automation_lock);
if (style != _gain_automation_curve.automation_style()) {
changed = true;
_gain_automation_curve.set_automation_style (style);
}
}
if (changed) {
gain_automation_style_changed (); /* EMIT SIGNAL */
}
Glib::Mutex::Lock lm (automation_lock);
_gain_automation_curve.set_automation_style (style);
}
void
IO::inc_gain (gain_t factor, void *src)
{
@ -2276,7 +2263,7 @@ IO::set_gain (gain_t val, void *src)
gain_changed (src);
_gain_control.Changed (); /* EMIT SIGNAL */
if (_session.transport_stopped() && src != 0 && src != this && gain_automation_recording()) {
if (_session.transport_stopped() && src != 0 && src != this && _gain_automation_curve.automation_write()) {
_gain_automation_curve.add (_session.transport_frame(), val);
}
@ -2318,7 +2305,7 @@ IO::automation_snapshot (nframes_t now)
{
if (last_automation_snapshot > now || (now - last_automation_snapshot) > _automation_interval) {
if (gain_automation_recording()) {
if (_gain_automation_curve.automation_write()) {
_gain_automation_curve.rt_add (now, gain());
}

View file

@ -34,7 +34,7 @@ namespace ARDOUR {
* be set to 0.
*/
void
PeakMeter::run (BufferSet& bufs, nframes_t nframes, nframes_t offset)
PeakMeter::run (BufferSet& bufs, nframes_t start_frame, nframes_t end_frame, nframes_t nframes, nframes_t offset)
{
size_t meterable = std::min(bufs.count().n_total(), _peak_power.size());
@ -93,9 +93,13 @@ PeakMeter::reset_max ()
}
}
void
PeakMeter::setup (const ChanCount& in)
bool
PeakMeter::configure_io (ChanCount in, ChanCount out)
{
/* we're transparent no matter what. fight the power. */
if (out != in)
return false;
uint32_t limit = in.n_total();
while (_peak_power.size() > limit) {
@ -113,6 +117,10 @@ PeakMeter::setup (const ChanCount& in)
assert(_peak_power.size() == limit);
assert(_visible_peak_power.size() == limit);
assert(_max_peak_power.size() == limit);
Insert::configure_io(in, out);
return true;
}
/** To be driven by the Meter signal from IO.

View file

@ -1391,7 +1391,7 @@ int
MidiDiskstream::rename_write_sources ()
{
if (_write_source != 0) {
_write_source->set_name (_name, destructive());
_write_source->set_source_name (_name, destructive());
/* XXX what to do if this fails ? */
}
return 0;

View file

@ -427,7 +427,7 @@ MidiTrack::roll (nframes_t nframes, nframes_t start_frame, nframes_t end_frame,
int dret;
boost::shared_ptr<MidiDiskstream> diskstream = midi_diskstream();
if (n_outputs().n_total() == 0 && _redirects.empty()) {
if (n_outputs().n_total() == 0 && _inserts.empty()) {
return 0;
}
@ -498,7 +498,7 @@ int
MidiTrack::silent_roll (nframes_t nframes, nframes_t start_frame, nframes_t end_frame, nframes_t offset,
bool can_record, bool rec_monitors_input)
{
if (n_outputs().n_midi() == 0 && _redirects.empty()) {
if (n_outputs().n_midi() == 0 && _inserts.empty()) {
return 0;
}
@ -518,29 +518,29 @@ MidiTrack::silent_roll (nframes_t nframes, nframes_t start_frame, nframes_t end_
void
MidiTrack::process_output_buffers (BufferSet& bufs,
nframes_t start_frame, nframes_t end_frame,
nframes_t nframes, nframes_t offset, bool with_redirects, int declick,
nframes_t nframes, nframes_t offset, bool with_inserts, int declick,
bool meter)
{
/* There's no such thing as a MIDI bus for the time being, to avoid diverging from trunk
* too much until the SoC settles down. We'll do all the MIDI route work here for now,
* but the long-term goal is to have Route::process_output_buffers handle everything */
/* There's no such thing as a MIDI bus for the time being.
* We'll do all the MIDI route work here for now, but the long-term goal is to have
* Route::process_output_buffers handle everything */
if (meter && (_meter_point == MeterInput || _meter_point == MeterPreFader)) {
_meter->run(bufs, nframes);
_meter->run(bufs, start_frame, end_frame, nframes, offset);
}
// Run all redirects
if (with_redirects) {
Glib::RWLock::ReaderLock rm (redirect_lock, Glib::TRY_LOCK);
// Run all inserts
if (with_inserts) {
Glib::RWLock::ReaderLock rm (insert_lock, Glib::TRY_LOCK);
if (rm.locked()) {
for (RedirectList::iterator i = _redirects.begin(); i != _redirects.end(); ++i) {
for (InsertList::iterator i = _inserts.begin(); i != _inserts.end(); ++i) {
(*i)->run (bufs, start_frame, end_frame, nframes, offset);
}
}
}
if (meter && (_meter_point == MeterPostFader)) {
_meter->run(bufs, nframes);
_meter->run(bufs, start_frame, end_frame, nframes, offset);
}
// Main output stage
@ -551,28 +551,6 @@ MidiTrack::process_output_buffers (BufferSet& bufs,
}
}
int
MidiTrack::set_name (string str, void *src)
{
int ret;
if (record_enabled() && _session.actively_recording()) {
/* this messes things up if done while recording */
return -1;
}
if (_diskstream->set_name (str)) {
return -1;
}
/* save state so that the statefile fully reflects any filename changes */
if ((ret = IO::set_name (str, src)) == 0) {
_session.save_state ("");
}
return ret;
}
int
MidiTrack::export_stuff (BufferSet& bufs, nframes_t nframes, nframes_t end_frame)
{

View file

@ -71,7 +71,7 @@ struct RegionSortByLastLayerOp {
};
Playlist::Playlist (Session& sess, string nom, DataType type, bool hide)
: _session (sess)
: SessionObject(sess, nom)
, _type(type)
{
init (hide);
@ -81,7 +81,7 @@ Playlist::Playlist (Session& sess, string nom, DataType type, bool hide)
}
Playlist::Playlist (Session& sess, const XMLNode& node, DataType type, bool hide)
: _session (sess)
: SessionObject(sess, "unnamed playlist")
, _type(type)
{
const XMLProperty* prop = node.property("type");
@ -94,7 +94,7 @@ Playlist::Playlist (Session& sess, const XMLNode& node, DataType type, bool hide
}
Playlist::Playlist (boost::shared_ptr<const Playlist> other, string namestr, bool hide)
: _name (namestr), _session (other->_session), _type(other->_type), _orig_diskstream_id(other->_orig_diskstream_id)
: SessionObject(other->_session, namestr), _type(other->_type), _orig_diskstream_id(other->_orig_diskstream_id)
{
init (hide);
@ -126,7 +126,7 @@ Playlist::Playlist (boost::shared_ptr<const Playlist> other, string namestr, boo
}
Playlist::Playlist (boost::shared_ptr<const Playlist> other, nframes_t start, nframes_t cnt, string str, bool hide)
: _name (str), _session (other->_session), _type(other->_type), _orig_diskstream_id(other->_orig_diskstream_id)
: SessionObject(other->_session, str), _type(other->_type), _orig_diskstream_id(other->_orig_diskstream_id)
{
RegionLock rlock2 (const_cast<Playlist*> (other.get()));
@ -247,14 +247,14 @@ Playlist::init (bool hide)
}
Playlist::Playlist (const Playlist& pl)
: _session (pl._session)
: SessionObject(pl._session, pl._name)
, _type(pl.data_type())
{
fatal << _("playlist const copy constructor called") << endmsg;
}
Playlist::Playlist (Playlist& pl)
: _session (pl._session)
: SessionObject(pl._session, pl._name)
, _type(pl.data_type())
{
fatal << _("playlist non-const copy constructor called") << endmsg;
@ -273,8 +273,8 @@ Playlist::~Playlist ()
/* GoingAway must be emitted by derived classes */
}
void
Playlist::set_name (string str)
bool
Playlist::set_name (const string& str)
{
/* in a typical situation, a playlist is being used
by one diskstream and also is referenced by the
@ -283,11 +283,10 @@ Playlist::set_name (string str)
*/
if (_refcnt > 2) {
return;
return false;
} else {
return SessionObject::set_name(str);
}
_name = str;
NameChanged(); /* EMIT SIGNAL */
}
/***********************************************************************

View file

@ -30,6 +30,7 @@
#include <ardour/route.h>
#include <ardour/ladspa_plugin.h>
#include <ardour/buffer_set.h>
#include <ardour/automation_event.h>
#ifdef VST_SUPPORT
#include <ardour/vst_plugin.h>
@ -67,11 +68,11 @@ PluginInsert::PluginInsert (Session& s, boost::shared_ptr<Plugin> plug, Placemen
IO::MoreChannels (max(input_streams(), output_streams()));
}
RedirectCreated (this); /* EMIT SIGNAL */
InsertCreated (this); /* EMIT SIGNAL */
}
PluginInsert::PluginInsert (Session& s, const XMLNode& node)
: Insert (s, "will change", PreFader)
: Insert (s, "unnamed plugin insert", PreFader)
{
if (set_state (node)) {
throw failed_constructor();
@ -88,7 +89,7 @@ PluginInsert::PluginInsert (Session& s, const XMLNode& node)
}
PluginInsert::PluginInsert (const PluginInsert& other)
: Insert (other._session, other.plugin()->name(), other.placement())
: Insert (other._session, other._name, other.placement())
{
uint32_t count = other._plugins.size();
@ -102,7 +103,7 @@ PluginInsert::PluginInsert (const PluginInsert& other)
init ();
RedirectCreated (this); /* EMIT SIGNAL */
InsertCreated (this); /* EMIT SIGNAL */
}
bool
@ -272,7 +273,7 @@ PluginInsert::connect_and_run (BufferSet& bufs, nframes_t nframes, nframes_t off
map<uint32_t,AutomationList*>::iterator li;
uint32_t n;
for (n = 0, li = parameter_automation.begin(); li != parameter_automation.end(); ++li, ++n) {
for (n = 0, li = _parameter_automation.begin(); li != _parameter_automation.end(); ++li, ++n) {
AutomationList& alist (*((*li).second));
@ -302,14 +303,14 @@ PluginInsert::automation_snapshot (nframes_t now)
{
map<uint32_t,AutomationList*>::iterator li;
for (li = parameter_automation.begin(); li != parameter_automation.end(); ++li) {
for (li =_parameter_automation.begin(); li !=_parameter_automation.end(); ++li) {
AutomationList *alist = ((*li).second);
if (alist != 0 && alist->automation_write ()) {
float val = _plugins[0]->get_parameter ((*li).first);
alist->rt_add (now, val);
last_automation_snapshot = now;
_last_automation_snapshot = now;
}
}
}
@ -319,7 +320,7 @@ PluginInsert::transport_stopped (nframes_t now)
{
map<uint32_t,AutomationList*>::iterator li;
for (li = parameter_automation.begin(); li != parameter_automation.end(); ++li) {
for (li =_parameter_automation.begin(); li !=_parameter_automation.end(); ++li) {
AutomationList& alist (*(li->second));
alist.reposition_for_rt_add (now);
@ -353,6 +354,9 @@ PluginInsert::run (BufferSet& bufs, nframes_t start_frame, nframes_t end_frame,
connect_and_run (bufs, nframes, offset, false);
}
} else {
/* FIXME: type, audio only */
uint32_t in = _plugins[0]->get_info()->n_inputs.n_audio();
uint32_t out = _plugins[0]->get_info()->n_outputs.n_audio();
@ -365,7 +369,7 @@ PluginInsert::run (BufferSet& bufs, nframes_t start_frame, nframes_t end_frame,
}
}
bufs.count().set(_default_type, out);
bufs.count().set_audio(out);
}
}
@ -526,26 +530,41 @@ PluginInsert::configure_io (ChanCount in, ChanCount out)
return false;
} else {
bool success = set_count (count_for_configuration(in, out));
if (success) {
_configured = true;
_configured_input = in;
}
if (success)
Insert::configure_io(in, out);
return success;
}
}
bool
PluginInsert::can_support_input_configuration (ChanCount in_count) const
PluginInsert::can_support_input_configuration (ChanCount in) const
{
int32_t outputs = _plugins[0]->get_info()->n_outputs.get(_default_type);
int32_t inputs = _plugins[0]->get_info()->n_inputs.get(_default_type);
int32_t in = in_count.get(_default_type);
ChanCount outputs = _plugins[0]->get_info()->n_outputs;
ChanCount inputs = _plugins[0]->get_info()->n_inputs;
/* see output_for_input_configuration below */
if ((inputs == 0)
|| (outputs == 1 && inputs == 1)
|| (inputs == in)
|| ((inputs < in) && (inputs % in == 0))) {
if ((inputs.n_total() == 0)
|| (inputs.n_total() == 1 && outputs == inputs)
|| (inputs.n_total() == 1 && outputs == inputs
&& ((inputs.n_audio() == 0 && in.n_audio() == 0)
|| (inputs.n_midi() == 0 && in.n_midi() == 0)))
|| (inputs == in)) {
return true;
}
bool can_replicate = true;
/* if number of inputs is a factor of the requested input
configuration for every type, we can replicate.
*/
for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
if (inputs.get(*t) >= in.get(*t) || (inputs.get(*t) % in.get(*t) != 0)) {
can_replicate = false;
break;
}
}
if (can_replicate && (in.n_total() % inputs.n_total() == 0)) {
return true;
} else {
return false;
@ -563,7 +582,9 @@ PluginInsert::output_for_input_configuration (ChanCount in) const
return outputs;
}
if (inputs.n_total() == 1 && outputs == inputs) {
if (inputs.n_total() == 1 && outputs == inputs
&& ((inputs.n_audio() == 0 && in.n_audio() == 0)
|| (inputs.n_midi() == 0 && in.n_midi() == 0))) {
/* mono plugin, replicate as needed to match in */
return in;
}
@ -573,17 +594,26 @@ PluginInsert::output_for_input_configuration (ChanCount in) const
return outputs;
}
// FIXME: single type plugins only. can we do this for instruments?
if ((inputs.n_total() == inputs.get(_default_type))
&& ((in.n_total() == in.get(_default_type))
&& (inputs.n_total() < in.n_total())
&& (inputs.n_total() % in.n_total() == 0))) {
bool can_replicate = true;
/* number of inputs is a factor of the requested input
configuration, so we can replicate.
*/
/* if number of inputs is a factor of the requested input
configuration for every type, we can replicate.
*/
for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
if (inputs.get(*t) >= in.get(*t) || (in.get(*t) % inputs.get(*t) != 0)) {
can_replicate = false;
break;
}
}
return ChanCount(_default_type, in.n_total() / inputs.n_total());
if (can_replicate && (inputs.n_total() % in.n_total() == 0)) {
ChanCount output;
for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
output.set(*t, outputs.get(*t) * (in.get(*t) / inputs.get(*t)));
}
return output;
}
/* sorry */
@ -606,7 +636,9 @@ PluginInsert::count_for_configuration (ChanCount in, ChanCount out) const
return 1;
}
if (inputs.n_total() == 1 && outputs == inputs) {
if (inputs.n_total() == 1 && outputs == inputs
&& ((inputs.n_audio() == 0 && in.n_audio() == 0)
|| (inputs.n_midi() == 0 && in.n_midi() == 0))) {
/* mono plugin, replicate as needed to match in */
return in.n_total();
}
@ -616,20 +648,14 @@ PluginInsert::count_for_configuration (ChanCount in, ChanCount out) const
return 1;
}
// FIXME: single type plugins only. can we do this for instruments?
if ((inputs.n_total() == inputs.get(_default_type))
&& ((in.n_total() == in.get(_default_type))
&& (inputs.n_total() < in.n_total())
&& (inputs.n_total() % in.n_total() == 0))) {
/* number of inputs is a factor of the requested input
configuration, so we can replicate.
*/
// assumes in is valid, so we must be replicating
if (inputs.n_total() < in.n_total()
&& (in.n_total() % inputs.n_total() == 0)) {
return in.n_total() / inputs.n_total();
}
/* sorry */
/* err... */
return 0;
}
@ -643,20 +669,18 @@ XMLNode&
PluginInsert::state (bool full)
{
char buf[256];
XMLNode *node = new XMLNode("Insert");
XMLNode& node = Insert::state (full);
node->add_child_nocopy (Redirect::state (full));
node->add_property ("type", _plugins[0]->state_node_name());
node.add_property ("type", _plugins[0]->state_node_name());
snprintf(buf, sizeof(buf), "%s", _plugins[0]->name());
node->add_property("id", string(buf));
node.add_property("id", string(buf));
if (_plugins[0]->state_node_name() == "ladspa") {
char buf[32];
snprintf (buf, sizeof (buf), "%ld", _plugins[0]->get_info()->unique_id);
node->add_property("unique-id", string(buf));
node.add_property("unique-id", string(buf));
}
node->add_property("count", string_compose("%1", _plugins.size()));
node->add_child_nocopy (_plugins[0]->get_state());
node.add_property("count", string_compose("%1", _plugins.size()));
node.add_child_nocopy (_plugins[0]->get_state());
/* add port automation state */
XMLNode *autonode = new XMLNode(port_automation_node_name);
@ -672,9 +696,9 @@ PluginInsert::state (bool full)
autonode->add_child_nocopy (*child);
}
node->add_child_nocopy (*autonode);
node.add_child_nocopy (*autonode);
return *node;
return node;
}
int
@ -752,23 +776,18 @@ PluginInsert::set_state(const XMLNode& node)
}
}
const XMLNode* insert_node = &node;
// legacy sessions: search for child Redirect node
for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
if ((*niter)->name() == Redirect::state_node_name) {
Redirect::set_state (**niter);
if ((*niter)->name() == "Redirect") {
insert_node = *niter;
break;
}
}
if (niter == nlist.end()) {
error << _("XML node describing insert is missing a Redirect node") << endmsg;
return -1;
}
if (niter == nlist.end()) {
error << string_compose(_("XML node describing a plugin insert is missing the `%1' information"), plugin->state_node_name()) << endmsg;
return -1;
}
Insert::set_state (*insert_node);
/* look for port automation node */
for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
@ -835,7 +854,7 @@ PluginInsert::set_state(const XMLNode& node)
}
// The name of the PluginInsert comes from the plugin, nothing else
set_name(plugin->get_info()->name,this);
_name = plugin->get_info()->name;
return 0;
}

View file

@ -41,41 +41,41 @@ using namespace ARDOUR;
using namespace PBD;
PortInsert::PortInsert (Session& s, Placement p)
: Insert (s, string_compose (_("insert %1"), (bitslot = s.next_insert_id()) + 1), p, 1, -1, 1, -1)
: Redirect (s, string_compose (_("insert %1"), (bitslot = s.next_insert_id()) + 1), p, 1, -1, 1, -1)
{
init ();
RedirectCreated (this); /* EMIT SIGNAL */
InsertCreated (this); /* EMIT SIGNAL */
}
PortInsert::PortInsert (const PortInsert& other)
: Insert (other._session, string_compose (_("insert %1"), (bitslot = other._session.next_insert_id()) + 1), other.placement(), 1, -1, 1, -1)
: Redirect (other._session, string_compose (_("insert %1"), (bitslot = other._session.next_insert_id()) + 1), other.placement(), 1, -1, 1, -1)
{
init ();
RedirectCreated (this); /* EMIT SIGNAL */
InsertCreated (this); /* EMIT SIGNAL */
}
void
PortInsert::init ()
{
if (add_input_port ("", this)) {
if (_io->add_input_port ("", this)) {
error << _("PortInsert: cannot add input port") << endmsg;
throw failed_constructor();
}
if (add_output_port ("", this)) {
if (_io->add_output_port ("", this)) {
error << _("PortInsert: cannot add output port") << endmsg;
throw failed_constructor();
}
}
PortInsert::PortInsert (Session& s, const XMLNode& node)
: Insert (s, "will change", PreFader)
: Redirect (s, "unnamed port insert", PreFader)
{
if (set_state (node)) {
throw failed_constructor();
}
RedirectCreated (this); /* EMIT SIGNAL */
InsertCreated (this); /* EMIT SIGNAL */
}
PortInsert::~PortInsert ()
@ -86,19 +86,19 @@ PortInsert::~PortInsert ()
void
PortInsert::run (BufferSet& bufs, nframes_t start_frame, nframes_t end_frame, nframes_t nframes, nframes_t offset)
{
if (n_outputs().get(_default_type) == 0) {
if (_io->n_outputs().n_total() == 0) {
return;
}
if (!active()) {
/* deliver silence */
silence (nframes, offset);
_io->silence (nframes, offset);
return;
}
deliver_output(bufs, start_frame, end_frame, nframes, offset);
_io->deliver_output(bufs, start_frame, end_frame, nframes, offset);
collect_input(bufs, nframes, offset);
_io->collect_input(bufs, nframes, offset);
}
XMLNode&
@ -110,14 +110,13 @@ PortInsert::get_state(void)
XMLNode&
PortInsert::state (bool full)
{
XMLNode *node = new XMLNode("Insert");
XMLNode& node = Redirect::state(full);
char buf[32];
node->add_child_nocopy (Redirect::state(full));
node->add_property ("type", "port");
node.add_property ("type", "port");
snprintf (buf, sizeof (buf), "%" PRIu32, bitslot);
node->add_property ("bitslot", buf);
node.add_property ("bitslot", buf);
return *node;
return node;
}
int
@ -145,17 +144,17 @@ PortInsert::set_state(const XMLNode& node)
_session.mark_insert_id (bitslot);
}
const XMLNode* insert_node = &node;
// legacy sessions: search for child Redirect node
for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
if ((*niter)->name() == Redirect::state_node_name) {
Redirect::set_state (**niter);
if ((*niter)->name() == "Redirect") {
insert_node = *niter;
break;
}
}
if (niter == nlist.end()) {
error << _("XML node describing insert is missing a Redirect node") << endmsg;
return -1;
}
Redirect::set_state (*insert_node);
return 0;
}
@ -170,13 +169,13 @@ PortInsert::latency()
need to take that into account too.
*/
return _session.engine().frames_per_cycle() + input_latency();
return _session.engine().frames_per_cycle() + _io->input_latency();
}
bool
PortInsert::can_support_input_configuration (ChanCount in) const
{
if (input_maximum() == ChanCount::INFINITE && output_maximum() == ChanCount::INFINITE) {
if (_io->input_maximum() == ChanCount::INFINITE && _io->output_maximum() == ChanCount::INFINITE) {
/* not configured yet */
@ -188,7 +187,7 @@ PortInsert::can_support_input_configuration (ChanCount in) const
many output ports it will have.
*/
if (output_maximum() == in) {
if (_io->output_maximum() == in) {
return true;
}
@ -220,23 +219,28 @@ PortInsert::configure_io (ChanCount in, ChanCount out)
to the number of input ports we need.
*/
set_output_maximum (in);
set_output_minimum (in);
set_input_maximum (out);
set_input_minimum (out);
_io->set_output_maximum (in);
_io->set_output_minimum (in);
_io->set_input_maximum (out);
_io->set_input_minimum (out);
return (ensure_io (out, in, false, this) == 0);
bool success = (_io->ensure_io (out, in, false, this) == 0);
if (success)
return Insert::configure_io(in, out);
else
return false;
}
ChanCount
PortInsert::output_streams() const
{
return n_inputs ();
return _io->n_inputs ();
}
ChanCount
PortInsert::input_streams() const
{
return n_outputs ();
return _io->n_outputs ();
}

View file

@ -42,17 +42,13 @@ using namespace std;
using namespace ARDOUR;
using namespace PBD;
const string Redirect::state_node_name = "Redirect";
sigc::signal<void,Redirect*> Redirect::RedirectCreated;
Redirect::Redirect (Session& s, const string& name, Placement p,
int input_min, int input_max,
int output_min, int output_max)
: IO (s, name, input_min, input_max, output_min, output_max)
: Insert(s, name, p)
, _io(new IO(s, name, input_min, input_max, output_min, output_max))
{
_placement = p;
_active = false;
_next_ab_is_active = false;
_sort_key = 0;
_gui = 0;
_extra_xml = 0;
@ -63,161 +59,22 @@ Redirect::~Redirect ()
notify_callbacks ();
}
boost::shared_ptr<Redirect>
Redirect::clone (boost::shared_ptr<const Redirect> other)
{
boost::shared_ptr<const Send> send;
boost::shared_ptr<const PortInsert> port_insert;
boost::shared_ptr<const PluginInsert> plugin_insert;
if ((send = boost::dynamic_pointer_cast<const Send>(other)) != 0) {
return boost::shared_ptr<Redirect> (new Send (*send));
} else if ((port_insert = boost::dynamic_pointer_cast<const PortInsert>(other)) != 0) {
return boost::shared_ptr<Redirect> (new PortInsert (*port_insert));
} else if ((plugin_insert = boost::dynamic_pointer_cast<const PluginInsert>(other)) != 0) {
return boost::shared_ptr<Redirect> (new PluginInsert (*plugin_insert));
} else {
fatal << _("programming error: unknown Redirect type in Redirect::Clone!\n")
<< endmsg;
/*NOTREACHED*/
}
return boost::shared_ptr<Redirect>();
}
void
Redirect::set_sort_key (uint32_t key)
{
_sort_key = key;
}
void
Redirect::set_placement (Placement p, void *src)
{
if (_placement != p) {
_placement = p;
placement_changed (this, src); /* EMIT SIGNAL */
}
}
/* NODE STRUCTURE
<Automation [optionally with visible="...." ]>
<parameter-N>
<AutomationList id=N>
<events>
X1 Y1
X2 Y2
....
</events>
</parameter-N>
<Automation>
*/
int
Redirect::set_automation_state (const XMLNode& node)
{
Glib::Mutex::Lock lm (_automation_lock);
parameter_automation.clear ();
XMLNodeList nlist = node.children();
XMLNodeIterator niter;
for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
uint32_t param;
if (sscanf ((*niter)->name().c_str(), "parameter-%" PRIu32, &param) != 1) {
error << string_compose (_("%2: badly formatted node name in XML automation state, ignored"), _name) << endmsg;
continue;
}
AutomationList& al = automation_list (param);
if (al.set_state (*(*niter)->children().front())) {
goto bad;
}
}
return 0;
bad:
error << string_compose(_("%1: cannot load automation data from XML"), _name) << endmsg;
parameter_automation.clear ();
return -1;
}
XMLNode&
Redirect::get_automation_state ()
{
Glib::Mutex::Lock lm (_automation_lock);
XMLNode* node = new XMLNode (X_("Automation"));
string fullpath;
if (parameter_automation.empty()) {
return *node;
}
map<uint32_t,AutomationList*>::iterator li;
for (li = parameter_automation.begin(); li != parameter_automation.end(); ++li) {
XMLNode* child;
char buf[64];
stringstream str;
snprintf (buf, sizeof (buf), "parameter-%" PRIu32, li->first);
child = new XMLNode (buf);
child->add_child_nocopy (li->second->get_state ());
}
return *node;
}
XMLNode&
Redirect::get_state (void)
{
return state (true);
}
XMLNode&
Redirect::state (bool full_state)
{
XMLNode* node = new XMLNode (state_node_name);
stringstream sstr;
node->add_property("active", active() ? "yes" : "no");
node->add_property("placement", enum_2_string (_placement));
node->add_child_nocopy (IO::state (full_state));
if (_extra_xml){
node->add_child_copy (*_extra_xml);
}
XMLNode& node = Insert::state(full_state);
if (full_state) {
node.add_child_nocopy (_io->state (full_state));
XMLNode& automation = get_automation_state();
for (set<uint32_t>::iterator x = visible_parameter_automation.begin(); x != visible_parameter_automation.end(); ++x) {
if (x != visible_parameter_automation.begin()) {
sstr << ' ';
}
sstr << *x;
}
automation.add_property ("visible", sstr.str());
node->add_child_nocopy (automation);
}
return *node;
return node;
}
int
Redirect::set_state (const XMLNode& node)
{
const XMLProperty *prop;
Insert::set_state(node);
if (node.name() != state_node_name) {
if (node.name() != "Insert" && node.name() != "Redirect") {
error << string_compose(_("incorrect XML node \"%1\" passed to Redirect object"), node.name()) << endmsg;
return -1;
}
@ -227,260 +84,22 @@ Redirect::set_state (const XMLNode& node)
bool have_io = false;
for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
if ((*niter)->name() == IO::state_node_name) {
IO::set_state (**niter);
have_io = true;
} else if ((*niter)->name() == X_("Automation")) {
XMLProperty *prop;
if ((prop = (*niter)->property ("path")) != 0) {
old_set_automation_state (*(*niter));
} else {
set_automation_state (*(*niter));
}
if ((prop = (*niter)->property ("visible")) != 0) {
uint32_t what;
stringstream sstr;
visible_parameter_automation.clear ();
sstr << prop->value();
while (1) {
sstr >> what;
if (sstr.fail()) {
break;
}
mark_automation_visible (what, true);
}
}
} else if ((*niter)->name() == "extra") {
_extra_xml = new XMLNode (*(*niter));
_io->set_state(**niter);
}
}
if (!have_io) {
error << _("XML node describing an IO is missing an IO node") << endmsg;
error << _("XML node describing a redirect is missing an IO node") << endmsg;
return -1;
}
if ((prop = node.property ("active")) == 0) {
error << _("XML node describing a redirect is missing the `active' field") << endmsg;
return -1;
}
if (_active != (prop->value() == "yes")) {
_active = !_active;
active_changed (this, this); /* EMIT_SIGNAL */
}
if ((prop = node.property ("placement")) == 0) {
error << _("XML node describing a redirect is missing the `placement' field") << endmsg;
return -1;
}
/* hack to handle older sessions before we only used EnumWriter */
string pstr;
if (prop->value() == "pre") {
pstr = "PreFader";
} else if (prop->value() == "post") {
pstr = "PostFader";
} else {
pstr = prop->value();
}
Placement p = Placement (string_2_enum (pstr, p));
set_placement (p, this);
return 0;
}
int
Redirect::old_set_automation_state (const XMLNode& node)
{
const XMLProperty *prop;
if ((prop = node.property ("path")) != 0) {
load_automation (prop->value());
} else {
warning << string_compose(_("%1: Automation node has no path property"), _name) << endmsg;
}
if ((prop = node.property ("visible")) != 0) {
uint32_t what;
stringstream sstr;
visible_parameter_automation.clear ();
sstr << prop->value();
while (1) {
sstr >> what;
if (sstr.fail()) {
break;
}
mark_automation_visible (what, true);
}
}
return 0;
}
int
Redirect::load_automation (string path)
{
string fullpath;
if (path[0] == '/') { // legacy
fullpath = path;
} else {
fullpath = _session.automation_dir();
fullpath += path;
}
ifstream in (fullpath.c_str());
if (!in) {
warning << string_compose(_("%1: cannot open %2 to load automation data (%3)"), _name, fullpath, strerror (errno)) << endmsg;
return 1;
}
Glib::Mutex::Lock lm (_automation_lock);
set<uint32_t> tosave;
parameter_automation.clear ();
while (in) {
double when;
double value;
uint32_t port;
in >> port; if (!in) break;
in >> when; if (!in) goto bad;
in >> value; if (!in) goto bad;
AutomationList& al = automation_list (port);
al.add (when, value);
tosave.insert (port);
}
return 0;
bad:
error << string_compose(_("%1: cannot load automation data from %2"), _name, fullpath) << endmsg;
parameter_automation.clear ();
return -1;
}
void
Redirect::what_has_automation (set<uint32_t>& s) const
Redirect::silence (nframes_t nframes, nframes_t offset)
{
Glib::Mutex::Lock lm (_automation_lock);
map<uint32_t,AutomationList*>::const_iterator li;
for (li = parameter_automation.begin(); li != parameter_automation.end(); ++li) {
s.insert ((*li).first);
}
}
void
Redirect::what_has_visible_automation (set<uint32_t>& s) const
{
Glib::Mutex::Lock lm (_automation_lock);
set<uint32_t>::const_iterator li;
for (li = visible_parameter_automation.begin(); li != visible_parameter_automation.end(); ++li) {
s.insert (*li);
}
}
AutomationList&
Redirect::automation_list (uint32_t parameter)
{
AutomationList* al = parameter_automation[parameter];
if (al == 0) {
al = parameter_automation[parameter] = new AutomationList (default_parameter_value (parameter));
/* let derived classes do whatever they need with this */
automation_list_creation_callback (parameter, *al);
}
return *al;
}
string
Redirect::describe_parameter (uint32_t which)
{
/* derived classes will override this */
return "";
}
void
Redirect::can_automate (uint32_t what)
{
can_automate_list.insert (what);
}
void
Redirect::mark_automation_visible (uint32_t what, bool yn)
{
if (yn) {
visible_parameter_automation.insert (what);
} else {
set<uint32_t>::iterator i;
if ((i = visible_parameter_automation.find (what)) != visible_parameter_automation.end()) {
visible_parameter_automation.erase (i);
}
}
}
bool
Redirect::find_next_event (nframes_t now, nframes_t end, ControlEvent& next_event) const
{
map<uint32_t,AutomationList*>::const_iterator li;
AutomationList::TimeComparator cmp;
next_event.when = max_frames;
for (li = parameter_automation.begin(); li != parameter_automation.end(); ++li) {
AutomationList::const_iterator i;
const AutomationList& alist (*((*li).second));
ControlEvent cp (now, 0.0f);
for (i = lower_bound (alist.const_begin(), alist.const_end(), &cp, cmp); i != alist.const_end() && (*i)->when < end; ++i) {
if ((*i)->when > now) {
break;
}
}
if (i != alist.const_end() && (*i)->when < end) {
if ((*i)->when < next_event.when) {
next_event.when = (*i)->when;
}
}
}
return next_event.when != max_frames;
}
void
Redirect::set_active (bool yn, void* src)
{
_active = yn;
active_changed (this, src);
_session.set_dirty ();
}
void
Redirect::set_next_ab_is_active (bool yn)
{
_next_ab_is_active = yn;
_io->silence(nframes, offset);
}

File diff suppressed because it is too large Load diff

View file

@ -149,7 +149,6 @@ RouteGroup::set_state (const XMLNode& node)
void
RouteGroup::set_active (bool yn, void *src)
{
if (is_active() == yn) {
return;

View file

@ -36,7 +36,7 @@ Send::Send (Session& s, Placement p)
: Redirect (s, string_compose (_("send %1"), (bitslot = s.next_send_id()) + 1), p)
{
_metering = false;
RedirectCreated (this); /* EMIT SIGNAL */
InsertCreated (this); /* EMIT SIGNAL */
}
Send::Send (Session& s, const XMLNode& node)
@ -48,14 +48,14 @@ Send::Send (Session& s, const XMLNode& node)
throw failed_constructor();
}
RedirectCreated (this); /* EMIT SIGNAL */
InsertCreated (this); /* EMIT SIGNAL */
}
Send::Send (const Send& other)
: Redirect (other._session, string_compose (_("send %1"), (bitslot = other._session.next_send_id()) + 1), other.placement())
{
_metering = false;
RedirectCreated (this); /* EMIT SIGNAL */
InsertCreated (this); /* EMIT SIGNAL */
}
Send::~Send ()
@ -72,12 +72,13 @@ Send::get_state(void)
XMLNode&
Send::state(bool full)
{
XMLNode *node = new XMLNode("Send");
XMLNode& node = Redirect::state(full);
char buf[32];
node->add_child_nocopy (Redirect::state (full));
node.add_property ("type", "send");
snprintf (buf, sizeof (buf), "%" PRIu32, bitslot);
node->add_property ("bitslot", buf);
return *node;
node.add_property ("bitslot", buf);
return node;
}
int
@ -94,16 +95,19 @@ Send::set_state(const XMLNode& node)
_session.mark_send_id (bitslot);
}
const XMLNode* insert_node = &node;
/* Send has regular IO automation (gain, pan) */
for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
if ((*niter)->name() == Redirect::state_node_name) {
Redirect::set_state (**niter);
break;
if ((*niter)->name() == "Redirect") {
insert_node = *niter;
} else if ((*niter)->name() == X_("Automation")) {
IO::set_automation_state (*(*niter));
_io->set_automation_state (*(*niter));
}
}
Redirect::set_state (*insert_node);
if (niter == nlist.end()) {
error << _("XML node describing a send is missing a Redirect node") << endmsg;
@ -126,21 +130,21 @@ Send::run (BufferSet& bufs, nframes_t start_frame, nframes_t end_frame, nframes_
sendbufs.read_from(bufs, nframes);
assert(sendbufs.count() == bufs.count());
IO::deliver_output (sendbufs, start_frame, end_frame, nframes, offset);
_io->deliver_output (sendbufs, start_frame, end_frame, nframes, offset);
if (_metering) {
if (_gain == 0) {
_meter->reset();
if (_io->_gain == 0) {
_io->_meter->reset();
} else {
_meter->run(output_buffers(), nframes, offset);
_io->_meter->run(_io->output_buffers(), start_frame, end_frame, nframes, offset);
}
}
} else {
silence (nframes, offset);
_io->silence (nframes, offset);
if (_metering) {
_meter->reset();
_io->_meter->reset();
}
}
}
@ -152,15 +156,72 @@ Send::set_metering (bool yn)
if (!_metering) {
/* XXX possible thread hazard here */
peak_meter().reset();
_io->peak_meter().reset();
}
}
void
Send::expect_inputs (const ChanCount& expected)
bool
Send::can_support_input_configuration (ChanCount in) const
{
if (expected != _expected_inputs) {
_expected_inputs = expected;
reset_panner ();
if (_io->input_maximum() == ChanCount::INFINITE && _io->output_maximum() == ChanCount::INFINITE) {
/* not configured yet */
return true; /* we can support anything the first time we're asked */
} else {
/* the "input" config for a port insert corresponds to how
many output ports it will have.
*/
if (_io->output_maximum() == in) {
return true;
}
}
return false;
}
ChanCount
Send::output_for_input_configuration (ChanCount in) const
{
// from the internal (Insert) perspective a Send does not modify its input whatsoever
return in;
}
bool
Send::configure_io (ChanCount in, ChanCount out)
{
/* we're transparent no matter what. fight the power. */
if (out != in)
return false;
_io->set_output_maximum (in);
_io->set_output_minimum (in);
_io->set_input_maximum (ChanCount::ZERO);
_io->set_input_minimum (ChanCount::ZERO);
bool success = _io->ensure_io (ChanCount::ZERO, in, false, this) == 0;
if (success) {
Insert::configure_io(in, out);
_io->reset_panner();
return true;
} else {
return false;
}
}
ChanCount
Send::output_streams() const
{
return _io->n_outputs ();
}
ChanCount
Send::input_streams() const
{
return _io->n_outputs (); // (sic)
}

View file

@ -1887,7 +1887,7 @@ Session::add_routes (RouteList& new_routes, bool save)
(*x)->solo_changed.connect (sigc::bind (mem_fun (*this, &Session::route_solo_changed), wpr));
(*x)->mute_changed.connect (mem_fun (*this, &Session::route_mute_changed));
(*x)->output_changed.connect (mem_fun (*this, &Session::set_worst_io_latencies_x));
(*x)->redirects_changed.connect (mem_fun (*this, &Session::update_latency_compensation_proxy));
(*x)->inserts_changed.connect (bind (mem_fun (*this, &Session::update_latency_compensation), false, false));
if ((*x)->master()) {
_master_out = (*x);
@ -3529,65 +3529,51 @@ Session::record_enable_change_all (bool yn)
}
void
Session::add_redirect (Redirect* redirect)
Session::add_insert (Insert* insert)
{
Send* send;
Insert* insert;
PortInsert* port_insert;
PluginInsert* plugin_insert;
if ((insert = dynamic_cast<Insert *> (redirect)) != 0) {
if ((port_insert = dynamic_cast<PortInsert *> (insert)) != 0) {
_port_inserts.insert (_port_inserts.begin(), port_insert);
} else if ((plugin_insert = dynamic_cast<PluginInsert *> (insert)) != 0) {
_plugin_inserts.insert (_plugin_inserts.begin(), plugin_insert);
} else {
fatal << _("programming error: unknown type of Insert created!") << endmsg;
/*NOTREACHED*/
}
} else if ((send = dynamic_cast<Send *> (redirect)) != 0) {
if ((port_insert = dynamic_cast<PortInsert *> (insert)) != 0) {
_port_inserts.insert (_port_inserts.begin(), port_insert);
} else if ((plugin_insert = dynamic_cast<PluginInsert *> (insert)) != 0) {
_plugin_inserts.insert (_plugin_inserts.begin(), plugin_insert);
} else if ((send = dynamic_cast<Send *> (insert)) != 0) {
_sends.insert (_sends.begin(), send);
} else {
fatal << _("programming error: unknown type of Redirect created!") << endmsg;
fatal << _("programming error: unknown type of Insert created!") << endmsg;
/*NOTREACHED*/
}
redirect->GoingAway.connect (sigc::bind (mem_fun (*this, &Session::remove_redirect), redirect));
insert->GoingAway.connect (sigc::bind (mem_fun (*this, &Session::remove_insert), insert));
set_dirty();
}
void
Session::remove_redirect (Redirect* redirect)
Session::remove_insert (Insert* insert)
{
Send* send;
Insert* insert;
PortInsert* port_insert;
PluginInsert* plugin_insert;
if ((insert = dynamic_cast<Insert *> (redirect)) != 0) {
if ((port_insert = dynamic_cast<PortInsert *> (insert)) != 0) {
list<PortInsert*>::iterator x = find (_port_inserts.begin(), _port_inserts.end(), port_insert);
if (x != _port_inserts.end()) {
insert_bitset[port_insert->bit_slot()] = false;
_port_inserts.erase (x);
}
} else if ((plugin_insert = dynamic_cast<PluginInsert *> (insert)) != 0) {
_plugin_inserts.remove (plugin_insert);
} else {
fatal << string_compose (_("programming error: %1"),
X_("unknown type of Insert deleted!"))
<< endmsg;
/*NOTREACHED*/
if ((port_insert = dynamic_cast<PortInsert *> (insert)) != 0) {
list<PortInsert*>::iterator x = find (_port_inserts.begin(), _port_inserts.end(), port_insert);
if (x != _port_inserts.end()) {
insert_bitset[port_insert->bit_slot()] = false;
_port_inserts.erase (x);
}
} else if ((send = dynamic_cast<Send *> (redirect)) != 0) {
} else if ((plugin_insert = dynamic_cast<PluginInsert *> (insert)) != 0) {
_plugin_inserts.remove (plugin_insert);
} else if ((send = dynamic_cast<Send *> (insert)) != 0) {
list<Send*>::iterator x = find (_sends.begin(), _sends.end(), send);
if (x != _sends.end()) {
send_bitset[send->bit_slot()] = false;
_sends.erase (x);
}
} else {
fatal << _("programming error: unknown type of Redirect deleted!") << endmsg;
fatal << _("programming error: unknown type of Insert deleted!") << endmsg;
/*NOTREACHED*/
}

View file

@ -261,7 +261,7 @@ Session::first_stage_init (string fullpath, string snapshot_name)
RegionFactory::CheckNewRegion.connect (mem_fun (*this, &Session::add_region));
SourceFactory::SourceCreated.connect (mem_fun (*this, &Session::add_source));
PlaylistFactory::PlaylistCreated.connect (mem_fun (*this, &Session::add_playlist));
Redirect::RedirectCreated.connect (mem_fun (*this, &Session::add_redirect));
Insert::InsertCreated.connect (mem_fun (*this, &Session::add_insert));
NamedSelection::NamedSelectionCreated.connect (mem_fun (*this, &Session::add_named_selection));
AutomationList::AutomationListCreated.connect (mem_fun (*this, &Session::add_automation_list));

View file

@ -379,7 +379,7 @@ Session::non_realtime_stop (bool abort, int on_entry, bool& finished)
if ((Config->get_slave_source() == None && Config->get_auto_return()) || (post_transport_work & PostTransportLocate) || synced_to_jack()) {
if (pending_locate_flush) {
flush_all_redirects ();
flush_all_inserts ();
}
if (((Config->get_slave_source() == None && Config->get_auto_return()) || synced_to_jack()) && !(post_transport_work & PostTransportLocate)) {
@ -573,12 +573,12 @@ Session::set_play_loop (bool yn)
}
void
Session::flush_all_redirects ()
Session::flush_all_inserts ()
{
boost::shared_ptr<RouteList> r = routes.reader ();
for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
(*i)->flush_redirects ();
(*i)->flush_inserts ();
}
}
@ -1266,12 +1266,6 @@ Session::update_latency_compensation (bool with_stop, bool abort)
}
}
void
Session::update_latency_compensation_proxy (void* ignored)
{
update_latency_compensation (false, false);
}
void
Session::allow_auto_play (bool yn)
{

View file

@ -679,7 +679,7 @@ SMFSource::set_allow_remove_if_empty (bool yn)
}
int
SMFSource::set_name (string newname, bool destructive)
SMFSource::set_source_name (string newname, bool destructive)
{
//Glib::Mutex::Lock lm (_lock); FIXME
string oldpath = _path;

View file

@ -42,20 +42,20 @@ using std::max;
using namespace ARDOUR;
Source::Source (Session& s, string name, DataType type)
: _session (s)
Source::Source (Session& s, const string& name, DataType type)
: SessionObject(s, name)
, _type(type)
{
assert(_name.find("/") == string::npos);
// not true.. is this supposed to be an assertion?
//assert(_name.find("/") == string::npos);
_name = name;
_timestamp = 0;
_length = 0;
_in_use = 0;
}
Source::Source (Session& s, const XMLNode& node)
: _session (s)
: SessionObject(s, "unnamed source")
, _type(DataType::AUDIO)
{
_timestamp = 0;

View file

@ -40,7 +40,7 @@ using namespace PBD;
Track::Track (Session& sess, string name, Route::Flag flag, TrackMode mode, DataType default_type)
: Route (sess, name, 1, -1, -1, -1, flag, default_type)
, _rec_enable_control (*this)
, _rec_enable_control (*this)
{
_declickable = true;
_freeze_record.state = NoFreeze;
@ -49,8 +49,8 @@ Track::Track (Session& sess, string name, Route::Flag flag, TrackMode mode, Data
}
Track::Track (Session& sess, const XMLNode& node, DataType default_type)
: Route (sess, node),
_rec_enable_control (*this)
: Route (sess, node)
, _rec_enable_control (*this)
{
_freeze_record.state = NoFreeze;
_declickable = true;
@ -92,7 +92,7 @@ Track::update_total_latency ()
{
_own_latency = 0;
for (RedirectList::iterator i = _redirects.begin(); i != _redirects.end(); ++i) {
for (InsertList::iterator i = _inserts.begin(); i != _inserts.end(); ++i) {
if ((*i)->active ()) {
_own_latency += (*i)->latency ();
}
@ -182,25 +182,27 @@ Track::set_record_enable (bool yn, void *src)
_rec_enable_control.Changed ();
}
int
Track::set_name (string str, void *src)
bool
Track::set_name (const string& str)
{
int ret;
bool ret;
if (record_enabled() && _session.actively_recording()) {
/* this messes things up if done while recording */
return -1;
return false;
}
if (_diskstream->set_name (str)) {
return -1;
return false;
}
/* save state so that the statefile fully reflects any filename changes */
if ((ret = IO::set_name (str, src)) == 0) {
if ((ret = IO::set_name (str)) == 0) {
_session.save_state ("");
}
return ret;
}

View file

@ -980,7 +980,7 @@ void MackieControlProtocol::notify_gain_changed( RouteSignal * route_signal )
}
}
void MackieControlProtocol::notify_name_changed( void *, RouteSignal * route_signal )
void MackieControlProtocol::notify_name_changed( RouteSignal * route_signal )
{
try
{

View file

@ -95,7 +95,7 @@ class MackieControlProtocol
/// Signal handler for Route::gain_changed ( from IO )
void notify_gain_changed( Mackie::RouteSignal * );
/// Signal handler for Route::name_change
void notify_name_changed( void *, Mackie::RouteSignal * );
void notify_name_changed( Mackie::RouteSignal * );
/// Signal handler from Panner::Change
void notify_panner_changed( Mackie::RouteSignal * );
/// Signal handler for new routes added

View file

@ -38,7 +38,7 @@ void RouteSignal::connect()
if ( _strip.has_gain() )
_gain_changed_connection = _route.gain_control().Changed.connect( sigc::bind ( mem_fun ( _mcp, &MackieControlProtocol::notify_gain_changed ), this ) );
_name_changed_connection = _route.name_changed.connect( sigc::bind ( mem_fun ( _mcp, &MackieControlProtocol::notify_name_changed ), this ) );
_name_changed_connection = _route.NameChanged.connect( sigc::bind ( mem_fun ( _mcp, &MackieControlProtocol::notify_name_changed ), this ) );
if ( _route.panner().size() == 1 )
{
@ -85,7 +85,7 @@ void RouteSignal::notify_all()
if ( _strip.has_gain() )
_mcp.notify_gain_changed( this );
_mcp.notify_name_changed( &_route, this );
_mcp.notify_name_changed( this );
if ( _strip.has_vpot() )
_mcp.notify_panner_changed( this );