Merged with trunk R1327.

git-svn-id: svn://localhost/ardour2/branches/midi@1328 d708f5d6-7413-0410-9779-e7cbd77b26cf
This commit is contained in:
David Robillard 2007-01-15 18:33:54 +00:00
parent 32f3a4ae3e
commit 7701c52adb
21 changed files with 464 additions and 383 deletions

View 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

View 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"

View 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,14 +4020,15 @@ 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;

View 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 */

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

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

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

View 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;
string name;
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;
}
}
void
Editor::named_selection_name_chosen ()
{
Gtk::Main::quit ();
}
void
Editor::create_named_selection (const string & name)
{
if (session == 0) {
return;
}
@ -142,7 +154,6 @@ Editor::create_named_selection (const string & name)
return;
}
TrackViewList *views = get_valid_views (selection->time.track, selection->time.group);
if (views->empty()) {
@ -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());
if (!thelist.empty()) {
ns = new NamedSelection (name, thelist);
row[named_selection_columns.selection] = ns;
row[named_selection_columns.text] = name;
ArdourPrompter p;
/* make the one we just added be selected */
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 ();
named_selection_display.get_selection()->select (row);
switch (p.run ()) {
case Gtk::RESPONSE_ACCEPT:
p.get_result (name);
if (name.empty()) {
return;
}
break;
default:
return;
}
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;
}
}

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

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

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

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

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

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

View 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,184 +225,11 @@ 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());
}
int
Crossfade::compute (boost::shared_ptr<AudioRegion> a, boost::shared_ptr<AudioRegion> b, CrossfadeModel model)
{
boost::shared_ptr<AudioRegion> top;
boost::shared_ptr<AudioRegion> bottom;
nframes_t short_xfade_length;
short_xfade_length = _short_xfade_length;
if (a->layer() < b->layer()) {
top = b;
bottom = a;
} else {
top = a;
bottom = b;
}
/* first check for matching ends */
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()) {
/* top ends before bottom, so put an xfade
in at the end of top.
*/
/* [-------- top ---------- ]
* {====== bottom =====================}
*/
_in = bottom;
_out = top;
if (top->last_frame() < short_xfade_length) {
_position = 0;
} else {
_position = top->last_frame() - short_xfade_length;
}
_length = min (short_xfade_length, top->length());
_follow_overlap = false;
_anchor_point = EndOfIn;
_active = true;
_fixed = true;
} else {
/* top ends after (or same time) as bottom - no xfade
*/
/* [-------- top ------------------------ ]
* {====== bottom =====================}
*/
throw NoCrossfadeHere();
}
} 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()) {
/* top starts after bottom, put an xfade in at the
start of top
*/
/* [-------- top ---------- ]
* {====== bottom =====================}
*/
_in = top;
_out = bottom;
_position = top->first_frame();
_length = min (short_xfade_length, top->length());
_follow_overlap = false;
_anchor_point = StartOfIn;
_active = true;
_fixed = true;
} else {
/* top starts before bottom - no xfade
*/
/* [-------- top ------------------------ ]
* {====== bottom =====================}
*/
throw NoCrossfadeHere();
}
} else {
/* OK, time to do more regular overlapping */
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;
case OverlapEnd: /* top covers start of bottom but ends within it */
/* [---- top ------------------------]
* { ==== bottom ============ }
*/
_in = bottom;
_out = top;
_anchor_point = StartOfIn;
if (model == FullCrossfade) {
_position = bottom->first_frame(); // "{"
_length = _out->first_frame() + _out->length() - _in->first_frame();
/* leave active alone */
_follow_overlap = true;
} else {
_length = min (short_xfade_length, top->length());
_position = top->last_frame() - _length; // "]" - length
_active = true;
_follow_overlap = false;
}
break;
case OverlapStart: /* top starts within bottom but covers bottom's end */
/* { ==== top ============ }
* [---- bottom -------------------]
*/
_in = top;
_out = bottom;
_position = top->first_frame();
_anchor_point = StartOfIn;
if (model == FullCrossfade) {
_length = _out->first_frame() + _out->length() - _in->first_frame();
/* leave active alone */
_follow_overlap = true;
} else {
_length = min (short_xfade_length, top->length());
_active = true;
_follow_overlap = false;
}
break;
}
}
return 0;
layer_relation = (int32_t) (_in->layer() - _out->layer());
}
nframes_t
@ -514,42 +334,61 @@ Crossfade::refresh ()
return false;
}
if (_in->layer() < _out->layer()) {
cerr << "layer change, invalidated\n";
/* 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;
}
/* overlap type must be Start, End or External */
OverlapType ot = _in->coverage (_out->first_frame(), _out->last_frame());
OverlapType ot;
ot = _in->coverage (_out->first_frame(), _out->last_frame());
switch (ot) {
case OverlapNone:
case OverlapInternal:
if (ot == OverlapNone) {
Invalidated (shared_from_this());
return false;
default:
break;
}
/* overlap type must not have altered */
bool send_signal;
if (ot != overlap_type) {
Invalidated (shared_from_this());
return false;
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 ();
}
/* time to update */
if (send_signal) {
StateChanged (BoundsChanged); /* EMIT SIGNAL */
}
return update (false);
_in_update = false;
return true;
}
bool
Crossfade::update (bool force)
Crossfade::update ()
{
nframes_t newlen;
@ -566,7 +405,7 @@ Crossfade::update (bool force)
_in_update = true;
if (force || (_follow_overlap && newlen != _length) || (_length > newlen)) {
if ((_follow_overlap && newlen != _length) || (_length > newlen)) {
double factor = newlen / (double) _length;
@ -574,43 +413,188 @@ Crossfade::update (bool force)
_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;
}
}
_position = _in->first_frame();
break;
case EndOfIn:
if (_position != _in->last_frame() - _length) {
_position = _in->last_frame() - _length;
}
_position = _in->last_frame() - _length;
break;
case EndOfOut:
if (_position != _out->last_frame() - _length) {
_position = _out->last_frame() - _length;
_position = _out->last_frame() - _length;
}
return true;
}
int
Crossfade::compute (boost::shared_ptr<AudioRegion> a, boost::shared_ptr<AudioRegion> b, CrossfadeModel model)
{
boost::shared_ptr<AudioRegion> top;
boost::shared_ptr<AudioRegion> bottom;
nframes_t short_xfade_length;
short_xfade_length = _short_xfade_length;
if (a->layer() < b->layer()) {
top = b;
bottom = a;
} else {
top = a;
bottom = b;
}
/* first check for matching ends */
if (top->first_frame() == bottom->first_frame()) {
/* Both regions start at the same point */
if (top->last_frame() < bottom->last_frame()) {
/* top ends before bottom, so put an xfade
in at the end of top.
*/
/* [-------- top ---------- ]
* {====== bottom =====================}
*/
_in = bottom;
_out = top;
if (top->last_frame() < short_xfade_length) {
_position = 0;
} else {
_position = top->last_frame() - short_xfade_length;
}
_length = min (short_xfade_length, top->length());
_follow_overlap = false;
_anchor_point = EndOfIn;
_active = true;
_fixed = true;
} else {
/* top ends after (or same time) as bottom - no xfade
*/
/* [-------- top ------------------------ ]
* {====== bottom =====================}
*/
throw NoCrossfadeHere();
}
} else if (top->last_frame() == bottom->last_frame()) {
/* Both regions end at the same point */
if (top->first_frame() > bottom->first_frame()) {
/* top starts after bottom, put an xfade in at the
start of top
*/
/* [-------- top ---------- ]
* {====== bottom =====================}
*/
_in = top;
_out = bottom;
_position = top->first_frame();
_length = min (short_xfade_length, top->length());
_follow_overlap = false;
_anchor_point = StartOfIn;
_active = true;
_fixed = true;
} else {
/* top starts before bottom - no xfade
*/
/* [-------- top ------------------------ ]
* {====== bottom =====================}
*/
throw NoCrossfadeHere();
}
} else {
/* OK, time to do more regular overlapping */
OverlapType ot = top->coverage (bottom->first_frame(), bottom->last_frame());
switch (ot) {
case OverlapNone:
/* should be NOTREACHED as a precondition of creating
a new crossfade, but we need to handle it here.
*/
throw NoCrossfadeHere();
break;
case OverlapInternal:
case OverlapExternal:
/* should be NOTREACHED because of tests above */
throw NoCrossfadeHere();
break;
case OverlapEnd: /* top covers start of bottom but ends within it */
/* [---- top ------------------------]
* { ==== bottom ============ }
*/
_in = bottom;
_out = top;
_anchor_point = StartOfIn;
if (model == FullCrossfade) {
_position = bottom->first_frame(); // "{"
_length = _out->first_frame() + _out->length() - _in->first_frame();
/* leave active alone */
_follow_overlap = true;
} else {
_length = min (short_xfade_length, top->length());
_position = top->last_frame() - _length; // "]" - length
_active = true;
_follow_overlap = false;
}
break;
case OverlapStart: /* top starts within bottom but covers bottom's end */
/* { ==== top ============ }
* [---- bottom -------------------]
*/
_in = top;
_out = bottom;
_position = top->first_frame();
_anchor_point = StartOfIn;
if (model == FullCrossfade) {
_length = _out->first_frame() + _out->length() - _in->first_frame();
/* leave active alone */
_follow_overlap = true;
} else {
_length = min (short_xfade_length, top->length());
_active = true;
_follow_overlap = false;
}
break;
}
}
/* 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;
return 0;
}
void
@ -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()
}
}
}

View 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");

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

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

View 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;
}
{
/* set up Master Out and Control Out if necessary */
if (master_out_channels) {
shared_ptr<Route> r (new Route (*this, _("master"), -1, master_out_channels, -1, master_out_channels, Route::MasterOut));
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

View file

@ -3242,6 +3242,9 @@ 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 ();

View 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 "$@"