summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gtk2_ardour/ardour.colors4
-rw-r--r--gtk2_ardour/ardour2_ui.rc75
-rw-r--r--gtk2_ardour/editor.cc25
-rw-r--r--gtk2_ardour/editor.h8
-rw-r--r--gtk2_ardour/editor_mixer.cc12
-rw-r--r--gtk2_ardour/editor_mouse.cc5
-rw-r--r--gtk2_ardour/editor_region_list.cc11
-rw-r--r--gtk2_ardour/editor_selection_list.cc122
-rw-r--r--gtk2_ardour/playlist_selector.cc1
-rw-r--r--gtk2_ardour/region_view.cc4
-rw-r--r--gtk2_ardour/route_ui.cc2
-rw-r--r--gtk2_ardour/time_axis_view_item.cc2
-rw-r--r--libs/ardour/ardour/crossfade.h3
-rw-r--r--libs/ardour/audio_playlist.cc12
-rw-r--r--libs/ardour/crossfade.cc434
-rw-r--r--libs/ardour/globals.cc4
-rw-r--r--libs/ardour/named_selection.cc13
-rw-r--r--libs/ardour/playlist.cc3
-rw-r--r--libs/ardour/session.cc58
-rw-r--r--libs/ardour/session_state.cc5
-rw-r--r--vst/ardourvst.in2
21 files changed, 443 insertions, 362 deletions
diff --git a/gtk2_ardour/ardour.colors b/gtk2_ardour/ardour.colors
index 097c72f6d8..456859162f 100644
--- a/gtk2_ardour/ardour.colors
+++ b/gtk2_ardour/ardour.colors
@@ -68,8 +68,8 @@ cEnteredAutomationLine 0.87 0.39 0.39 1.00
cEnteredMarker 0.87 0.39 0.39 1.00
cMeterMarker 0.95 0.26 0.36 1.00
cTempoMarker 0.95 0.26 0.36 1.00
-cMeasureLineBeat 0.40 0.40 0.40 0.50
-cMeasureLineBar 0.55 0.55 0.60 0.70
+cMeasureLineBeat 0.45 0.45 0.45 0.40
+cMeasureLineBar 0.55 0.55 0.60 0.55
cGhostTrackBaseOutline 0.00 0.00 0.00 1.00
cGhostTrackBaseFill 0.27 0.00 0.49 0.50
cImageTrackBase 0.87 0.87 0.85 1.00
diff --git a/gtk2_ardour/ardour2_ui.rc b/gtk2_ardour/ardour2_ui.rc
index 249edddbf4..a450e6d7dc 100644
--- a/gtk2_ardour/ardour2_ui.rc
+++ b/gtk2_ardour/ardour2_ui.rc
@@ -676,27 +676,44 @@ style "edit_group_3"
bg[SELECTED] = { 0.93, 0.34, 0.08 }
}
-style "region_list_display" = "small_bold_text"
+style "treeview_parent_node"
{
- fg[NORMAL] = { 0.80, 0.80, 0.80 }
- fg[ACTIVE] = { 0.80, 0.80, 0.80 }
- fg[SELECTED] = { 0.70, 0.70, 0.70 }
- bg[NORMAL] = { 0, 0, 0 }
- bg[ACTIVE] = { 0, 0, 0 }
- bg[SELECTED] = { 0, 0, 0 }
- base[NORMAL] = { 0, 0, 0 }
- base[ACTIVE] = { 0, 1, 0 }
- base[INSENSITIVE] = { 0, 0, 0 }
- base[SELECTED] = { 0.80, 0.80, 0.80 }
+ # specifies *just* the color used for whole file rows when not selected
+ fg[NORMAL] = { 0.0, 0.6, 0.85 }
+}
+
+style "treeview_display" = "small_bold_text"
+{
+ # expander arrow border and DnD "icon" text
+ fg[NORMAL] = { 0.8, 0.8, 0.8 }
+
+ # background with no rows or no selection, plus
+ # expander arrow core and DnD "icon" background
+ base[NORMAL] = { 0.20, 0.20, 0.25 }
+
+ # selected row bg when window does not have focus (including during DnD)
+ base[ACTIVE] = { 0.0, 0.60, 0.60 }
+
+ # selected row bg when window has focus
+ base[SELECTED] = { 0, 0.75, 0.75 }
+
+ # row text when in normal state and not a parent
+ text[NORMAL] = { 0.80, 0.80, 0.80 }
+
+ # selected row text with window focus
+ text[SELECTED] = { 0, 1.0, 1.0 }
+
+ # selected row text without window focus (including during DnD)
+ text[ACTIVE] = { 0, 1.0, 1.0 }
}
style "main_canvas_area"
{
- bg[NORMAL] = { 0.20, 0.20, 0.25 }
- bg[ACTIVE] = { 0.20, 0.20, 0.25 }
- bg[INSENSITIVE] = { 0.20, 0.20, 0.25 }
- bg[SELECTED] = { 0.20, 0.20, 0.25 }
- bg[PRELIGHT] = { 0.20, 0.20, 0.25 }
+ bg[NORMAL] = { 0.30, 0.30, 0.34 }
+ bg[ACTIVE] = { 0.30, 0.30, 0.34 }
+ bg[INSENSITIVE] = { 0.30, 0.30, 0.34 }
+ bg[SELECTED] = { 0.30, 0.30, 0.34 }
+ bg[PRELIGHT] = { 0.30, 0.30, 0.34 }
}
style "track_controls_inactive"
@@ -999,11 +1016,6 @@ style "pan_slider"
}
-style "region_list_whole_file"
-{
- fg[NORMAL] = { 0.4, 0.4, 0.9 }
-}
-
style "ardour_button" ="default_buttons_menus"
{
xthickness = 1
@@ -1189,7 +1201,6 @@ widget "*EditorTrackNameDisplay" style "track_name_display"
widget "*EditorTrackNameDisplay*" style "track_name_display"
widget "*EditorActiveTrackNameDisplay" style "active_track_name_display"
widget "*EditorActiveTrackNameDisplay*" style "active_track_name_display"
-widget "*EditorRegionList" style "region_list_display"
widget "*CrossfadeEditAuditionButton" style "red_when_active"
widget "*CrossfadeEditAuditionButton*" style "red_when_active"
widget "*CrossfadeEditCurveButton" style "red_when_active"
@@ -1221,19 +1232,19 @@ widget "*ParameterValueDisplay" style "medium_bold_entry"
widget "*PluginUIClickBox" style "medium_bold_entry"
widget "*PluginUIClickBox*" style "medium_bold_entry"
widget "*PluginSlider" style "plugin_slider"
-widget "*TrackListDisplay" style "track_list_display"
-widget "*TrackListDisplay.*" style "small_bold_text"
-widget "*EditGroupList" style "track_list_display"
-widget "*RegionListDisplay" style "small_bold_entry"
-widget "*RegionListDisplay.*" style "small_bold_text"
widget "*RedirectSelector" style "redirect_list_display"
widget "*RedirectSelector.*" style "redirect_list_display"
+widget "*EditGroupDisplay" style "treeview_display"
+widget "*TrackListDisplay" style "treeview_display"
+widget "*RegionListDisplay" style "treeview_display"
+widget "*NamedSelectionDisplay" style "treeview_display"
+widget "*SnapshotDisplay" style "treeview_display"
widget "*MixerTrackCommentArea" style "option_entry"
widget "*MixerPanZone" style "pan_zone"
-widget "*MixerTrackDisplayList" style "track_list_display"
-widget "*MixerSnapshotDisplayList" style "track_list_display"
-widget "*MixerAuxDisplayList" style "track_list_display"
-widget "*MixerGroupList" style "track_list_display"
+widget "*MixerTrackDisplayList" style "treeview_display"
+widget "*MixerSnapshotDisplayList" style "treeview_display"
+widget "*MixerAuxDisplayList" style "treeview_display"
+widget "*MixerGroupList" style "treeview_display"
widget "*RegionEditorLabel" style "medium_text"
widget "*RegionEditorSmallLabel" style "small_text"
widget "*RegionEditorEntry" style "medium_entry"
@@ -1360,7 +1371,7 @@ widget "*PanningLinkDirectionButton" style "very_small_button"
widget "*PanningLinkDirectionButton.*" style "very_small_button"
widget "*ChannelCountSelector" style "medium_bold_entry"
widget "*ChannelCountSelector.GtkArrow" style "default_buttons_menus"
-widget "*RegionListWholeFile" style "region_list_whole_file"
+widget "*RegionListWholeFile" style "treeview_parent_node"
class "GtkWidget" style "default_base"
class "GtkScrollbar" style "ardour_adjusters"
diff --git a/gtk2_ardour/editor.cc b/gtk2_ardour/editor.cc
index 77c731178c..c7c72dff2c 100644
--- a/gtk2_ardour/editor.cc
+++ b/gtk2_ardour/editor.cc
@@ -504,12 +504,11 @@ Editor::Editor (AudioEngine& eng)
active_cell->property_activatable() = true;
active_cell->property_radio() = false;
- edit_group_display.set_name ("EditGroupList");
-
group_model->signal_row_changed().connect (mem_fun (*this, &Editor::edit_group_row_change));
edit_group_display.set_name ("EditGroupList");
edit_group_display.get_selection()->set_mode (SELECTION_SINGLE);
+ edit_group_display.set_headers_visible (false);
edit_group_display.set_reorderable (false);
edit_group_display.set_rules_hint (true);
edit_group_display.set_size_request (75, -1);
@@ -595,11 +594,12 @@ Editor::Editor (AudioEngine& eng)
named_selection_display.append_column (_("Chunks"), named_selection_columns.text);
named_selection_display.set_headers_visible (false);
named_selection_display.set_size_request (100, -1);
- named_selection_display.set_name ("RegionListDisplay");
+ named_selection_display.set_name ("NamedSelectionDisplay");
named_selection_display.get_selection()->set_mode (SELECTION_SINGLE);
named_selection_display.set_size_request (100, -1);
- named_selection_display.signal_button_release_event().connect (mem_fun(*this, &Editor::named_selection_display_button_press), false);
+ named_selection_display.signal_button_release_event().connect (mem_fun(*this, &Editor::named_selection_display_button_release), false);
+ named_selection_display.signal_key_release_event().connect (mem_fun(*this, &Editor::named_selection_display_key_release), false);
named_selection_display.get_selection()->signal_changed().connect (mem_fun (*this, &Editor::named_selection_display_selection_changed));
/* SNAPSHOTS */
@@ -607,7 +607,7 @@ Editor::Editor (AudioEngine& eng)
snapshot_display_model = ListStore::create (snapshot_display_columns);
snapshot_display.set_model (snapshot_display_model);
snapshot_display.append_column (X_("snapshot"), snapshot_display_columns.visible_name);
- snapshot_display.set_name ("SnapshotDisplayList");
+ snapshot_display.set_name ("SnapshotDisplay");
snapshot_display.set_size_request (75, -1);
snapshot_display.set_headers_visible (false);
snapshot_display.set_reorderable (false);
@@ -1773,7 +1773,7 @@ Editor::add_selection_context_items (Menu_Helpers::MenuList& edit_items)
items.push_back (MenuElem (_("Crop region to range"), mem_fun(*this, &Editor::crop_region_to_selection)));
items.push_back (MenuElem (_("Fill range with region"), mem_fun(*this, &Editor::region_fill_selection)));
items.push_back (MenuElem (_("Duplicate range"), bind (mem_fun(*this, &Editor::duplicate_dialog), false)));
- items.push_back (MenuElem (_("Create chunk from range"), mem_fun(*this, &Editor::name_selection)));
+ items.push_back (MenuElem (_("Create chunk from range"), mem_fun(*this, &Editor::create_named_selection)));
items.push_back (SeparatorElem());
items.push_back (MenuElem (_("Bounce range"), mem_fun(*this, &Editor::bounce_range_selection)));
items.push_back (MenuElem (_("Export range"), mem_fun(*this, &Editor::export_selection)));
@@ -4020,15 +4020,16 @@ Editor::redisplay_snapshots ()
string statename = *(*i);
TreeModel::Row row = *(snapshot_display_model->append());
- // we don't have a way of changing the rendering in just one TreeView
- // cell so just put an asterisk on each side of the name for now.
+ /* this lingers on in case we ever want to change the visible
+ name of the snapshot.
+ */
+
string display_name;
+ display_name = statename;
+
if (statename == session->snap_name()) {
- display_name = "*"+statename+"*";
snapshot_display.get_selection()->select(row);
- } else {
- display_name = statename;
- }
+ }
row[snapshot_display_columns.visible_name] = display_name;
row[snapshot_display_columns.real_name] = statename;
diff --git a/gtk2_ardour/editor.h b/gtk2_ardour/editor.h
index c3c77c553b..80fa2ff4df 100644
--- a/gtk2_ardour/editor.h
+++ b/gtk2_ardour/editor.h
@@ -788,16 +788,16 @@ class Editor : public PublicEditor
Gtkmm2ext::DnDTreeView<ARDOUR::NamedSelection*> named_selection_display;
Gtk::ScrolledWindow named_selection_scroller;
- void name_selection();
- void named_selection_name_chosen ();
- void create_named_selection (const string &);
+ void create_named_selection ();
void paste_named_selection (float times);
+ void remove_selected_named_selections ();
void handle_new_named_selection ();
void add_named_selection_to_named_selection_display (ARDOUR::NamedSelection&);
void redisplay_named_selections ();
- gint named_selection_display_button_press (GdkEventButton *ev);
+ bool named_selection_display_button_release (GdkEventButton *ev);
+ bool named_selection_display_key_release (GdkEventKey *ev);
void named_selection_display_selection_changed ();
/* track views */
diff --git a/gtk2_ardour/editor_mixer.cc b/gtk2_ardour/editor_mixer.cc
index 8139e91ca7..bdb934e8e0 100644
--- a/gtk2_ardour/editor_mixer.cc
+++ b/gtk2_ardour/editor_mixer.cc
@@ -282,11 +282,21 @@ Editor::session_going_away ()
/* rip everything out of the list displays */
- region_list_clear (); // no clear() method in gtkmm 1.2
+ region_list_display.set_model (Glib::RefPtr<Gtk::TreeStore>(0));
+ route_list_display.set_model (Glib::RefPtr<Gtk::TreeStore>(0));
+ named_selection_display.set_model (Glib::RefPtr<Gtk::TreeStore>(0));
+ edit_group_display.set_model (Glib::RefPtr<Gtk::TreeStore>(0));
+
+ region_list_model->clear ();
route_display_model->clear ();
named_selection_model->clear ();
group_model->clear ();
+ region_list_display.set_model (region_list_model);
+ route_list_display.set_model (route_display_model);
+ named_selection_display.set_model (named_selection_model);
+ edit_group_display.set_model (group_model);
+
edit_cursor_clock.set_session (0);
zoom_range_clock.set_session (0);
nudge_clock.set_session (0);
diff --git a/gtk2_ardour/editor_mouse.cc b/gtk2_ardour/editor_mouse.cc
index fc76c6a43c..01ea203c61 100644
--- a/gtk2_ardour/editor_mouse.cc
+++ b/gtk2_ardour/editor_mouse.cc
@@ -2800,7 +2800,6 @@ Editor::region_drag_motion_callback (ArdourCanvas::Item* item, GdkEvent* event)
set<boost::shared_ptr<Playlist> > affected_playlists;
pair<set<boost::shared_ptr<Playlist> >::iterator,bool> insert_result;
- // TODO: Crossfades need to be copied!
for (list<RegionView*>::const_iterator i = selection->regions.by_layer().begin(); i != selection->regions.by_layer().end(); ++i) {
RegionView* rv;
@@ -2808,7 +2807,7 @@ Editor::region_drag_motion_callback (ArdourCanvas::Item* item, GdkEvent* event)
boost::shared_ptr<Playlist> to_playlist = rv->region()->playlist();
RouteTimeAxisView* rtv = dynamic_cast<RouteTimeAxisView*>(&rv->get_time_axis_view());
-
+
insert_result = affected_playlists.insert (to_playlist);
if (insert_result.second) {
session->add_command (new MementoCommand<Playlist>(*to_playlist, &to_playlist->get_state(), 0));
@@ -3223,7 +3222,7 @@ Editor::region_drag_motion_callback (ArdourCanvas::Item* item, GdkEvent* event)
/* hide any dependent views */
-// rv->get_time_axis_view().hide_dependent_views (*rv);
+ rv->get_time_axis_view().hide_dependent_views (*rv);
/* this is subtle. raising the regionview itself won't help,
because raise_to_top() just puts the item on the top of
diff --git a/gtk2_ardour/editor_region_list.cc b/gtk2_ardour/editor_region_list.cc
index bc95cb0d14..97512c06e8 100644
--- a/gtk2_ardour/editor_region_list.cc
+++ b/gtk2_ardour/editor_region_list.cc
@@ -50,7 +50,8 @@ using namespace Editing;
void
Editor::handle_region_removed (boost::weak_ptr<Region> wregion)
{
- ENSURE_GUI_THREAD (bind (mem_fun (*this, &Editor::handle_region_removed), wregion));
+ cerr << "removed region\n";
+ ENSURE_GUI_THREAD (mem_fun (*this, &Editor::redisplay_regions));
redisplay_regions ();
}
@@ -256,12 +257,6 @@ Editor::redisplay_regions ()
}
void
-Editor::region_list_clear ()
-{
- region_list_model->clear();
-}
-
-void
Editor::build_region_list_menu ()
{
region_list_menu = dynamic_cast<Menu*>(ActionManager::get_widget ("/RegionListMenu"));
@@ -562,6 +557,7 @@ Editor::hide_a_region (boost::shared_ptr<Region> r)
void
Editor::remove_a_region (boost::shared_ptr<Region> r)
{
+ cerr << "remove " << r->name();
session->remove_region_from_region_list (r);
}
@@ -580,6 +576,7 @@ Editor::hide_region_from_region_list ()
void
Editor::remove_region_from_region_list ()
{
+ cerr << "Mapping remove over region selection\n";
region_list_selection_mapover (mem_fun (*this, &Editor::remove_a_region));
}
diff --git a/gtk2_ardour/editor_selection_list.cc b/gtk2_ardour/editor_selection_list.cc
index 8e88ee497b..864e527b59 100644
--- a/gtk2_ardour/editor_selection_list.cc
+++ b/gtk2_ardour/editor_selection_list.cc
@@ -65,10 +65,48 @@ Editor::redisplay_named_selections ()
session->foreach_named_selection (*this, &Editor::add_named_selection_to_named_selection_display);
}
-gint
-Editor::named_selection_display_button_press (GdkEventButton *ev)
+bool
+Editor::named_selection_display_key_release (GdkEventKey* ev)
{
+ if (session == 0) {
+ return true;
+ }
+
+ switch (ev->keyval) {
+ case GDK_Delete:
+ remove_selected_named_selections ();
+ return true;
+ break;
+ default:
+ return false;
+ break;
+ }
+
+}
+
+void
+Editor::remove_selected_named_selections ()
+{
+ Glib::RefPtr<TreeSelection> selection = named_selection_display.get_selection();
+ TreeView::Selection::ListHandle_Path rows = selection->get_selected_rows ();
+
+ if (selection->count_selected_rows() == 0) {
+ return;
+ }
+
+ for (TreeView::Selection::ListHandle_Path::iterator i = rows.begin(); i != rows.end(); ++i) {
+
+ TreeIter iter;
+ if ((iter = named_selection_model->get_iter (*i))) {
+ session->remove_named_selection ((*iter)[named_selection_columns.selection]);
+ }
+ }
+}
+
+bool
+Editor::named_selection_display_button_release (GdkEventButton *ev)
+{
TreeModel::Children rows = named_selection_model->children();
TreeModel::Children::iterator i;
Glib::RefPtr<TreeSelection> selection = named_selection_display.get_selection();
@@ -91,7 +129,8 @@ Editor::named_selection_display_button_press (GdkEventButton *ev)
}
}
}
- return FALSE;
+
+ return false;
}
@@ -101,37 +140,10 @@ Editor::named_selection_display_selection_changed ()
}
void
-Editor::name_selection ()
+Editor::create_named_selection ()
{
- ArdourPrompter p;
-
- p.set_prompt (_("Name for Chunk:"));
- p.add_button (Gtk::Stock::NEW, Gtk::RESPONSE_ACCEPT);
- p.set_response_sensitive (Gtk::RESPONSE_ACCEPT, false);
- p.change_labels (_("Create Chunk"), _("Forget it"));
- p.show_all ();
-
- switch (p.run ()) {
- case Gtk::RESPONSE_ACCEPT:
- string name;
- p.get_result (name);
- if (name.length()) {
- create_named_selection (name);
- }
- break;
- }
+ string name;
-}
-
-void
-Editor::named_selection_name_chosen ()
-{
- Gtk::Main::quit ();
-}
-
-void
-Editor::create_named_selection (const string & name)
-{
if (session == 0) {
return;
}
@@ -141,7 +153,6 @@ Editor::create_named_selection (const string & name)
if (selection->time.empty()) {
return;
}
-
TrackViewList *views = get_valid_views (selection->time.track, selection->time.group);
@@ -157,25 +168,42 @@ Editor::create_named_selection (const string & name)
boost::shared_ptr<Playlist> pl = (*i)->playlist();
- if (pl) {
-
- if ((what_we_found = pl->copy (selection->time, false)) != 0) {
-
- thelist.push_back (what_we_found);
- }
+ if (pl && (what_we_found = pl->copy (selection->time, false)) != 0) {
+ thelist.push_back (what_we_found);
}
}
- NamedSelection* ns;
- TreeModel::Row row = *(named_selection_model->append());
-
- ns = new NamedSelection (name, thelist);
- row[named_selection_columns.selection] = ns;
- row[named_selection_columns.text] = name;
+ if (!thelist.empty()) {
- /* make the one we just added be selected */
+ ArdourPrompter p;
+
+ p.set_prompt (_("Name for Chunk:"));
+ p.add_button (Gtk::Stock::NEW, Gtk::RESPONSE_ACCEPT);
+ p.set_response_sensitive (Gtk::RESPONSE_ACCEPT, false);
+ p.change_labels (_("Create Chunk"), _("Forget it"));
+ p.show_all ();
+
+ switch (p.run ()) {
+
+ case Gtk::RESPONSE_ACCEPT:
+ p.get_result (name);
+ if (name.empty()) {
+ return;
+ }
+ break;
+ default:
+ return;
+ }
- named_selection_display.get_selection()->select (row);
+ new NamedSelection (name, thelist); // creation will add it to the model
+ /* make the one we just added be selected */
+
+ TreeModel::Children::iterator added = named_selection_model->children().end();
+ --added;
+ named_selection_display.get_selection()->select (*added);
+ } else {
+ error << _("No selectable material found in the currently selected time range") << endmsg;
+ }
}
diff --git a/gtk2_ardour/playlist_selector.cc b/gtk2_ardour/playlist_selector.cc
index d02c5a88de..ddb771bb18 100644
--- a/gtk2_ardour/playlist_selector.cc
+++ b/gtk2_ardour/playlist_selector.cc
@@ -88,7 +88,6 @@ PlaylistSelector::clear_map ()
bool
PlaylistSelector::on_unmap_event (GdkEventAny* ev)
{
- cerr << "PLselector unmapped\n";
clear_map ();
if (model) {
model->clear ();
diff --git a/gtk2_ardour/region_view.cc b/gtk2_ardour/region_view.cc
index a9315bb76f..aff5866c8d 100644
--- a/gtk2_ardour/region_view.cc
+++ b/gtk2_ardour/region_view.cc
@@ -367,9 +367,9 @@ void
RegionView::set_frame_color ()
{
if (_region->opaque()) {
- fill_opacity = 230;
+ fill_opacity = 130;
} else {
- fill_opacity = 100;
+ fill_opacity = 60;
}
TimeAxisViewItem::set_frame_color ();
diff --git a/gtk2_ardour/route_ui.cc b/gtk2_ardour/route_ui.cc
index 070ad42037..e7fa77f4da 100644
--- a/gtk2_ardour/route_ui.cc
+++ b/gtk2_ardour/route_ui.cc
@@ -446,7 +446,7 @@ RouteUI::refresh_remote_control_menu ()
RadioMenuItem::Group rc_group;
CheckMenuItem* rc_active;
- uint32_t limit = _session.ntracks();
+ uint32_t limit = _session.ntracks() + _session.nbusses();
char buf[32];
MenuList& rc_items = remote_control_menu->items();
diff --git a/gtk2_ardour/time_axis_view_item.cc b/gtk2_ardour/time_axis_view_item.cc
index 6af38deaee..a008e2af1a 100644
--- a/gtk2_ardour/time_axis_view_item.cc
+++ b/gtk2_ardour/time_axis_view_item.cc
@@ -102,7 +102,7 @@ TimeAxisViewItem::TimeAxisViewItem(const string & it_name, ArdourCanvas::Group&
frame_position = start ;
item_duration = duration ;
name_connected = false;
- fill_opacity = 230;
+ fill_opacity = 130;
position_locked = false ;
max_item_duration = ARDOUR::max_frames;
min_item_duration = 0 ;
diff --git a/libs/ardour/ardour/crossfade.h b/libs/ardour/ardour/crossfade.h
index 946d35b8e0..62ab1f775d 100644
--- a/libs/ardour/ardour/crossfade.h
+++ b/libs/ardour/ardour/crossfade.h
@@ -157,6 +157,7 @@ class Crossfade : public PBD::StatefulDestructible, public boost::enable_shared_
AnchorPoint _anchor_point;
bool _follow_overlap;
bool _fixed;
+ int32_t layer_relation;
Curve _fade_in;
Curve _fade_out;
@@ -165,7 +166,7 @@ class Crossfade : public PBD::StatefulDestructible, public boost::enable_shared_
void initialize ();
int compute (boost::shared_ptr<ARDOUR::AudioRegion>, boost::shared_ptr<ARDOUR::AudioRegion>, CrossfadeModel);
- bool update (bool force);
+ bool update ();
void member_changed (ARDOUR::Change);
};
diff --git a/libs/ardour/audio_playlist.cc b/libs/ardour/audio_playlist.cc
index dcba0ae31c..a6d73e8544 100644
--- a/libs/ardour/audio_playlist.cc
+++ b/libs/ardour/audio_playlist.cc
@@ -277,9 +277,14 @@ AudioPlaylist::refresh_dependents (boost::shared_ptr<Region> r)
if ((*x)->involves (ar)) {
if (find (updated.begin(), updated.end(), *x) == updated.end()) {
- if ((*x)->refresh ()) {
- /* not invalidated by the refresh */
- updated.insert (*x);
+ try {
+ if ((*x)->refresh ()) {
+ updated.insert (*x);
+ }
+ }
+
+ catch (Crossfade::NoCrossfadeHere& err) {
+ // relax, Invalidated during refresh
}
}
}
@@ -353,6 +358,7 @@ AudioPlaylist::check_dependents (boost::shared_ptr<Region> r, bool norefresh)
refresh_dependents (r);
}
+
if (!Config->get_auto_xfade()) {
return;
}
diff --git a/libs/ardour/crossfade.cc b/libs/ardour/crossfade.cc
index 31970a7646..bd5f908380 100644
--- a/libs/ardour/crossfade.cc
+++ b/libs/ardour/crossfade.cc
@@ -87,13 +87,7 @@ Crossfade::Crossfade (boost::shared_ptr<AudioRegion> in, boost::shared_ptr<Audio
_position = position;
_anchor_point = ap;
- switch (Config->get_xfade_model()) {
- case ShortCrossfade:
- _follow_overlap = false;
- break;
- default:
- _follow_overlap = true;
- }
+ _follow_overlap = false;
_active = Config->get_xfades_active ();
_fixed = true;
@@ -115,7 +109,6 @@ Crossfade::Crossfade (boost::shared_ptr<AudioRegion> a, boost::shared_ptr<AudioR
_active = act;
initialize ();
-
}
Crossfade::Crossfade (const Playlist& playlist, XMLNode& node)
@@ -192,6 +185,7 @@ Crossfade::Crossfade (const Crossfade &orig, boost::shared_ptr<AudioRegion> newi
_in->suspend_fade_in ();
overlap_type = _in->coverage (_out->position(), _out->last_frame());
+ layer_relation = (int32_t) (_in->layer() - _out->layer());
// Let's make sure the fade isn't too long
set_length(_length);
@@ -200,7 +194,6 @@ Crossfade::Crossfade (const Crossfade &orig, boost::shared_ptr<AudioRegion> newi
Crossfade::~Crossfade ()
{
- cerr << "Crossfade deleted\n";
notify_callbacks ();
}
@@ -232,12 +225,212 @@ Crossfade::initialize ()
_fade_in.add (_length, 1.0);
_fade_in.thaw ();
- _in->StateChanged.connect (sigc::mem_fun (*this, &Crossfade::member_changed));
- _out->StateChanged.connect (sigc::mem_fun (*this, &Crossfade::member_changed));
+ // _in->StateChanged.connect (sigc::mem_fun (*this, &Crossfade::member_changed));
+ // _out->StateChanged.connect (sigc::mem_fun (*this, &Crossfade::member_changed));
overlap_type = _in->coverage (_out->position(), _out->last_frame());
+ layer_relation = (int32_t) (_in->layer() - _out->layer());
}
+nframes_t
+Crossfade::read_at (Sample *buf, Sample *mixdown_buffer,
+ float *gain_buffer, nframes_t start, nframes_t cnt, uint32_t chan_n,
+ nframes_t read_frames, nframes_t skip_frames)
+{
+ nframes_t offset;
+ nframes_t to_write;
+
+ if (!_active) {
+ return 0;
+ }
+
+ if (start < _position) {
+
+ /* handle an initial section of the read area that we do not
+ cover.
+ */
+
+ offset = _position - start;
+
+ if (offset < cnt) {
+ cnt -= offset;
+ } else {
+ return 0;
+ }
+
+ start = _position;
+ buf += offset;
+ to_write = min (_length, cnt);
+
+ } else {
+
+ to_write = min (_length - (start - _position), cnt);
+
+ }
+
+ offset = start - _position;
+
+ _out->read_at (crossfade_buffer_out, mixdown_buffer, gain_buffer, start, to_write, chan_n, read_frames, skip_frames);
+ _in->read_at (crossfade_buffer_in, mixdown_buffer, gain_buffer, start, to_write, chan_n, read_frames, skip_frames);
+
+ float* fiv = new float[to_write];
+ float* fov = new float[to_write];
+
+ _fade_in.get_vector (offset, offset+to_write, fiv, to_write);
+ _fade_out.get_vector (offset, offset+to_write, fov, to_write);
+
+ /* note: although we have not explicitly taken into account the return values
+ from _out->read_at() or _in->read_at(), the length() function does this
+ implicitly. why? because it computes a value based on the in+out regions'
+ position and length, and so we know precisely how much data they could return.
+ */
+
+ for (nframes_t n = 0; n < to_write; ++n) {
+ buf[n] = (crossfade_buffer_out[n] * fov[n]) + (crossfade_buffer_in[n] * fiv[n]);
+ }
+
+ delete [] fov;
+ delete [] fiv;
+
+ return to_write;
+}
+
+OverlapType
+Crossfade::coverage (nframes_t start, nframes_t end) const
+{
+ nframes_t my_end = _position + _length;
+
+ if ((start >= _position) && (end <= my_end)) {
+ return OverlapInternal;
+ }
+ if ((end >= _position) && (end <= my_end)) {
+ return OverlapStart;
+ }
+ if ((start >= _position) && (start <= my_end)) {
+ return OverlapEnd;
+ }
+ if ((_position >= start) && (_position <= end) && (my_end <= end)) {
+ return OverlapExternal;
+ }
+ return OverlapNone;
+}
+
+void
+Crossfade::set_active (bool yn)
+{
+ if (_active != yn) {
+ _active = yn;
+ StateChanged (ActiveChanged);
+ }
+}
+
+bool
+Crossfade::refresh ()
+{
+ /* crossfades must be between non-muted regions */
+
+ if (_out->muted() || _in->muted()) {
+ Invalidated (shared_from_this());
+ return false;
+ }
+
+ /* layer ordering cannot change */
+
+ int32_t new_layer_relation = (int32_t) (_in->layer() - _out->layer());
+
+ if (new_layer_relation * layer_relation < 0) { // different sign, layers rotated
+ Invalidated (shared_from_this());
+ return false;
+ }
+
+ OverlapType ot = _in->coverage (_out->first_frame(), _out->last_frame());
+
+ if (ot == OverlapNone) {
+ Invalidated (shared_from_this());
+ return false;
+ }
+
+ bool send_signal;
+
+ if (ot != overlap_type) {
+
+ if (_follow_overlap) {
+
+ try {
+ compute (_in, _out, Config->get_xfade_model());
+ }
+
+ catch (NoCrossfadeHere& err) {
+ Invalidated (shared_from_this());
+ return false;
+ }
+
+ send_signal = true;
+
+ } else {
+
+ Invalidated (shared_from_this());
+ return false;
+ }
+
+ } else {
+
+ send_signal = update ();
+ }
+
+ if (send_signal) {
+ StateChanged (BoundsChanged); /* EMIT SIGNAL */
+ }
+
+ _in_update = false;
+
+ return true;
+}
+
+bool
+Crossfade::update ()
+{
+ nframes_t newlen;
+
+ if (_follow_overlap) {
+ newlen = _out->first_frame() + _out->length() - _in->first_frame();
+ } else {
+ newlen = _length;
+ }
+
+ if (newlen == 0) {
+ Invalidated (shared_from_this());
+ return false;
+ }
+
+ _in_update = true;
+
+ if ((_follow_overlap && newlen != _length) || (_length > newlen)) {
+
+ double factor = newlen / (double) _length;
+
+ _fade_out.x_scale (factor);
+ _fade_in.x_scale (factor);
+
+ _length = newlen;
+ }
+
+ switch (_anchor_point) {
+ case StartOfIn:
+ _position = _in->first_frame();
+ break;
+
+ case EndOfIn:
+ _position = _in->last_frame() - _length;
+ break;
+
+ case EndOfOut:
+ _position = _out->last_frame() - _length;
+ }
+
+ return true;
+}
+
int
Crossfade::compute (boost::shared_ptr<AudioRegion> a, boost::shared_ptr<AudioRegion> b, CrossfadeModel model)
{
@@ -259,8 +452,6 @@ Crossfade::compute (boost::shared_ptr<AudioRegion> a, boost::shared_ptr<AudioReg
if (top->first_frame() == bottom->first_frame()) {
- cerr << "same start\n";
-
/* Both regions start at the same point */
if (top->last_frame() < bottom->last_frame()) {
@@ -301,8 +492,6 @@ Crossfade::compute (boost::shared_ptr<AudioRegion> a, boost::shared_ptr<AudioReg
} else if (top->last_frame() == bottom->last_frame()) {
- cerr << "same end\n";
-
/* Both regions end at the same point */
if (top->first_frame() > bottom->first_frame()) {
@@ -341,21 +530,17 @@ Crossfade::compute (boost::shared_ptr<AudioRegion> a, boost::shared_ptr<AudioReg
OverlapType ot = top->coverage (bottom->first_frame(), bottom->last_frame());
- cerr << "ot = " << ot << endl;
-
switch (ot) {
case OverlapNone:
/* should be NOTREACHED as a precondition of creating
a new crossfade, but we need to handle it here.
*/
- cerr << "no sir\n";
throw NoCrossfadeHere();
break;
case OverlapInternal:
case OverlapExternal:
/* should be NOTREACHED because of tests above */
- cerr << "nu-uh\n";
throw NoCrossfadeHere();
break;
@@ -412,207 +597,6 @@ Crossfade::compute (boost::shared_ptr<AudioRegion> a, boost::shared_ptr<AudioReg
return 0;
}
-nframes_t
-Crossfade::read_at (Sample *buf, Sample *mixdown_buffer,
- float *gain_buffer, nframes_t start, nframes_t cnt, uint32_t chan_n,
- nframes_t read_frames, nframes_t skip_frames)
-{
- nframes_t offset;
- nframes_t to_write;
-
- if (!_active) {
- return 0;
- }
-
- if (start < _position) {
-
- /* handle an initial section of the read area that we do not
- cover.
- */
-
- offset = _position - start;
-
- if (offset < cnt) {
- cnt -= offset;
- } else {
- return 0;
- }
-
- start = _position;
- buf += offset;
- to_write = min (_length, cnt);
-
- } else {
-
- to_write = min (_length - (start - _position), cnt);
-
- }
-
- offset = start - _position;
-
- _out->read_at (crossfade_buffer_out, mixdown_buffer, gain_buffer, start, to_write, chan_n, read_frames, skip_frames);
- _in->read_at (crossfade_buffer_in, mixdown_buffer, gain_buffer, start, to_write, chan_n, read_frames, skip_frames);
-
- float* fiv = new float[to_write];
- float* fov = new float[to_write];
-
- _fade_in.get_vector (offset, offset+to_write, fiv, to_write);
- _fade_out.get_vector (offset, offset+to_write, fov, to_write);
-
- /* note: although we have not explicitly taken into account the return values
- from _out->read_at() or _in->read_at(), the length() function does this
- implicitly. why? because it computes a value based on the in+out regions'
- position and length, and so we know precisely how much data they could return.
- */
-
- for (nframes_t n = 0; n < to_write; ++n) {
- buf[n] = (crossfade_buffer_out[n] * fov[n]) + (crossfade_buffer_in[n] * fiv[n]);
- }
-
- delete [] fov;
- delete [] fiv;
-
- return to_write;
-}
-
-OverlapType
-Crossfade::coverage (nframes_t start, nframes_t end) const
-{
- nframes_t my_end = _position + _length;
-
- if ((start >= _position) && (end <= my_end)) {
- return OverlapInternal;
- }
- if ((end >= _position) && (end <= my_end)) {
- return OverlapStart;
- }
- if ((start >= _position) && (start <= my_end)) {
- return OverlapEnd;
- }
- if ((_position >= start) && (_position <= end) && (my_end <= end)) {
- return OverlapExternal;
- }
- return OverlapNone;
-}
-
-void
-Crossfade::set_active (bool yn)
-{
- if (_active != yn) {
- _active = yn;
- StateChanged (ActiveChanged);
- }
-}
-
-bool
-Crossfade::refresh ()
-{
- /* crossfades must be between non-muted regions */
-
- if (_out->muted() || _in->muted()) {
- Invalidated (shared_from_this());
- return false;
- }
-
- if (_in->layer() < _out->layer()) {
- cerr << "layer change, invalidated\n";
- Invalidated (shared_from_this());
- return false;
- }
-
- /* overlap type must be Start, End or External */
-
- OverlapType ot;
-
- ot = _in->coverage (_out->first_frame(), _out->last_frame());
-
- switch (ot) {
- case OverlapNone:
- case OverlapInternal:
- Invalidated (shared_from_this());
- return false;
-
- default:
- break;
- }
-
- /* overlap type must not have altered */
-
- if (ot != overlap_type) {
- Invalidated (shared_from_this());
- return false;
- }
-
- /* time to update */
-
- return update (false);
-}
-
-bool
-Crossfade::update (bool force)
-{
- nframes_t newlen;
-
- if (_follow_overlap) {
- newlen = _out->first_frame() + _out->length() - _in->first_frame();
- } else {
- newlen = _length;
- }
-
- if (newlen == 0) {
- Invalidated (shared_from_this());
- return false;
- }
-
- _in_update = true;
-
- if (force || (_follow_overlap && newlen != _length) || (_length > newlen)) {
-
- double factor = newlen / (double) _length;
-
- _fade_out.x_scale (factor);
- _fade_in.x_scale (factor);
-
- _length = newlen;
-
- }
-
- switch (_anchor_point) {
- case StartOfIn:
- if (_position != _in->first_frame()) {
- if (_length > _short_xfade_length) {
- /* assume FullCrossfade */
- _position = _in->first_frame();
- } else {
- /* assume short xfade */
- _position = _out->last_frame() - _length;
- }
- }
- break;
-
- case EndOfIn:
- if (_position != _in->last_frame() - _length) {
- _position = _in->last_frame() - _length;
- }
- break;
-
- case EndOfOut:
- if (_position != _out->last_frame() - _length) {
- _position = _out->last_frame() - _length;
- }
- }
-
- /* UI's may need to know that the overlap changed even
- though the xfade length did not.
- */
-
- StateChanged (BoundsChanged); /* EMIT SIGNAL */
-
- _in_update = false;
-
- return true;
-}
-
void
Crossfade::member_changed (Change what_changed)
{
@@ -621,7 +605,15 @@ Crossfade::member_changed (Change what_changed)
BoundsChanged);
if (what_changed & what_we_care_about) {
- refresh ();
+ try {
+ if (what_changed & what_we_care_about) {
+ refresh ();
+ }
+ }
+
+ catch (NoCrossfadeHere& err) {
+ // relax, Invalidated inside refresh()
+ }
}
}
diff --git a/libs/ardour/globals.cc b/libs/ardour/globals.cc
index 2806ab60a8..549f4b7dbb 100644
--- a/libs/ardour/globals.cc
+++ b/libs/ardour/globals.cc
@@ -211,7 +211,7 @@ setup_hardware_optimization (bool try_optimization)
"cpuid\n"
"movl %%edx, %0\n"
"popl %%ebx\n"
- : "=l" (use_sse)
+ : "=r" (use_sse)
:
: "%eax", "%ecx", "%edx", "memory");
@@ -223,7 +223,7 @@ setup_hardware_optimization (bool try_optimization)
"cpuid\n"
"movq %%rdx, %0\n"
"popq %%rbx\n"
- : "=l" (use_sse)
+ : "=r" (use_sse)
:
: "%rax", "%rcx", "%rdx", "memory");
diff --git a/libs/ardour/named_selection.cc b/libs/ardour/named_selection.cc
index ecce09692f..b5a71f6403 100644
--- a/libs/ardour/named_selection.cc
+++ b/libs/ardour/named_selection.cc
@@ -40,8 +40,18 @@ NamedSelection::NamedSelection (string n, PlaylistList& l)
{
playlists = l;
for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
+ string new_name;
+
+ /* rename playlists to reflect our ownership */
+
+ new_name = name;
+ new_name += '/';
+ new_name += (*i)->name();
+
+ (*i)->set_name (new_name);
(*i)->use();
}
+
NamedSelectionCreated (this);
}
@@ -90,7 +100,8 @@ NamedSelection::NamedSelection (Session& session, const XMLNode& node)
NamedSelection::~NamedSelection ()
{
for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
- (*i)->release();
+ (*i)->release ();
+ (*i)->GoingAway ();
}
}
diff --git a/libs/ardour/playlist.cc b/libs/ardour/playlist.cc
index 2becdc19b4..099b4dabbb 100644
--- a/libs/ardour/playlist.cc
+++ b/libs/ardour/playlist.cc
@@ -209,7 +209,6 @@ Playlist::release ()
}
}
-
void
Playlist::copy_regions (RegionList& newlist) const
{
@@ -1709,6 +1708,7 @@ Playlist::move_region_to_layer (layer_t target_layer, boost::shared_ptr<Region>
region->set_layer (target_layer);
+#if 0
/* now check all dependents */
for (list<LayerInfo>::iterator x = layerinfo.begin(); x != layerinfo.end(); ++x) {
@@ -1716,6 +1716,7 @@ Playlist::move_region_to_layer (layer_t target_layer, boost::shared_ptr<Region>
}
check_dependents (region, false);
+#endif
return 0;
}
diff --git a/libs/ardour/session.cc b/libs/ardour/session.cc
index eb9e1c69ca..c4a5e5fe0a 100644
--- a/libs/ardour/session.cc
+++ b/libs/ardour/session.cc
@@ -366,23 +366,34 @@ Session::Session (AudioEngine &eng,
}
}
- if (control_out_channels) {
- shared_ptr<Route> r (new Route (*this, _("monitor"), -1, control_out_channels, -1, control_out_channels, Route::ControlOut));
- RouteList rl;
- rl.push_back (r);
- add_routes (rl);
- _control_out = r;
- }
-
- if (master_out_channels) {
- shared_ptr<Route> r (new Route (*this, _("master"), -1, master_out_channels, -1, master_out_channels, Route::MasterOut));
+ {
+ /* set up Master Out and Control Out if necessary */
+
RouteList rl;
- rl.push_back (r);
- add_routes (rl);
- _master_out = r;
- } else {
- /* prohibit auto-connect to master, because there isn't one */
- output_ac = AutoConnectOption (output_ac & ~AutoConnectMaster);
+ int control_id = 1;
+
+ if (control_out_channels) {
+ shared_ptr<Route> r (new Route (*this, _("monitor"), -1, control_out_channels, -1, control_out_channels, Route::ControlOut));
+ r->set_remote_control_id (control_id++);
+
+ rl.push_back (r);
+ }
+
+ if (master_out_channels) {
+ shared_ptr<Route> r (new Route (*this, _("master"), -1, master_out_channels, -1, master_out_channels, Route::MasterOut));
+ r->set_remote_control_id (control_id);
+ cerr << "master bus has remote control ID " << r->remote_control_id() << endl;
+
+ rl.push_back (r);
+ } else {
+ /* prohibit auto-connect to master, because there isn't one */
+ output_ac = AutoConnectOption (output_ac & ~AutoConnectMaster);
+ }
+
+ if (!rl.empty()) {
+ add_routes (rl);
+ }
+
}
Config->set_input_auto_connect (input_ac);
@@ -1695,7 +1706,7 @@ Session::new_audio_track (int input_channels, int output_channels, TrackMode mod
_engine.get_physical_outputs (physoutputs);
_engine.get_physical_inputs (physinputs);
- control_id = 0;
+ control_id = ntracks() + nbusses() + 1;
while (how_many) {
@@ -1784,7 +1795,7 @@ Session::new_audio_track (int input_channels, int output_channels, TrackMode mod
}
track->DiskstreamChanged.connect (mem_fun (this, &Session::resort_routes));
- track->set_remote_control_id (ntracks() + control_id + 1);
+ track->set_remote_control_id (control_id);
++control_id;
new_routes.push_back (track);
@@ -1817,6 +1828,7 @@ Session::new_audio_route (int input_channels, int output_channels, uint32_t how_
uint32_t n = 0;
string port;
RouteList ret;
+ uint32_t control_id;
/* count existing audio busses */
@@ -1837,6 +1849,7 @@ Session::new_audio_route (int input_channels, int output_channels, uint32_t how_
_engine.get_physical_outputs (physoutputs);
_engine.get_physical_inputs (physinputs);
+ control_id = ntracks() + nbusses() + 1;
while (how_many) {
@@ -1900,6 +1913,9 @@ Session::new_audio_route (int input_channels, int output_channels, uint32_t how_
bus->set_control_outs (cports);
}
+ bus->set_remote_control_id (control_id);
+ ++control_id;
+
ret.push_back (bus);
}
@@ -3788,9 +3804,13 @@ Session::add_named_selection (NamedSelection* named_selection)
named_selections.insert (named_selections.begin(), named_selection);
}
+ for (list<boost::shared_ptr<Playlist> >::iterator i = named_selection->playlists.begin(); i != named_selection->playlists.end(); ++i) {
+ add_playlist (*i);
+ }
+
set_dirty();
- NamedSelectionAdded (); /* EMIT SIGNAL */
+ NamedSelectionAdded (); /* EMIT SIGNAL */
}
void
diff --git a/libs/ardour/session_state.cc b/libs/ardour/session_state.cc
index 097a9e2381..37f7b2c32f 100644
--- a/libs/ardour/session_state.cc
+++ b/libs/ardour/session_state.cc
@@ -3242,8 +3242,11 @@ Session::config_changed (const char* parameter_name)
}
first_file_data_format_reset = false;
+
+ } else if (PARAM_IS ("slave-source")) {
+ set_slave_source (Config->get_slave_source());
}
-
+
set_dirty ();
#undef PARAM_IS
diff --git a/vst/ardourvst.in b/vst/ardourvst.in
index 8297e1870b..2accc5cfb9 100644
--- a/vst/ardourvst.in
+++ b/vst/ardourvst.in
@@ -4,5 +4,7 @@
# but somehow scons puts leading /'s on INSTALL_PREFIX and that causes
# wine to be unable to find the .exe.so file
+export GTK_PATH=%PREFIX%/lib/ardour2:$GTK_PATH
+
LD_LIBRARY_PATH=%PREFIX%/lib/ardour2:$LD_LIBRARY_PATH exec wine %PREFIX%/lib/ardour2/ardour_vst.exe.so "$@"