Merged with trunk R1327.
authorDavid Robillard <d@drobilla.net>
Mon, 15 Jan 2007 18:33:54 +0000 (18:33 +0000)
committerDavid Robillard <d@drobilla.net>
Mon, 15 Jan 2007 18:33:54 +0000 (18:33 +0000)
git-svn-id: svn://localhost/ardour2/branches/midi@1328 d708f5d6-7413-0410-9779-e7cbd77b26cf

21 files changed:
gtk2_ardour/ardour.colors
gtk2_ardour/ardour2_ui.rc
gtk2_ardour/editor.cc
gtk2_ardour/editor.h
gtk2_ardour/editor_mixer.cc
gtk2_ardour/editor_mouse.cc
gtk2_ardour/editor_region_list.cc
gtk2_ardour/editor_selection_list.cc
gtk2_ardour/playlist_selector.cc
gtk2_ardour/region_view.cc
gtk2_ardour/route_ui.cc
gtk2_ardour/time_axis_view_item.cc
libs/ardour/ardour/crossfade.h
libs/ardour/audio_playlist.cc
libs/ardour/crossfade.cc
libs/ardour/globals.cc
libs/ardour/named_selection.cc
libs/ardour/playlist.cc
libs/ardour/session.cc
libs/ardour/session_state.cc
vst/ardourvst.in

index 097c72f6d88dd5585e943b935852870a96054256..456859162f0876d8cc299ce0e240c699b4cdab51 100644 (file)
@@ -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
index 249edddbf4095d05e558119080ed90a7b5200b5d..a450e6d7dc94f633b2ffba0aea8f457be8cff4b7 100644 (file)
@@ -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"
index 77c731178c2089f62eccaa129bb4ed409cb143fd..c7c72dff2c5a666826fbd2403ad66facfcfeda3b 100644 (file)
@@ -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;
index c3c77c553bdb4a44116a64b1feedc120126da58c..80fa2ff4dfecb23ff7ea310940c43ac8464de206 100644 (file)
@@ -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 */
index 8139e91ca701578b79d23ac55d2635fb3babf422..bdb934e8e0c59c0755822516f655904f19f7066e 100644 (file)
@@ -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);
index fc76c6a43c18c158c0858970ce50e95c525705ee..01ea203c61227e3a28475d9c15efff65ddb694d7 100644 (file)
@@ -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
index bc95cb0d14c2335be256987af50bbd5217635613..97512c06e86a460e915fcc0211e6a4aa03da8735 100644 (file)
@@ -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 ();
 }
 
@@ -255,12 +256,6 @@ Editor::redisplay_regions ()
        }
 }
 
-void
-Editor::region_list_clear ()
-{
-       region_list_model->clear();
-}
-
 void
 Editor::build_region_list_menu ()
 {
@@ -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));
 }
 
index 8e88ee497bbb9a74bd7fb8dbd878b101b0e5cf64..864e527b595d408fe6a25028b390b43caf4948c5 100644 (file)
@@ -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;
+       }
 }
 
index d02c5a88de7d941f57634e38927e136004e0504e..ddb771bb1841b5a75238bb6ad07a1b0b13f7bf73 100644 (file)
@@ -88,7 +88,6 @@ PlaylistSelector::clear_map ()
 bool
 PlaylistSelector::on_unmap_event (GdkEventAny* ev)
 {
-       cerr << "PLselector unmapped\n";
        clear_map ();
        if (model) {
                model->clear ();
index a9315bb76f88dd2734d3cdce4baaa5b08adde1f2..aff5866c8d445fe3cffec35ac59ad3f5a9bd3680 100644 (file)
@@ -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 ();
index 070ad4203777641be76b162bdb33c88723397379..e7fa77f4dab3682cbbd1b7a5f54c52f6115bb68b 100644 (file)
@@ -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();
index 6af38deaee2e99ff3f589514dac7aa1a3bacef42..a008e2af1a97bf54ef254a1f8eff2eaaf7a23c0c 100644 (file)
@@ -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 ;
index 946d35b8e02d18cdbc64f279f025e1ee8791f368..62ab1f775da65324a3afe81602710ef0cc9a9992 100644 (file)
@@ -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);
 };
index dcba0ae31c6e83d4465ad44c79dd942593eb4375..a6d73e8544cb7207383e98b2636aadde4b55783f 100644 (file)
@@ -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;
        }
index 31970a764659b8363539d11d7e078d968e306004..bd5f908380e0f7dc3d5aa56ef1ebc5648f51d88a 100644 (file)
@@ -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()
+               }
        }
 }
 
index 2806ab60a852ddb476cb4073fea4859b31a692bf..549f4b7dbbc78d1aee5cb621d0a65049225d2d73 100644 (file)
@@ -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");
 
index ecce09692f20ccc8d7a224247688775ba46fd08e..b5a71f6403a3cc2453f279c828a9630d812d7155 100644 (file)
@@ -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 ();
        }
 }
 
index 2becdc19b42b2ff4b083da571f17c6a0fb38ffb7..099b4dabbbe23c23a17561749074fedc2c6cb341 100644 (file)
@@ -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;
 }
index eb9e1c69ca3e15b84e089befd56780ec82dacdb6..c4a5e5fe0a6c68c00c387ec847b2493c182cbb3b 100644 (file)
@@ -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
index 097a9e23814d09a9a681599858d7664a8e7ecdd5..37f7b2c32f6db69d7e08c903bc71cc4bbf8279f4 100644 (file)
@@ -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
index 8297e1870b5abd5b18e221aedc64ae4056baf56f..2accc5cfb99f1f458448a076679d137a2fa8bb41 100644 (file)
@@ -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 "$@"