chn.channels = 12;
channel_setups.push_back (chn);
- chn.name = X_("Custom");
+ chn.name = _("Custom");
chn.channels = 0;
channel_setups.push_back (chn);
}
#include <gtkmm2ext/gtk_ui.h>
+#include "pbd/stacktrace.h"
+
#include "ardour/audioplaylist.h"
#include "ardour/audioregion.h"
#include "ardour/audiofilesource.h"
{
ENSURE_GUI_THREAD (*this, &AudioStreamView::remove_region_view, weak_r);
- cerr << "a region went way, it appears to be ours (" << this << ")\n";
-
boost::shared_ptr<Region> r (weak_r.lock());
if (!r) {
return;
}
+ cerr << "a region went way, it appears to be ours (" << this << ")\n";
+
if (!_trackview.session()->deletion_in_progress()) {
for (CrossfadeViewList::iterator i = crossfade_views.begin(); i != crossfade_views.end();) {
}
void
-AudioStreamView::playlist_modified_weak (boost::weak_ptr<Diskstream> ds)
+AudioStreamView::playlist_layered (boost::weak_ptr<Diskstream> wds)
{
- boost::shared_ptr<Diskstream> sp (ds.lock());
- if (sp) {
- playlist_modified (sp);
+ boost::shared_ptr<Diskstream> ds (wds.lock());
+
+ if (!ds) {
+ return;
}
-}
-void
-AudioStreamView::playlist_modified (boost::shared_ptr<Diskstream> ds)
-{
- /* we do not allow shared_ptr<T> to be bound to slots */
- ENSURE_GUI_THREAD (*this, &AudioStreamView::playlist_modified_weak, ds)
+ cerr << "AS, call SV::modified @ " << get_microseconds() << endl;
+
+ StreamView::playlist_layered (wds);
- StreamView::playlist_modified (ds);
+ cerr << "AS, done with SV::modified @ " << get_microseconds() << endl;
/* make sure xfades are on top and all the regionviews are stacked correctly. */
+ cerr << "AS, raise xfades @ " << get_microseconds() << endl;
for (CrossfadeViewList::iterator i = crossfade_views.begin(); i != crossfade_views.end(); ++i) {
i->second->get_canvas_group()->raise_to_top();
}
+ cerr << "AS, done with xfades @ " << get_microseconds() << endl;
}
void
-AudioStreamView::playlist_changed_weak (boost::weak_ptr<Diskstream> ds)
+AudioStreamView::playlist_switched (boost::weak_ptr<Diskstream> wds)
{
- boost::shared_ptr<Diskstream> sp (ds.lock());
- if (sp) {
- playlist_changed (sp);
- }
-}
+ boost::shared_ptr<Diskstream> ds (wds.lock());
-void
-AudioStreamView::playlist_changed (boost::shared_ptr<Diskstream> ds)
-{
- ENSURE_GUI_THREAD (*this, &AudioStreamView::playlist_changed_weak, boost::weak_ptr<Diskstream> (ds));
+ if (!ds) {
+ return;
+ }
playlist_connections.drop_connections ();
- StreamView::playlist_changed(ds);
+ StreamView::playlist_switched (ds);
boost::shared_ptr<AudioPlaylist> apl = boost::dynamic_pointer_cast<AudioPlaylist>(ds->playlist());
}
void
-AudioStreamView::add_crossfade_weak (boost::weak_ptr<Crossfade> crossfade)
+AudioStreamView::add_crossfade (boost::weak_ptr<Crossfade> wc)
{
- boost::shared_ptr<Crossfade> sp (crossfade.lock());
+ boost::shared_ptr<Crossfade> crossfade (wc.lock());
- if (!sp) {
+ if (!crossfade) {
return;
}
- add_crossfade (sp);
-}
-
-void
-AudioStreamView::add_crossfade (boost::shared_ptr<Crossfade> crossfade)
-{
AudioRegionView* lview = 0;
AudioRegionView* rview = 0;
- /* we do not allow shared_ptr<T> to be bound to slots */
-
- ENSURE_GUI_THREAD (*this, &AudioStreamView::add_crossfade_weak, boost::weak_ptr<Crossfade> (crossfade));
-
/* first see if we already have a CrossfadeView for this Crossfade */
CrossfadeViewList::iterator i = crossfade_views.find (crossfade);
void undisplay_diskstream ();
void redisplay_diskstream ();
- void playlist_modified_weak (boost::weak_ptr<ARDOUR::Diskstream>);
- void playlist_modified (boost::shared_ptr<ARDOUR::Diskstream>);
- void playlist_changed_weak (boost::weak_ptr<ARDOUR::Diskstream>);
- void playlist_changed (boost::shared_ptr<ARDOUR::Diskstream>);
+ void playlist_layered (boost::weak_ptr<ARDOUR::Diskstream>);
+ void playlist_switched (boost::weak_ptr<ARDOUR::Diskstream>);
- void add_crossfade (boost::shared_ptr<ARDOUR::Crossfade>);
- void add_crossfade_weak (boost::weak_ptr<ARDOUR::Crossfade>);
+ void add_crossfade (boost::weak_ptr<ARDOUR::Crossfade>);
void remove_crossfade (boost::shared_ptr<ARDOUR::Region>);
void color_handler ();
int x, y, xoff, yoff;
Gdk::Geometry g;
+ // return 0;
+
if ((prop = node.property ("id")) != 0) {
_id = prop->value ();
}
}
if ((prop = node.property ("region-list-sort-type"))) {
- _regions->reset_sort_type (str2regionlistsorttype(prop->value()), true);
+ RegionListSortType st;
+ _regions->reset_sort_type ((RegionListSortType) string_2_enum (prop->value(), st), true);
}
if ((prop = node.property ("xfades-visible"))) {
node->add_property ("show-measures", _show_measures ? "yes" : "no");
node->add_property ("follow-playhead", _follow_playhead ? "yes" : "no");
node->add_property ("xfades-visible", _xfade_visibility ? "yes" : "no");
- node->add_property ("region-list-sort-type", enum2str (_regions->sort_type ()));
+ node->add_property ("region-list-sort-type", enum_2_string (_regions->sort_type ()));
node->add_property ("mouse-mode", enum2str(mouse_mode));
node->add_property ("internal-edit", _internal_editing ? "yes" : "no");
node->add_property ("join-object-range", join_object_range_button.get_active () ? "yes" : "no");
ActionManager::region_selection_sensitive_actions.push_back (act);
act = ActionManager::register_action (editor_actions, "set-punch-from-edit-range", _("Set Punch from Edit Range"), sigc::mem_fun(*this, &Editor::set_punch_from_edit_range));
ActionManager::session_sensitive_actions.push_back (act);
+ ActionManager::region_selection_sensitive_actions.push_back (act);
act = ActionManager::register_action (editor_actions, "set-punch-from-region", _("Set Punch From Region"), sigc::mem_fun(*this, &Editor::set_punch_from_region));
ActionManager::session_sensitive_actions.push_back (act);
ActionManager::region_selection_sensitive_actions.push_back (act);
rv->region()->set_layer (dest_layer);
rv->region()->set_pending_explicit_relayer (true);
}
+
+ /* freeze playlist to avoid lots of relayering in the case of a multi-region drag */
- insert_result = modified_playlists.insert (playlist);
-
- if (insert_result.second) {
- _editor->session()->add_command (new MementoCommand<Playlist>(*playlist, &playlist->get_state(), 0));
- }
- /* freeze to avoid lots of relayering in the case of a multi-region drag */
frozen_insert_result = frozen_playlists.insert(playlist);
if (frozen_insert_result.second) {
playlist->freeze();
}
+ XMLNode& before (rv->region()->get_state());
rv->region()->set_position (where, (void*) this);
+ _editor->session()->add_command (new MementoCommand<Region>(*rv->region(), &before, &playlist->get_state()));
+
}
if (changed_tracks && !_copy) {
double speed = rtv->get_diskstream()->speed();
XMLNode &before = playlist->get_state();
- playlist->add_region (RegionFactory::create (rv->region()), (nframes64_t) (pos * speed));
+ boost::shared_ptr<Region> new_region (RegionFactory::create (rv->region()));
+ playlist->add_region (new_region, (nframes64_t) (pos * speed));
XMLNode &after = playlist->get_state();
_session->add_command(new MementoCommand<Playlist>(*playlist.get(), &before, &after));
- // playlist is frozen, so we have to update manually
+ // playlist is frozen, so we have to update manually XXX this is disgusting
- playlist->Modified(); /* EMIT SIGNAL */
+ playlist->RegionAdded (new_region); /* EMIT SIGNAL */
}
gint
#include <sstream>
#include "pbd/basename.h"
+#include "pbd/enumwriter.h"
#include "ardour/audioregion.h"
#include "ardour/audiofilesource.h"
using Gtkmm2ext::Keyboard;
EditorRegions::EditorRegions (Editor* e)
- : EditorComponent (e),
- _menu (0),
- _show_automatic_regions (true),
- _sort_type ((Editing::RegionListSortType) 0),
- _no_redisplay (false)
+ : EditorComponent (e)
+ , _menu (0)
+ , _show_automatic_regions (true)
+ , _sort_type ((Editing::RegionListSortType) 0)
+ , _no_redisplay (false)
+ , ignore_region_list_selection_change (false)
+ , ignore_selected_region_change (false)
{
_display.set_size_request (100, -1);
_display.set_name ("RegionListDisplay");
void
EditorRegions::selection_changed ()
{
+ if (ignore_region_list_selection_change) {
+ return;
+ }
+
if (_display.get_selection()->count_selected_rows() > 0) {
TreeIter iter;
TreeView::Selection::ListHandle_Path rows = _display.get_selection()->get_selected_rows ();
- _editor->deselect_all ();
+ _editor->get_selection().clear_regions ();
for (TreeView::Selection::ListHandle_Path::iterator i = rows.begin(); i != rows.end(); ++i) {
- if (iter = _model->get_iter (*i)) { // they could have clicked on a row that is just a placeholder, like "Hidden"
+ if (iter = _model->get_iter (*i)) {
boost::shared_ptr<Region> region = (*iter)[_columns.region];
+ // they could have clicked on a row that is just a placeholder, like "Hidden"
+
if (region) {
if (region->automatic()) {
+
_display.get_selection()->unselect(*i);
} else {
_change_connection.block (true);
- //editor_regions_selection_changed_connection.block(true);
-
+ cerr << "\tpush to region selection\n";
_editor->set_selected_regionview_from_region_list (region, Selection::Add);
_change_connection.block (false);
- //editor_regions_selection_changed_connection.block(false);
}
}
}
}
} else {
- _editor->deselect_all ();
+ _editor->get_selection().clear_regions ();
}
}
boost::shared_ptr<Region> compared_region = (*i)[_columns.region];
if (r == compared_region) {
+ cerr << "\tpush into region list\n";
_display.get_selection()->select(*i);
break;
}
if (!(*i).children().empty()) {
+ cerr << "\tlook for " << r->name() << " among children of " << (compared_region ? compared_region->name() : string ("NO REGION")) << endl;
if (set_selected_in_subrow(r, (*i), 2)) {
break;
}
TreeModel::iterator i;
TreeModel::Children rows = _model->children();
+
+ return;
for (i = rows.begin(); i != rows.end(); ++i) {
}
}
}
+
// cerr << "Returning - No match\n";
}
}
}
}
+
return false;
}
if (!_session) {
return;
}
-
+
TreeModel::iterator i;
TreeModel::Children rows = _model->children();
break;
case ByEndInFile:
+ // cerr << "Compare " << (region1->start() + region1->length()) << " and " << (region2->start() + region2->length()) << endl;
cmp = (region1->start() + region1->length()) - (region2->start() + region2->length());
break;
break;
}
+ // cerr << "Comparison on " << enum_2_string (_sort_type) << " gives " << cmp << endl;
+
if (cmp < 0) {
return -1;
} else if (cmp > 0) {
bool _no_redisplay;
std::list<boost::shared_ptr<ARDOUR::Region> > tmp_region_list;
PBD::ScopedConnection region_property_connection;
+ bool ignore_region_list_selection_change;
+ bool ignore_selected_region_change;
};
#endif /* __gtk_ardour_editor_regions_h__ */
_regions->block_change_connection (true);
editor_regions_selection_changed_connection.block(true);
+ _regions->unselect_all ();
+
for (TrackViewList::iterator i = track_views.begin(); i != track_views.end(); ++i) {
(*i)->set_selected_regionviews (selection->regions);
}
ImportMode import_mode;
EditPoint edit_point;
LayerDisplay layer_display;
+ RegionListSortType region_list_sort_type;
#define REGISTER(e) enum_writer.register_distinct (typeid(e).name(), i, s); i.clear(); s.clear()
#define REGISTER_BITS(e) enum_writer.register_bits (typeid(e).name(), i, s); i.clear(); s.clear()
REGISTER_ENUM (Overlaid);
REGISTER_ENUM (Stacked);
REGISTER (layer_display);
+
+ REGISTER_ENUM (ByEndInFile);
+ REGISTER_ENUM (ByLength);
+ REGISTER_ENUM (ByName);
+ REGISTER_ENUM (ByPosition);
+ REGISTER_ENUM (BySourceFileCreationDate);
+ REGISTER_ENUM (BySourceFileFS);
+ REGISTER_ENUM (BySourceFileLength);
+ REGISTER_ENUM (BySourceFileName);
+ REGISTER_ENUM (ByStartInFile);
+ REGISTER_ENUM (ByTimestamp);
+ REGISTER (region_list_sort_type);
}
#ifndef __ardour_gtk_midi_tracer_h__
#define __ardour_gtk_midi_tracer_h__
-#include <types.h>
#include <gtkmm/textview.h>
#include <gtkmm/scrolledwindow.h>
#include <gtkmm/togglebutton.h>
Label label;
label.set_text (_("\
-You cannot reorder this set of processors\n\
+You cannot reorder these plugins/sends/inserts\n\
in that way because the inputs and\n\
-outputs do not work correctly."));
+outputs will not work correctly."));
+ dialog.get_vbox()->set_border_width (12);
dialog.get_vbox()->pack_start (label);
dialog.add_button (Stock::OK, RESPONSE_ACCEPT);
}
void
-StreamView::add_region_view_weak (boost::weak_ptr<Region> r)
+StreamView::add_region_view (boost::weak_ptr<Region> wr)
{
- boost::shared_ptr<Region> sp (r.lock());
-
- if (sp) {
- add_region_view (sp);
+ boost::shared_ptr<Region> r (wr.lock());
+ if (!r) {
+ return;
}
-}
-
-
-void
-StreamView::add_region_view (boost::shared_ptr<Region> r)
-{
- ENSURE_GUI_THREAD (*this, &StreamView::add_region_view_weak, boost::weak_ptr<Region>(r));
add_region_view_internal (r, true);
void
StreamView::display_diskstream (boost::shared_ptr<Diskstream> ds)
{
- playlist_change_connection.disconnect();
- playlist_changed (ds);
- ds->PlaylistChanged.connect (playlist_change_connection, boost::bind (&StreamView::playlist_changed_weak, this, boost::weak_ptr<Diskstream> (ds)), gui_context());
+ playlist_switched_connection.disconnect();
+ playlist_switched (ds);
+ ds->PlaylistChanged.connect (playlist_switched_connection, boost::bind (&StreamView::playlist_switched, this, boost::weak_ptr<Diskstream> (ds)), gui_context());
}
void
}
void
-StreamView::playlist_modified_weak (boost::weak_ptr<Diskstream> ds)
+StreamView::playlist_layered (boost::weak_ptr<Diskstream> wds)
{
- boost::shared_ptr<Diskstream> sp (ds.lock());
+ boost::shared_ptr<Diskstream> ds (wds.lock());
- if (sp) {
- playlist_modified (sp);
+ if (!ds) {
+ return;
}
-}
-
-void
-StreamView::playlist_modified (boost::shared_ptr<Diskstream> ds)
-{
- /* we do not allow shared_ptr<T> to be bound to slots */
- ENSURE_GUI_THREAD (*this, &StreamView::playlist_modified_weak, ds)
/* update layers count and the y positions and heights of our regions */
if (ds->playlist()) {
}
void
-StreamView::playlist_changed_weak (boost::weak_ptr<Diskstream> ds)
+StreamView::playlist_switched (boost::weak_ptr<Diskstream> wds)
{
- boost::shared_ptr<Diskstream> sp (ds.lock());
- if (sp) {
- playlist_changed (sp);
- }
-}
+ boost::shared_ptr<Diskstream> ds (wds.lock());
-void
-StreamView::playlist_changed (boost::shared_ptr<Diskstream> ds)
-{
- ENSURE_GUI_THREAD (*this, &StreamView::playlist_changed_weak, boost::weak_ptr<Diskstream> (ds));
+ if (!ds) {
+ return;
+ }
/* disconnect from old playlist */
/* catch changes */
- ds->playlist()->Modified.connect (playlist_connections, boost::bind (&StreamView::playlist_modified_weak, this, ds), gui_context());
- ds->playlist()->RegionAdded.connect (playlist_connections, ui_bind (&StreamView::add_region_view_weak, this, _1), gui_context());
+ ds->playlist()->LayeringChanged.connect (playlist_connections, boost::bind (&StreamView::playlist_layered, this, boost::weak_ptr<Diskstream>(ds)), gui_context());
+ ds->playlist()->RegionAdded.connect (playlist_connections, ui_bind (&StreamView::add_region_view, this, _1), gui_context());
ds->playlist()->RegionRemoved.connect (playlist_connections, ui_bind (&StreamView::remove_region_view, this, _1), gui_context());
}
virtual void update_contents_metrics(boost::shared_ptr<ARDOUR::Region>) {}
- void add_region_view_weak (boost::weak_ptr<ARDOUR::Region> r);
- void add_region_view (boost::shared_ptr<ARDOUR::Region>);
+ void add_region_view (boost::weak_ptr<ARDOUR::Region>);
void region_layered (RegionView*);
virtual void update_contents_height ();
void diskstream_changed ();
void layer_regions ();
- virtual void playlist_changed_weak (boost::weak_ptr<ARDOUR::Diskstream>);
- virtual void playlist_changed (boost::shared_ptr<ARDOUR::Diskstream>);
- virtual void playlist_modified_weak (boost::weak_ptr<ARDOUR::Diskstream>);
- virtual void playlist_modified (boost::shared_ptr<ARDOUR::Diskstream>);
+ virtual void playlist_switched (boost::weak_ptr<ARDOUR::Diskstream>);
+ virtual void playlist_layered (boost::weak_ptr<ARDOUR::Diskstream>);
virtual void color_handler () = 0;
uint32_t stream_base_color; ///< Background color
PBD::ScopedConnectionList playlist_connections;
- PBD::ScopedConnection playlist_change_connection;
+ PBD::ScopedConnection playlist_switched_connection;
ARDOUR::layer_t _layers;
LayerDisplay _layer_display;
XMLNode& get_template ();
PBD::Signal1<void,bool> InUse;
- PBD::Signal0<void> Modified;
+ PBD::Signal0<void> ContentsChanged;
PBD::Signal1<void,boost::weak_ptr<Region> > RegionAdded;
PBD::Signal1<void,boost::weak_ptr<Region> > RegionRemoved;
PBD::Signal0<void> NameChanged;
PBD::Signal0<void> LengthChanged;
+ PBD::Signal0<void> LayeringChanged;
PBD::Signal1<void,std::list< Evoral::RangeMove<nframes_t> > const &> RangesMoved;
static std::string bump_name (std::string old_name, Session&);
std::set<boost::shared_ptr<Region> > pending_adds;
std::set<boost::shared_ptr<Region> > pending_removes;
RegionList pending_bounds;
- bool pending_modified;
+ bool pending_contents_change;
+ bool pending_layering;
bool pending_length;
std::list< Evoral::RangeMove<nframes_t> > pending_range_moves;
bool save_on_thaw;
void delay_notifications ();
void release_notifications ();
virtual void flush_notifications ();
+ void clear_pending ();
void notify_region_removed (boost::shared_ptr<Region>);
void notify_region_added (boost::shared_ptr<Region>);
void notify_length_changed ();
void notify_layering_changed ();
- void notify_modified ();
+ void notify_contents_changed ();
void notify_state_changed (Change);
void notify_region_moved (boost::shared_ptr<Region>);
process. this problem is deferred to the UI.
*/
- _playlist->Modified();
+ _playlist->LayeringChanged(); // XXX this may not get the UI to do the right thing
} else {
that occured.
*/
- notify_modified ();
+ notify_contents_changed ();
}
bool
parent_wants_notify = Playlist::region_changed (what_changed, region);
if ((parent_wants_notify || (what_changed & our_interests))) {
- notify_modified ();
+ notify_contents_changed ();
}
return true;
void
AudioRegion::listen_to_my_curves ()
{
+ cerr << _name << ": listeing my own curves\n";
+
_envelope->StateChanged.connect_same_thread (*this, boost::bind (&AudioRegion::envelope_changed, this));
_fade_in->StateChanged.connect_same_thread (*this, boost::bind (&AudioRegion::fade_in_changed, this));
_fade_out->StateChanged.connect_same_thread (*this, boost::bind (&AudioRegion::fade_out_changed, this));
const XMLNodeList& nlist = node.children();
const XMLProperty *prop;
LocaleGuard lg (X_("POSIX"));
+ boost::shared_ptr<Playlist> the_playlist (_playlist.lock());
+
+ freeze ();
+ if (the_playlist) {
+ the_playlist->freeze ();
+ }
Region::set_live_state (node, version, what_changed, false);
+ cerr << "After region SLS, wc = " << what_changed << endl;
uint32_t old_flags = _flags;
if ((old_flags ^ _flags) & Muted) {
what_changed = Change (what_changed|MuteChanged);
+ cerr << _name << " mute changed\n";
}
if ((old_flags ^ _flags) & Opaque) {
what_changed = Change (what_changed|OpacityChanged);
+ cerr << _name << " opacity changed\n";
}
if ((old_flags ^ _flags) & Locked) {
what_changed = Change (what_changed|LockChanged);
+ cerr << _name << " lock changed\n";
}
if ((prop = node.property ("scale-gain")) != 0) {
- _scale_amplitude = atof (prop->value().c_str());
- what_changed = Change (what_changed|ScaleAmplitudeChanged);
+ float a = atof (prop->value().c_str());
+ if (a != _scale_amplitude) {
+ _scale_amplitude = a;
+ what_changed = Change (what_changed|ScaleAmplitudeChanged);
+ cerr << _name << " amp changed\n";
+ }
} else {
_scale_amplitude = 1.0;
}
/* Now find envelope description and other misc child items */
+ _envelope->freeze ();
+
for (XMLNodeConstIterator niter = nlist.begin(); niter != nlist.end(); ++niter) {
XMLNode *child;
child = (*niter);
+#if 0
if (child->name() == "Envelope") {
_envelope->clear ();
_envelope->set_max_xval (_length);
_envelope->truncate_end (_length);
+ cerr << _name << " envelope changd\n";
+
+
} else if (child->name() == "FadeIn") {
_fade_in->clear ();
set_fade_in_active (false);
}
}
+ cerr << _name << " fadein changd\n";
} else if (child->name() == "FadeOut") {
set_fade_out_active (false);
}
}
+ cerr << _name << " fadeout changd\n";
}
+#endif
}
+ _envelope->thaw ();
+ thaw ("");
+
if (send) {
+ cerr << _name << ": audio final change: " << hex << what_changed << dec << endl;
send_change (what_changed);
}
+ if (the_playlist) {
+ the_playlist->thaw ();
+ }
+
return 0;
}
}
_fade_in->thaw ();
-
- send_change (FadeInChanged);
}
void
}
_fade_out->thaw ();
-
- send_change (FadeOutChanged);
}
void
/* tell the diskstream we're in */
if (pl) {
- pl->Modified();
+ pl->ContentsChanged();
}
/* tell everybody else */
boost::shared_ptr<Playlist> pl (playlist());
if (pl) {
- pl->Modified();
+ pl->ContentsChanged();
}
/* tell everybody else */
ControlList::thaw();
if (_changed_when_thawed) {
+ _changed_when_thawed = false;
StateChanged(); /* EMIT SIGNAL */
}
}
nframes_t length,
nframes_t position,
AnchorPoint ap)
- : AudioRegion (in->session(), position, length, "foobar"),
+ : AudioRegion (in->session(), position, length, in->name() + string ("<>") + out->name()),
_fade_in (Evoral::Parameter(FadeInAutomation)), // linear (gain coefficient) => -inf..+6dB
_fade_out (Evoral::Parameter(FadeOutAutomation)) // linear (gain coefficient) => -inf..+6dB
}
Crossfade::Crossfade (boost::shared_ptr<AudioRegion> a, boost::shared_ptr<AudioRegion> b, CrossfadeModel model, bool act)
- : AudioRegion (a->session(), 0, 0, "foobar"),
+ : AudioRegion (a->session(), 0, 0, a->name() + string ("<>") + b->name()),
_fade_in (Evoral::Parameter(FadeInAutomation)), // linear (gain coefficient) => -inf..+6dB
_fade_out (Evoral::Parameter(FadeOutAutomation)) // linear (gain coefficient) => -inf..+6dB
{
}
Crossfade::Crossfade (const Playlist& playlist, XMLNode& node)
- : AudioRegion (playlist.session(), 0, 0, "foobar"),
+ : AudioRegion (playlist.session(), 0, 0, "unnamed crossfade"),
_fade_in (Evoral::Parameter(FadeInAutomation)), // linear (gain coefficient) => -inf..+6dB
_fade_out (Evoral::Parameter(FadeOutAutomation)) // linear (gain coefficient) => -inf..+6dB
reset_write_sources (false);
}
- _playlist->Modified.connect_same_thread (playlist_connections, boost::bind (&Diskstream::playlist_modified, this));
+ _playlist->ContentsChanged.connect_same_thread (playlist_connections, boost::bind (&Diskstream::playlist_modified, this));
_playlist->DropReferences.connect_same_thread (playlist_connections, boost::bind (&Diskstream::playlist_deleted, this, boost::weak_ptr<Playlist>(_playlist)));
_playlist->RangesMoved.connect_same_thread (playlist_connections, boost::bind (&Diskstream::playlist_ranges_moved, this, _1));
}
parent_wants_notify = Playlist::region_changed (what_changed, region);
if ((parent_wants_notify || (what_changed & our_interests))) {
- notify_modified ();
+ notify_contents_changed ();
}
return true;
{
g_atomic_int_set (&block_notifications, 0);
g_atomic_int_set (&ignore_state_changes, 0);
- pending_modified = false;
+ pending_contents_change = false;
pending_length = false;
+ pending_layering = false;
first_set_state = true;
_refcnt = 0;
_hidden = hide;
freeze_length = 0;
_explicit_relayering = false;
- Modified.connect_same_thread (*this, boost::bind (&Playlist::mark_session_dirty, this));
+ ContentsChanged.connect_same_thread (*this, boost::bind (&Playlist::mark_session_dirty, this));
}
Playlist::~Playlist ()
}
void
-Playlist::notify_modified ()
+Playlist::notify_contents_changed ()
{
if (holding_state ()) {
- pending_modified = true;
+ pending_contents_change = true;
} else {
- pending_modified = false;
- Modified(); /* EMIT SIGNAL */
+ pending_contents_change = false;
+ cerr << _name << "send contents change @ " << get_microseconds() << endl;
+ ContentsChanged(); /* EMIT SIGNAL */
+ cerr << _name << "done with cc @ " << get_microseconds() << endl;
+ }
+}
+
+void
+Playlist::notify_layering_changed ()
+{
+ if (holding_state ()) {
+ pending_layering = true;
+ } else {
+ pending_layering = false;
+ cerr << _name << "send layering @ " << get_microseconds() << endl;
+ LayeringChanged(); /* EMIT SIGNAL */
+ cerr << _name << "done with layering @ " << get_microseconds() << endl;
}
}
{
if (holding_state ()) {
pending_removes.insert (r);
- pending_modified = true;
+ pending_contents_change = true;
pending_length = true;
} else {
/* this might not be true, but we have to act
*/
pending_length = false;
LengthChanged (); /* EMIT SIGNAL */
- pending_modified = false;
+ pending_contents_change = false;
RegionRemoved (boost::weak_ptr<Region> (r)); /* EMIT SIGNAL */
- Modified (); /* EMIT SIGNAL */
+ ContentsChanged (); /* EMIT SIGNAL */
}
}
if (holding_state()) {
pending_adds.insert (r);
- pending_modified = true;
+ pending_contents_change = true;
pending_length = true;
} else {
pending_length = false;
LengthChanged (); /* EMIT SIGNAL */
- pending_modified = false;
+ pending_contents_change = false;
RegionAdded (boost::weak_ptr<Region> (r)); /* EMIT SIGNAL */
- Modified (); /* EMIT SIGNAL */
+ cerr << _name << "send3 contents changed @ " << get_microseconds() << endl;
+ ContentsChanged (); /* EMIT SIGNAL */
+ cerr << _name << "done contents changed @ " << get_microseconds() << endl;
}
}
} else {
pending_length = false;
LengthChanged(); /* EMIT SIGNAL */
- pending_modified = false;
- Modified (); /* EMIT SIGNAL */
+ pending_contents_change = false;
+ cerr << _name << "send4 contents change @ " << get_microseconds() << endl;
+ ContentsChanged (); /* EMIT SIGNAL */
+ cerr << _name << "done contents change @ " << get_microseconds() << endl;
}
}
{
set<boost::shared_ptr<Region> > dependent_checks_needed;
set<boost::shared_ptr<Region> >::iterator s;
- uint32_t n = 0;
+ uint32_t regions_changed = false;
+ bool check_length = false;
+ nframes64_t old_length = 0;
if (in_flush) {
return;
in_flush = true;
+ if (!pending_bounds.empty() || !pending_removes.empty() || !pending_adds.empty()) {
+ regions_changed = true;
+ if (!pending_length) {
+ old_length = _get_maximum_extent ();
+ check_length = true;
+ }
+ }
+
/* we have no idea what order the regions ended up in pending
bounds (it could be based on selection order, for example).
so, to preserve layering in the "most recently moved is higher"
if (_session.config.get_layer_model() == MoveAddHigher) {
timestamp_layer_op (*r);
}
-
- pending_length = true;
dependent_checks_needed.insert (*r);
-
- n++;
}
for (s = pending_removes.begin(); s != pending_removes.end(); ++s) {
remove_dependents (*s);
+ cerr << _name << " sends RegionRemoved\n";
RegionRemoved (boost::weak_ptr<Region> (*s)); /* EMIT SIGNAL */
- n++;
}
for (s = pending_adds.begin(); s != pending_adds.end(); ++s) {
+ cerr << _name << " sends RegionAdded\n";
RegionAdded (boost::weak_ptr<Region> (*s)); /* EMIT SIGNAL */
dependent_checks_needed.insert (*s);
- n++;
}
- if ((freeze_length != _get_maximum_extent()) || pending_length) {
- pending_length = 0;
+ if (check_length) {
+ if (old_length != _get_maximum_extent()) {
+ pending_length = true;
+ cerr << _name << " length has changed\n";
+ }
+ }
+
+ if (pending_length || (freeze_length != _get_maximum_extent())) {
+ pending_length = false;
+ cerr << _name << " sends LengthChanged\n";
LengthChanged(); /* EMIT SIGNAL */
- n++;
}
- if (n || pending_modified) {
+ if (regions_changed || pending_contents_change) {
if (!in_set_state) {
relayer ();
}
- pending_modified = false;
- Modified (); /* EMIT SIGNAL */
+ pending_contents_change = false;
+ cerr << _name << " sends 5 contents change @ " << get_microseconds() << endl;
+ ContentsChanged (); /* EMIT SIGNAL */
+ cerr << _name << "done contents change @ " << get_microseconds() << endl;
}
for (s = dependent_checks_needed.begin(); s != dependent_checks_needed.end(); ++s) {
}
if (!pending_range_moves.empty ()) {
+ cerr << _name << " sends RangesMoved\n";
RangesMoved (pending_range_moves);
}
+
+ clear_pending ();
+ in_flush = false;
+}
+
+void
+Playlist::clear_pending ()
+{
pending_adds.clear ();
pending_removes.clear ();
pending_bounds.clear ();
pending_range_moves.clear ();
-
- in_flush = false;
+ pending_contents_change = false;
+ pending_length = false;
}
/*************************************************************
{
RegionList::iterator i;
nframes_t old_length = 0;
+ int ret = -1;
if (!holding_state()) {
old_length = _get_maximum_extent();
region->set_playlist (boost::weak_ptr<Playlist>());
}
+ /* XXX should probably freeze here .... */
+
for (i = regions.begin(); i != regions.end(); ++i) {
if (*i == region) {
}
notify_region_removed (region);
- return 0;
+ ret = 0;
+ break;
}
}
+ /* XXX and thaw ... */
-
- return -1;
+ return ret;
}
void
notify_region_moved (region);
}
+
+ /* don't notify about layer changes, since we are the only object that can initiate
+ them, and we notify in ::relayer()
+ */
+
if (what_changed & our_interests) {
save = true;
}
if (with_signals) {
pending_length = false;
LengthChanged ();
- pending_modified = false;
- Modified ();
+ pending_contents_change = false;
+ cerr << _name << "send2 contents change @ " << get_microseconds() << endl;
+ ContentsChanged ();
+ cerr << _name << "done with contents changed @ " << get_microseconds() << endl;
}
}
Change what_changed = Change (0);
- if (region->set_live_state (*child, version, what_changed, true)) {
- error << _("Playlist: cannot reset region state from XML") << endmsg;
+ region->freeze ();
+
+ if (region->set_live_state (*child, version, what_changed, false)) {
+ region->thaw ("");
continue;
}
- } else if ((region = RegionFactory::create (_session, *child, true)) == 0) {
+ } else if ((region = RegionFactory::create (_session, *child, true)) != 0) {
+ region->freeze ();
+ } else {
error << _("Playlist: cannot create region from XML") << endmsg;
continue;
}
// So that layer_op ordering doesn't get screwed up
region->set_last_layer_op( region->layer());
-
+ region->thaw ("");
}
}
- notify_modified ();
-
- thaw ();
-
/* update dependents, which was not done during add_region_internal
due to in_set_state being true
*/
check_dependents (*r, false);
}
+ clear_pending (); // this makes thaw() do nothing
+ thaw ();
+ notify_contents_changed ();
+
in_set_state--;
first_set_state = false;
return 0;
void
Playlist::relayer ()
{
- /* don't send multiple Modified notifications
- when multiple regions are relayered.
- */
-
- freeze ();
+ bool changed = false;
/* Build up a new list of regions on each layer, stored in a set of lists
each of which represent some period of time on some layer. The idea
for (int k = start_division; k <= end_division; ++k) {
layers[j][k].push_back (*i);
}
+
+ if ((*i)->layer() != j) {
+ changed = true;
+ }
(*i)->set_layer (j);
}
- /* sending Modified means that various kinds of layering
- models operate correctly at the GUI
- level. slightly inefficient, but only slightly.
-
- We force a Modified signal here in case no layers actually
- changed.
- */
-
- notify_modified ();
-
- thaw ();
+ if (changed) {
+ notify_layering_changed ();
+ }
}
/* XXX these layer functions are all deprecated */
relayer ();
check_dependents (region, false);
- notify_modified();
+ notify_contents_changed();
}
}
sscanf (prop->value().c_str(), "%" PRIu32, &val);
if (val != _start) {
what_changed = Change (what_changed|StartChanged);
+ cerr << _name << " start changed\n";
_start = val;
}
} else {
sscanf (prop->value().c_str(), "%" PRIu32, &val);
if (val != _length) {
what_changed = Change (what_changed|LengthChanged);
+ cerr << _name << " length changed\n";
_last_length = _length;
_length = val;
}
sscanf (prop->value().c_str(), "%" PRIu32, &val);
if (val != _position) {
what_changed = Change (what_changed|PositionChanged);
+ cerr << _name << " position changed\n";
_last_position = _position;
_position = val;
}
x = (layer_t) atoi (prop->value().c_str());
if (x != _layer) {
what_changed = Change (what_changed|LayerChanged);
+ cerr << _name << " layer changed\n";
_layer = x;
}
} else {
sscanf (prop->value().c_str(), "%" PRIu32, &val);
if (val != _sync_position) {
what_changed = Change (what_changed|SyncOffsetChanged);
+ cerr << _name << " sync changed\n";
_sync_position = val;
}
} else {
}
if (send) {
+ cerr << _name << ": final change to be sent: " << hex << what_changed << dec << endl;
send_change (what_changed);
}
recompute_at_end ();
}
- StateChanged (what_changed);
+ send_change (what_changed);
}
void
Region::send_change (Change what_changed)
{
+
{
Glib::Mutex::Lock lm (_lock);
if (_frozen) {
}
}
+ cerr << _name << " actually sends " << hex << what_changed << dec << " @" << get_microseconds() << endl;
StateChanged (what_changed);
+ cerr << _name << " done with " << hex << what_changed << dec << " @" << get_microseconds() << endl;
if (!(_flags & DoNotSendPropertyChanges)) {
try {
boost::shared_ptr<Region> rptr = shared_from_this();
+ cerr << _name << " actually sends prop change " << hex << what_changed << dec << " @ " << get_microseconds() << endl;
RegionPropertyChanged (rptr);
+ cerr << _name << " done with prop change @ " << get_microseconds() << endl;
} catch (...) {
/* no shared_ptr available, relax; */
}
$Id$
*/
+#include <iostream>
#include <string>
#include <sstream>
#include <time.h>