summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gtk2_ardour/analysis_window.cc6
-rw-r--r--gtk2_ardour/audio_region_editor.cc8
-rw-r--r--gtk2_ardour/audio_streamview.cc4
-rw-r--r--gtk2_ardour/editor.cc30
-rw-r--r--gtk2_ardour/editor.h6
-rw-r--r--gtk2_ardour/editor_audio_import.cc2
-rw-r--r--gtk2_ardour/editor_canvas_events.cc4
-rw-r--r--gtk2_ardour/editor_export_audio.cc2
-rw-r--r--gtk2_ardour/editor_mouse.cc54
-rw-r--r--gtk2_ardour/editor_ops.cc84
-rw-r--r--gtk2_ardour/editor_region_list.cc6
-rw-r--r--gtk2_ardour/editor_selection_list.cc6
-rw-r--r--gtk2_ardour/editor_timefx.cc2
-rw-r--r--gtk2_ardour/playlist_selection.h3
-rw-r--r--gtk2_ardour/playlist_selector.cc40
-rw-r--r--gtk2_ardour/playlist_selector.h11
-rw-r--r--gtk2_ardour/public_editor.h2
-rw-r--r--gtk2_ardour/route_time_axis.cc59
-rw-r--r--gtk2_ardour/route_time_axis.h6
-rw-r--r--gtk2_ardour/selection.cc30
-rw-r--r--gtk2_ardour/selection.h16
-rw-r--r--gtk2_ardour/time_axis_view.h2
-rw-r--r--libs/ardour/ardour/audio_diskstream.h4
-rw-r--r--libs/ardour/ardour/audioplaylist.h9
-rw-r--r--libs/ardour/ardour/audioregion.h2
-rw-r--r--libs/ardour/ardour/crossfade.h5
-rw-r--r--libs/ardour/ardour/diskstream.h10
-rw-r--r--libs/ardour/ardour/named_selection.h5
-rw-r--r--libs/ardour/ardour/playlist.h54
-rw-r--r--libs/ardour/ardour/region.h7
-rw-r--r--libs/ardour/ardour/session.h30
-rw-r--r--libs/ardour/ardour/session_playlist.h2
-rw-r--r--libs/ardour/ardour/source.h6
-rw-r--r--libs/ardour/ardour/track.h5
-rw-r--r--libs/ardour/audio_diskstream.cc25
-rw-r--r--libs/ardour/audio_playlist.cc28
-rw-r--r--libs/ardour/audio_track.cc20
-rw-r--r--libs/ardour/audioregion.cc45
-rw-r--r--libs/ardour/auditioner.cc2
-rw-r--r--libs/ardour/diskstream.cc32
-rw-r--r--libs/ardour/import.cc8
-rw-r--r--libs/ardour/named_selection.cc18
-rw-r--r--libs/ardour/playlist.cc147
-rw-r--r--libs/ardour/playlist_factory.cc75
-rw-r--r--libs/ardour/region.cc55
-rw-r--r--libs/ardour/session.cc88
-rw-r--r--libs/ardour/session_command.cc5
-rw-r--r--libs/ardour/session_state.cc170
-rw-r--r--libs/ardour/source.cc13
-rw-r--r--libs/ardour/source_factory.cc6
50 files changed, 720 insertions, 539 deletions
diff --git a/gtk2_ardour/analysis_window.cc b/gtk2_ardour/analysis_window.cc
index af81a28d80..e06ac59e19 100644
--- a/gtk2_ardour/analysis_window.cc
+++ b/gtk2_ardour/analysis_window.cc
@@ -228,8 +228,8 @@ AnalysisWindow::analyze_data (Gtk::Button *button)
for (TrackSelection::iterator i = s.tracks.begin(); i != s.tracks.end(); ++i) {
- ARDOUR::AudioPlaylist *pl
- = dynamic_cast<ARDOUR::AudioPlaylist*>((*i)->playlist());
+ boost::shared_ptr<AudioPlaylist> pl
+ = boost::dynamic_pointer_cast<AudioPlaylist*>((*i)->playlist());
if (!pl)
continue;
@@ -246,7 +246,7 @@ AnalysisWindow::analyze_data (Gtk::Button *button)
if (source_selection_ranges_rb.get_active()) {
// cerr << "Analyzing ranges on track " << *&rui->route().name() << endl;
- for (std::list<ARDOUR::AudioRange>::iterator j = ts.begin(); j != ts.end(); ++j) {
+ for (std::list<AudioRange>::iterator j = ts.begin(); j != ts.end(); ++j) {
nframes_t i = 0;
int n;
diff --git a/gtk2_ardour/audio_region_editor.cc b/gtk2_ardour/audio_region_editor.cc
index 0852072132..3ce8c76d2e 100644
--- a/gtk2_ardour/audio_region_editor.cc
+++ b/gtk2_ardour/audio_region_editor.cc
@@ -201,7 +201,7 @@ AudioRegionEditor::start_clock_changed ()
{
_session.begin_reversible_command (_("change region start position"));
- Playlist* const pl = _region->playlist();
+ boost::shared_ptr<Playlist> pl = _region->playlist();
if (pl) {
XMLNode &before = pl->get_state();
@@ -218,8 +218,8 @@ AudioRegionEditor::end_clock_changed ()
{
_session.begin_reversible_command (_("change region end position"));
- Playlist* const pl = _region->playlist();
-
+ boost::shared_ptr<Playlist> pl = _region->playlist();
+
if (pl) {
XMLNode &before = pl->get_state();
_region->trim_end (end_clock.current_time(), this);
@@ -239,7 +239,7 @@ AudioRegionEditor::length_clock_changed ()
_session.begin_reversible_command (_("change region length"));
- Playlist* const pl = _region->playlist();
+ boost::shared_ptr<Playlist> pl = _region->playlist();
if (pl) {
XMLNode &before = pl->get_state();
diff --git a/gtk2_ardour/audio_streamview.cc b/gtk2_ardour/audio_streamview.cc
index 75eb28e7d5..185a961064 100644
--- a/gtk2_ardour/audio_streamview.cc
+++ b/gtk2_ardour/audio_streamview.cc
@@ -239,7 +239,7 @@ AudioStreamView::playlist_changed (boost::shared_ptr<Diskstream> ds)
StreamView::playlist_changed(ds);
- AudioPlaylist* apl = dynamic_cast<AudioPlaylist*>(ds->playlist());
+ boost::shared_ptr<AudioPlaylist> apl = boost::dynamic_pointer_cast<AudioPlaylist>(ds->playlist());
if (apl)
playlist_connections.push_back (apl->NewCrossfade.connect (mem_fun (*this, &AudioStreamView::add_crossfade)));
}
@@ -328,7 +328,7 @@ AudioStreamView::redisplay_diskstream ()
if (_trackview.is_audio_track()) {
_trackview.get_diskstream()->playlist()->foreach_region (static_cast<StreamView*>(this), &StreamView::add_region_view);
- AudioPlaylist* apl = dynamic_cast<AudioPlaylist*>(_trackview.get_diskstream()->playlist());
+ boost::shared_ptr<AudioPlaylist> apl = boost::dynamic_pointer_cast<AudioPlaylist>(_trackview.get_diskstream()->playlist());
if (apl)
apl->foreach_crossfade (this, &AudioStreamView::add_crossfade);
}
diff --git a/gtk2_ardour/editor.cc b/gtk2_ardour/editor.cc
index 1938675780..b21db92119 100644
--- a/gtk2_ardour/editor.cc
+++ b/gtk2_ardour/editor.cc
@@ -1538,7 +1538,7 @@ Editor::build_track_region_context_menu (nframes_t frame)
if (atv) {
boost::shared_ptr<Diskstream> ds;
- Playlist* pl = 0;
+ boost::shared_ptr<Playlist> pl;
if ((ds = atv->get_diskstream()) && ((pl = ds->playlist()))) {
Playlist::RegionList* regions = pl->regions_at ((nframes_t) floor ( (double)frame * ds->speed()));
@@ -1565,10 +1565,10 @@ Editor::build_track_crossfade_context_menu (nframes_t frame)
if (atv) {
boost::shared_ptr<Diskstream> ds;
- Playlist* pl = 0;
- AudioPlaylist* apl = 0;
+ boost::shared_ptr<Playlist> pl;
+ boost::shared_ptr<AudioPlaylist> apl;
- if ((ds = atv->get_diskstream()) && ((pl = ds->playlist()) != 0) && ((apl = dynamic_cast<AudioPlaylist*> (pl)) != 0)) {
+ if ((ds = atv->get_diskstream()) && ((pl = ds->playlist()) != 0) && ((apl = boost::dynamic_pointer_cast<AudioPlaylist> (pl)) != 0)) {
Playlist::RegionList* regions = pl->regions_at (frame);
AudioPlaylist::Crossfades xfades;
@@ -2996,7 +2996,7 @@ void
Editor::mapped_set_selected_regionview_from_click (RouteTimeAxisView& tv, uint32_t ignored,
RegionView* basis, vector<RegionView*>* all_equivs)
{
- Playlist* pl;
+ boost::shared_ptr<Playlist> pl;
vector<boost::shared_ptr<Region> > results;
RegionView* marv;
boost::shared_ptr<Diskstream> ds;
@@ -3012,7 +3012,7 @@ Editor::mapped_set_selected_regionview_from_click (RouteTimeAxisView& tv, uint32
}
- if ((pl = dynamic_cast<Playlist*>(ds->playlist())) != 0) {
+ if ((pl = ds->playlist()) != 0) {
pl->get_equivalent_regions (basis->region(), results);
}
@@ -3213,7 +3213,7 @@ Editor::set_selected_regionview_from_region_list (boost::shared_ptr<Region> regi
if ((tatv = dynamic_cast<RouteTimeAxisView*> (*i)) != 0) {
- Playlist* pl;
+ boost::shared_ptr<Playlist> pl;
vector<boost::shared_ptr<Region> > results;
RegionView* marv;
boost::shared_ptr<Diskstream> ds;
@@ -3222,8 +3222,8 @@ Editor::set_selected_regionview_from_region_list (boost::shared_ptr<Region> regi
/* bus */
continue;
}
-
- if ((pl = dynamic_cast<Playlist*>(ds->playlist())) != 0) {
+
+ if ((pl = (ds->playlist())) != 0) {
pl->get_region_list_equivalent_regions (region, results);
}
@@ -3844,17 +3844,19 @@ Editor::end_location_changed (Location* location)
}
int
-Editor::playlist_deletion_dialog (Playlist* pl)
+Editor::playlist_deletion_dialog (boost::shared_ptr<Playlist> pl)
{
ArdourDialog dialog ("playlist deletion dialog");
Label label (string_compose (_("Playlist %1 is currently unused.\n"
- "If left alone, no audio files used by it will be cleaned.\n"
- "If deleted, audio files used by it alone by will cleaned."),
- pl->name()));
-
+ "If left alone, no audio files used by it will be cleaned.\n"
+ "If deleted, audio files used by it alone by will cleaned."),
+ pl->name()));
+
dialog.set_position (WIN_POS_CENTER);
dialog.get_vbox()->pack_start (label);
+ label.show ();
+
dialog.add_button (_("Delete playlist"), RESPONSE_ACCEPT);
dialog.add_button (_("Keep playlist"), RESPONSE_CANCEL);
dialog.add_button (_("Cancel"), RESPONSE_CANCEL);
diff --git a/gtk2_ardour/editor.h b/gtk2_ardour/editor.h
index 39b4b93222..2f435336ca 100644
--- a/gtk2_ardour/editor.h
+++ b/gtk2_ardour/editor.h
@@ -257,7 +257,7 @@ class Editor : public PublicEditor
void route_name_changed (TimeAxisView *);
gdouble frames_per_unit;
nframes_t leftmost_frame;
- void clear_playlist (ARDOUR::Playlist&);
+ void clear_playlist (boost::shared_ptr<ARDOUR::Playlist>);
void new_playlists ();
void copy_playlists ();
@@ -1039,7 +1039,7 @@ class Editor : public PublicEditor
void fade_in_drag_finished_callback (ArdourCanvas::Item*, GdkEvent*);
void fade_out_drag_finished_callback (ArdourCanvas::Item*, GdkEvent*);
- std::set<ARDOUR::Playlist*> motion_frozen_playlists;
+ std::set<boost::shared_ptr<ARDOUR::Playlist> > motion_frozen_playlists;
void region_drag_motion_callback (ArdourCanvas::Item*, GdkEvent*);
void region_drag_finished_callback (ArdourCanvas::Item*, GdkEvent*);
@@ -1754,7 +1754,7 @@ class Editor : public PublicEditor
/* handling cleanup */
- int playlist_deletion_dialog (ARDOUR::Playlist*);
+ int playlist_deletion_dialog (boost::shared_ptr<ARDOUR::Playlist>);
vector<sigc::connection> session_connections;
diff --git a/gtk2_ardour/editor_audio_import.cc b/gtk2_ardour/editor_audio_import.cc
index 65823efcac..56bdc82ff7 100644
--- a/gtk2_ardour/editor_audio_import.cc
+++ b/gtk2_ardour/editor_audio_import.cc
@@ -325,7 +325,7 @@ Editor::finish_bringing_in_audio (boost::shared_ptr<AudioRegion> region, uint32_
case ImportToTrack:
if (track) {
- Playlist* playlist = track->diskstream()->playlist();
+ boost::shared_ptr<Playlist> playlist = track->diskstream()->playlist();
boost::shared_ptr<AudioRegion> copy (boost::dynamic_pointer_cast<AudioRegion> (RegionFactory::create (region)));
begin_reversible_command (_("insert sndfile"));
diff --git a/gtk2_ardour/editor_canvas_events.cc b/gtk2_ardour/editor_canvas_events.cc
index ceff151541..19c83e01cc 100644
--- a/gtk2_ardour/editor_canvas_events.cc
+++ b/gtk2_ardour/editor_canvas_events.cc
@@ -513,8 +513,8 @@ Editor::canvas_crossfade_view_event (GdkEvent* event, ArdourCanvas::Item* item,
if (atv->is_audio_track()) {
- AudioPlaylist* pl;
- if ((pl = dynamic_cast<AudioPlaylist*> (atv->get_diskstream()->playlist())) != 0) {
+ boost::shared_ptr<AudioPlaylist> pl;
+ if ((pl = boost::dynamic_pointer_cast<AudioPlaylist> (atv->get_diskstream()->playlist())) != 0) {
Playlist::RegionList* rl = pl->regions_at (event_frame (event));
diff --git a/gtk2_ardour/editor_export_audio.cc b/gtk2_ardour/editor_export_audio.cc
index fd40b9cae0..57ab02e3a3 100644
--- a/gtk2_ardour/editor_export_audio.cc
+++ b/gtk2_ardour/editor_export_audio.cc
@@ -288,7 +288,7 @@ Editor::write_audio_selection (TimeSelection& ts)
if (atv->is_audio_track()) {
- AudioPlaylist* playlist = dynamic_cast<AudioPlaylist*>(atv->get_diskstream()->playlist());
+ boost::shared_ptr<AudioPlaylist> playlist = boost::dynamic_pointer_cast<AudioPlaylist>(atv->get_diskstream()->playlist());
if (playlist && write_audio_range (*playlist, atv->get_diskstream()->n_channels(), ts) == 0) {
ret = -1;
diff --git a/gtk2_ardour/editor_mouse.cc b/gtk2_ardour/editor_mouse.cc
index 76a40de95f..8868c1a88c 100644
--- a/gtk2_ardour/editor_mouse.cc
+++ b/gtk2_ardour/editor_mouse.cc
@@ -2791,8 +2791,8 @@ Editor::region_drag_motion_callback (ArdourCanvas::Item* item, GdkEvent* event)
vector<RegionView*> new_regionviews;
- set<Playlist*> affected_playlists;
- pair<set<Playlist*>::iterator,bool> insert_result;
+ 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) {
@@ -2800,7 +2800,7 @@ Editor::region_drag_motion_callback (ArdourCanvas::Item* item, GdkEvent* event)
rv = (*i);
- Playlist* to_playlist = rv->region()->playlist();
+ boost::shared_ptr<Playlist> to_playlist = rv->region()->playlist();
RouteTimeAxisView* atv = dynamic_cast<RouteTimeAxisView*>(&rv->get_time_axis_view());
insert_result = affected_playlists.insert (to_playlist);
@@ -3128,7 +3128,7 @@ Editor::region_drag_motion_callback (ArdourCanvas::Item* item, GdkEvent* event)
MOTION
************************************************************/
- pair<set<Playlist*>::iterator,bool> insert_result;
+ pair<set<boost::shared_ptr<Playlist> >::iterator,bool> insert_result;
const list<RegionView*>& layered_regions = selection->regions.by_layer();
for (list<RegionView*>::const_iterator i = layered_regions.begin(); i != layered_regions.end(); ++i) {
@@ -3240,7 +3240,7 @@ Editor::region_drag_motion_callback (ArdourCanvas::Item* item, GdkEvent* event)
AudioTimeAxisView* atv = dynamic_cast<AudioTimeAxisView*> (&rv->get_time_axis_view());
if (atv && atv->is_audio_track()) {
- AudioPlaylist* pl = dynamic_cast<AudioPlaylist*>(atv->get_diskstream()->playlist());
+ boost::shared_ptr<AudioPlaylist> pl = boost::dynamic_pointer_cast<AudioPlaylist>(atv->get_diskstream()->playlist());
if (pl) {
/* only freeze and capture state once */
@@ -3278,7 +3278,7 @@ Editor::region_drag_finished_callback (ArdourCanvas::Item* item, GdkEvent* event
{
nframes_t where;
RegionView* rv = reinterpret_cast<RegionView *> (drag_info.data);
- pair<set<Playlist*>::iterator,bool> insert_result;
+ pair<set<boost::shared_ptr<Playlist> >::iterator,bool> insert_result;
bool nocommit = true;
double speed;
RouteTimeAxisView* atv;
@@ -3350,8 +3350,8 @@ Editor::region_drag_finished_callback (ArdourCanvas::Item* item, GdkEvent* event
for (list<RegionView*>::const_iterator i = new_selection.begin(); i != new_selection.end();i++ ) {
- Playlist* from_playlist;
- Playlist* to_playlist;
+ boost::shared_ptr<Playlist> from_playlist;
+ boost::shared_ptr<Playlist> to_playlist;
double ix1, ix2, iy1, iy2;
@@ -3387,8 +3387,8 @@ Editor::region_drag_finished_callback (ArdourCanvas::Item* item, GdkEvent* event
for (list<RegionView*>::const_iterator i = new_selection.begin(); i != new_selection.end();i++ ) {
- Playlist* from_playlist;
- Playlist* to_playlist;
+ boost::shared_ptr<Playlist> from_playlist;
+ boost::shared_ptr<Playlist> to_playlist;
double ix1, ix2, iy1, iy2;
@@ -3459,9 +3459,9 @@ Editor::region_drag_finished_callback (ArdourCanvas::Item* item, GdkEvent* event
}
out:
- for (set<Playlist*>::iterator p = motion_frozen_playlists.begin(); p != motion_frozen_playlists.end(); ++p) {
+ for (set<boost::shared_ptr<Playlist> >::iterator p = motion_frozen_playlists.begin(); p != motion_frozen_playlists.end(); ++p) {
(*p)->thaw ();
- session->add_command (new MementoCommand<Playlist>(*(*p), 0, & (*p)->get_state()));
+ session->add_command (new MementoCommand<Playlist>(*((*p).get()), 0, & (*p)->get_state()));
}
motion_frozen_playlists.clear ();
@@ -3654,7 +3654,7 @@ Editor::start_selection_grab (ArdourCanvas::Item* item, GdkEvent* event)
begin_reversible_command (_("selection grab"));
- Playlist* playlist = clicked_trackview->playlist();
+ boost::shared_ptr<Playlist> playlist = clicked_trackview->playlist();
XMLNode *before = &(playlist->get_state());
clicked_trackview->playlist()->add_region (region, selection->time[clicked_selection].start);
@@ -3978,7 +3978,7 @@ Editor::trim_motion_callback (ArdourCanvas::Item* item, GdkEvent* event)
double speed = 1.0;
TimeAxisView* tvp = clicked_trackview;
RouteTimeAxisView* tv = dynamic_cast<RouteTimeAxisView*>(tvp);
- pair<set<Playlist*>::iterator,bool> insert_result;
+ pair<set<boost::shared_ptr<Playlist> >::iterator,bool> insert_result;
if (tv && tv->is_audio_track()) {
speed = tv->get_diskstream()->speed();
@@ -4024,7 +4024,7 @@ Editor::trim_motion_callback (ArdourCanvas::Item* item, GdkEvent* event)
if (arv)
arv->temporarily_hide_envelope ();
- Playlist * pl = (*i)->region()->playlist();
+ boost::shared_ptr<Playlist> pl = (*i)->region()->playlist();
insert_result = motion_frozen_playlists.insert (pl);
if (insert_result.second) {
session->add_command(new MementoCommand<Playlist>(*pl, &pl->get_state(), 0));
@@ -4216,9 +4216,9 @@ Editor::trim_finished_callback (ArdourCanvas::Item* item, GdkEvent* event)
}
}
- for (set<Playlist*>::iterator p = motion_frozen_playlists.begin(); p != motion_frozen_playlists.end(); ++p) {
+ for (set<boost::shared_ptr<Playlist> >::iterator p = motion_frozen_playlists.begin(); p != motion_frozen_playlists.end(); ++p) {
//(*p)->thaw ();
- session->add_command (new MementoCommand<Playlist>(*(*p), 0, &(*p)->get_state()));
+ session->add_command (new MementoCommand<Playlist>(*(*p).get(), 0, &(*p)->get_state()));
}
motion_frozen_playlists.clear ();
@@ -4252,22 +4252,22 @@ Editor::point_trim (GdkEvent* event)
i != selection->regions.by_layer().end(); ++i)
{
if (!(*i)->region()->locked()) {
- Playlist *pl = (*i)->region()->playlist();
+ boost::shared_ptr<Playlist> pl = (*i)->region()->playlist();
XMLNode &before = pl->get_state();
(*i)->region()->trim_front (new_bound, this);
XMLNode &after = pl->get_state();
- session->add_command(new MementoCommand<Playlist>(*pl, &before, &after));
+ session->add_command(new MementoCommand<Playlist>(*pl.get(), &before, &after));
}
}
} else {
if (!rv->region()->locked()) {
- Playlist *pl = rv->region()->playlist();
+ boost::shared_ptr<Playlist> pl = rv->region()->playlist();
XMLNode &before = pl->get_state();
rv->region()->trim_front (new_bound, this);
XMLNode &after = pl->get_state();
- session->add_command(new MementoCommand<Playlist>(*pl, &before, &after));
+ session->add_command(new MementoCommand<Playlist>(*pl.get(), &before, &after));
}
}
@@ -4283,22 +4283,22 @@ Editor::point_trim (GdkEvent* event)
for (list<RegionView*>::const_iterator i = selection->regions.by_layer().begin(); i != selection->regions.by_layer().end(); ++i)
{
if (!(*i)->region()->locked()) {
- Playlist *pl = (*i)->region()->playlist();
+ boost::shared_ptr<Playlist> pl = (*i)->region()->playlist();
XMLNode &before = pl->get_state();
(*i)->region()->trim_end (new_bound, this);
XMLNode &after = pl->get_state();
- session->add_command(new MementoCommand<Playlist>(*pl, &before, &after));
+ session->add_command(new MementoCommand<Playlist>(*pl.get(), &before, &after));
}
}
} else {
if (!rv->region()->locked()) {
- Playlist *pl = rv->region()->playlist();
+ boost::shared_ptr<Playlist> pl = rv->region()->playlist();
XMLNode &before = pl->get_state();
rv->region()->trim_end (new_bound, this);
XMLNode &after = pl->get_state();
- session->add_command (new MementoCommand<Playlist>(*pl, &before, &after));
+ session->add_command (new MementoCommand<Playlist>(*pl.get(), &before, &after));
}
}
@@ -4843,13 +4843,13 @@ Editor::mouse_brush_insert_region (RegionView* rv, nframes_t pos)
return;
}
- Playlist* playlist = atv->playlist();
+ boost::shared_ptr<Playlist> playlist = atv->playlist();
double speed = atv->get_diskstream()->speed();
XMLNode &before = playlist->get_state();
playlist->add_region (boost::dynamic_pointer_cast<AudioRegion> (RegionFactory::create (arv->audio_region())), (nframes_t) (pos * speed));
XMLNode &after = playlist->get_state();
- session->add_command(new MementoCommand<Playlist>(*playlist, &before, &after));
+ session->add_command(new MementoCommand<Playlist>(*playlist.get(), &before, &after));
// playlist is frozen, so we have to update manually
diff --git a/gtk2_ardour/editor_ops.cc b/gtk2_ardour/editor_ops.cc
index 00faa2f21d..c8c11d59c1 100644
--- a/gtk2_ardour/editor_ops.cc
+++ b/gtk2_ardour/editor_ops.cc
@@ -44,6 +44,7 @@
#include <ardour/audio_track.h>
#include <ardour/audioplaylist.h>
#include <ardour/region_factory.h>
+#include <ardour/playlist_factory.h>
#include <ardour/reverse.h>
#include "ardour_ui.h"
@@ -122,7 +123,7 @@ Editor::split_regions_at (nframes_t where, RegionSelection& regions)
tmp = a;
++tmp;
- Playlist* pl = (*a)->region()->playlist();
+ boost::shared_ptr<Playlist> pl = (*a)->region()->playlist();
AudioRegionView* const arv = dynamic_cast<AudioRegionView*>(*a);
if (arv)
@@ -149,7 +150,7 @@ Editor::remove_clicked_region ()
return;
}
- Playlist* playlist = clicked_audio_trackview->playlist();
+ boost::shared_ptr<Playlist> playlist = clicked_audio_trackview->playlist();
begin_reversible_command (_("remove region"));
XMLNode &before = playlist->get_state();
@@ -232,7 +233,7 @@ Editor::select_region_for_operation (int dir, TimeAxisView **tv)
RouteTimeAxisView* rtv;
if ((rtv = dynamic_cast<RouteTimeAxisView*> (*tv)) != 0) {
- Playlist *pl;
+ boost::shared_ptr<Playlist> pl;
if ((pl = rtv->playlist()) == 0) {
return region;
@@ -1719,7 +1720,7 @@ Editor::insert_region_list_drag (boost::shared_ptr<AudioRegion> region, int x, i
TimeAxisView *tv;
nframes_t where;
AudioTimeAxisView *atv = 0;
- Playlist *playlist;
+ boost::shared_ptr<Playlist> playlist;
track_canvas.window_to_world (x, y, wx, wy);
wx += horizontal_adjustment.get_value();
@@ -1749,20 +1750,26 @@ Editor::insert_region_list_drag (boost::shared_ptr<AudioRegion> region, int x, i
return;
}
+ cerr << "drop target playlist, UC = " << playlist.use_count() << endl;
+
snap_to (where);
begin_reversible_command (_("insert dragged region"));
XMLNode &before = playlist->get_state();
+ cerr << "pre add target playlist, UC = " << playlist.use_count() << endl;
playlist->add_region (RegionFactory::create (region), where, 1.0);
+ cerr << "post add target playlist, UC = " << playlist.use_count() << endl;
session->add_command(new MementoCommand<Playlist>(*playlist, &before, &playlist->get_state()));
commit_reversible_command ();
+
+ cerr << "post drop target playlist, UC = " << playlist.use_count() << endl;
}
void
Editor::insert_region_list_selection (float times)
{
RouteTimeAxisView *tv = 0;
- Playlist *playlist;
+ boost::shared_ptr<Playlist> playlist;
if (clicked_audio_trackview != 0) {
tv = clicked_audio_trackview;
@@ -2097,7 +2104,7 @@ Editor::region_from_selection ()
for (TrackSelection::iterator i = selection->tracks.begin(); i != selection->tracks.end(); ++i) {
boost::shared_ptr<AudioRegion> current;
boost::shared_ptr<Region> current_r;
- Playlist *pl;
+ boost::shared_ptr<Playlist> pl;
nframes_t internal_start;
string new_name;
@@ -2134,7 +2141,7 @@ Editor::create_region_from_selection (vector<boost::shared_ptr<AudioRegion> >& n
boost::shared_ptr<AudioRegion> current;
boost::shared_ptr<Region> current_r;
- Playlist* playlist;
+ boost::shared_ptr<Playlist> playlist;
nframes_t internal_start;
string new_name;
@@ -2189,7 +2196,7 @@ Editor::separate_region_from_selection ()
return;
}
- Playlist *playlist;
+ boost::shared_ptr<Playlist> playlist;
for (TrackSelection::iterator i = selection->tracks.begin(); i != selection->tracks.end(); ++i) {
@@ -2235,7 +2242,7 @@ Editor::separate_regions_using_location (Location& loc)
return;
}
- Playlist *playlist;
+ boost::shared_ptr<Playlist> playlist;
/* XXX i'm unsure as to whether this should operate on selected tracks only
or the entire enchillada. uncomment the below line to correct the behaviour
@@ -2284,8 +2291,8 @@ Editor::crop_region_to_selection ()
return;
}
- vector<Playlist*> playlists;
- Playlist *playlist;
+ vector<boost::shared_ptr<Playlist> > playlists;
+ boost::shared_ptr<Playlist> playlist;
if (clicked_trackview != 0) {
@@ -2321,7 +2328,7 @@ Editor::crop_region_to_selection ()
begin_reversible_command (_("trim to selection"));
- for (vector<Playlist*>::iterator i = playlists.begin(); i != playlists.end(); ++i) {
+ for (vector<boost::shared_ptr<Playlist> >::iterator i = playlists.begin(); i != playlists.end(); ++i) {
boost::shared_ptr<Region> region;
@@ -2371,7 +2378,7 @@ Editor::region_fill_track ()
if (!ar)
continue;
- Playlist* pl = region->playlist();
+ boost::shared_ptr<Playlist> pl = region->playlist();
if (end <= region->last_frame()) {
return;
@@ -2415,7 +2422,7 @@ Editor::region_fill_selection ()
nframes_t start = selection->time[clicked_selection].start;
nframes_t end = selection->time[clicked_selection].end;
- Playlist *playlist;
+ boost::shared_ptr<Playlist> playlist;
if (selection->tracks.empty()) {
return;
@@ -2781,7 +2788,7 @@ Editor::bounce_range_selection ()
continue;
}
- Playlist* playlist;
+ boost::shared_ptr<Playlist> playlist;
if ((playlist = atv->playlist()) == 0) {
return;
@@ -2897,7 +2904,7 @@ Editor::cut_copy_points (CutCopyOp op)
}
struct PlaylistState {
- Playlist* playlist;
+ boost::shared_ptr<Playlist> playlist;
XMLNode* before;
};
@@ -2910,7 +2917,7 @@ struct lt_playlist {
void
Editor::cut_copy_regions (CutCopyOp op)
{
- typedef std::map<AudioPlaylist*,AudioPlaylist*> PlaylistMapping;
+ typedef std::map<boost::shared_ptr<AudioPlaylist>,boost::shared_ptr<AudioPlaylist> > PlaylistMapping;
PlaylistMapping pmap;
nframes_t first_position = max_frames;
@@ -2921,7 +2928,8 @@ Editor::cut_copy_regions (CutCopyOp op)
first_position = min ((*x)->region()->position(), first_position);
if (op == Cut || op == Clear) {
- AudioPlaylist *pl = dynamic_cast<AudioPlaylist*>((*x)->region()->playlist());
+ boost::shared_ptr<AudioPlaylist> pl = boost::dynamic_pointer_cast<AudioPlaylist>((*x)->region()->playlist());
+
if (pl) {
PlaylistState before;
@@ -2939,8 +2947,8 @@ Editor::cut_copy_regions (CutCopyOp op)
for (RegionSelection::iterator x = selection->regions.begin(); x != selection->regions.end(); ) {
- AudioPlaylist *pl = dynamic_cast<AudioPlaylist*>((*x)->region()->playlist());
- AudioPlaylist* npl;
+ boost::shared_ptr<AudioPlaylist> pl = boost::dynamic_pointer_cast<AudioPlaylist>((*x)->region()->playlist());
+ boost::shared_ptr<AudioPlaylist> npl;
RegionSelection::iterator tmp;
tmp = x;
@@ -2951,7 +2959,7 @@ Editor::cut_copy_regions (CutCopyOp op)
PlaylistMapping::iterator pi = pmap.find (pl);
if (pi == pmap.end()) {
- npl = new AudioPlaylist (*session, "cutlist", true);
+ npl = boost::dynamic_pointer_cast<AudioPlaylist> (PlaylistFactory::create (*session, "cutlist", true));
npl->freeze();
pmap[pl] = npl;
} else {
@@ -2983,7 +2991,7 @@ Editor::cut_copy_regions (CutCopyOp op)
x = tmp;
}
- list<Playlist*> foo;
+ list<boost::shared_ptr<Playlist> > foo;
for (PlaylistMapping::iterator i = pmap.begin(); i != pmap.end(); ++i) {
foo.push_back (i->second);
@@ -3080,8 +3088,8 @@ Editor::paste_named_selection (float times)
TreeModel::iterator i = selected->get_selected();
NamedSelection* ns = (*i)[named_selection_columns.selection];
- list<Playlist*>::iterator chunk;
- list<Playlist*>::iterator tmp;
+ list<boost::shared_ptr<Playlist> >::iterator chunk;
+ list<boost::shared_ptr<Playlist> >::iterator tmp;
chunk = ns->playlists.begin();
@@ -3090,8 +3098,8 @@ Editor::paste_named_selection (float times)
for (t = selection->tracks.begin(); t != selection->tracks.end(); ++t) {
AudioTimeAxisView* atv;
- Playlist* pl;
- AudioPlaylist* apl;
+ boost::shared_ptr<Playlist> pl;
+ boost::shared_ptr<AudioPlaylist> apl;
if ((atv = dynamic_cast<AudioTimeAxisView*> (*t)) == 0) {
continue;
@@ -3100,8 +3108,8 @@ Editor::paste_named_selection (float times)
if ((pl = atv->playlist()) == 0) {
continue;
}
-
- if ((apl = dynamic_cast<AudioPlaylist*> (pl)) == 0) {
+
+ if ((apl = boost::dynamic_pointer_cast<AudioPlaylist> (pl)) == 0) {
continue;
}
@@ -3109,7 +3117,7 @@ Editor::paste_named_selection (float times)
++tmp;
XMLNode &before = apl->get_state();
- apl->paste (**chunk, edit_cursor->current_frame, times);
+ apl->paste (*chunk, edit_cursor->current_frame, times);
session->add_command(new MementoCommand<AudioPlaylist>(*apl, &before, &apl->get_state()));
if (tmp != ns->playlists.end()) {
@@ -3123,7 +3131,7 @@ Editor::paste_named_selection (float times)
void
Editor::duplicate_some_regions (RegionSelection& regions, float times)
{
- Playlist *playlist;
+ boost::shared_ptr<Playlist> playlist;
RegionSelection sel = regions; // clear (below) will clear the argument list
begin_reversible_command (_("duplicate region"));
@@ -3161,7 +3169,7 @@ Editor::duplicate_selection (float times)
return;
}
- Playlist *playlist;
+ boost::shared_ptr<Playlist> playlist;
vector<boost::shared_ptr<AudioRegion> > new_regions;
vector<boost::shared_ptr<AudioRegion> >::iterator ri;
@@ -3227,20 +3235,20 @@ Editor::center_edit_cursor ()
}
void
-Editor::clear_playlist (Playlist& playlist)
+Editor::clear_playlist (boost::shared_ptr<Playlist> playlist)
{
begin_reversible_command (_("clear playlist"));
- XMLNode &before = playlist.get_state();
- playlist.clear ();
- XMLNode &after = playlist.get_state();
- session->add_command (new MementoCommand<Playlist>(playlist, &before, &after));
+ XMLNode &before = playlist->get_state();
+ playlist->clear ();
+ XMLNode &after = playlist->get_state();
+ session->add_command (new MementoCommand<Playlist>(*playlist.get(), &before, &after));
commit_reversible_command ();
}
void
Editor::nudge_track (bool use_edit_cursor, bool forwards)
{
- Playlist *playlist;
+ boost::shared_ptr<Playlist> playlist;
nframes_t distance;
nframes_t next_distance;
nframes_t start;
@@ -3388,7 +3396,7 @@ Editor::apply_filter (AudioFilter& filter, string command)
if (!arv)
continue;
- Playlist* playlist = arv->region()->playlist();
+ boost::shared_ptr<Playlist> playlist = arv->region()->playlist();
RegionSelection::iterator tmp;
diff --git a/gtk2_ardour/editor_region_list.cc b/gtk2_ardour/editor_region_list.cc
index fdb8ca9dd3..d12d562237 100644
--- a/gtk2_ardour/editor_region_list.cc
+++ b/gtk2_ardour/editor_region_list.cc
@@ -101,7 +101,8 @@ Editor::add_audio_region_to_region_display (boost::shared_ptr<AudioRegion> regio
parent = *(region_list_model->append());
parent[region_list_columns.name] = _("Hidden");
- /// XXX FIX ME parent[region_list_columns.region]->reset ();
+ boost::shared_ptr<Region> proxy = parent[region_list_columns.region];
+ proxy.reset ();
} else {
@@ -109,7 +110,8 @@ Editor::add_audio_region_to_region_display (boost::shared_ptr<AudioRegion> regio
parent = *(region_list_model->insert(iter));
parent[region_list_columns.name] = _("Hidden");
- /// XXX FIX ME parent[region_list_columns.region]->reset ();
+ boost::shared_ptr<Region> proxy = parent[region_list_columns.region];
+ proxy.reset ();
} else {
parent = *iter;
diff --git a/gtk2_ardour/editor_selection_list.cc b/gtk2_ardour/editor_selection_list.cc
index 469e7a472e..8e88ee497b 100644
--- a/gtk2_ardour/editor_selection_list.cc
+++ b/gtk2_ardour/editor_selection_list.cc
@@ -150,12 +150,12 @@ Editor::create_named_selection (const string & name)
return;
}
- Playlist* what_we_found;
- list<Playlist*> thelist;
+ boost::shared_ptr<Playlist> what_we_found;
+ list<boost::shared_ptr<Playlist> > thelist;
for (TrackViewList::iterator i = views->begin(); i != views->end(); ++i) {
- Playlist *pl = (*i)->playlist();
+ boost::shared_ptr<Playlist> pl = (*i)->playlist();
if (pl) {
diff --git a/gtk2_ardour/editor_timefx.cc b/gtk2_ardour/editor_timefx.cc
index 188960c962..bfc5ee85cd 100644
--- a/gtk2_ardour/editor_timefx.cc
+++ b/gtk2_ardour/editor_timefx.cc
@@ -159,7 +159,7 @@ void
Editor::do_timestretch (TimeStretchDialog& dialog)
{
Track* t;
- Playlist* playlist;
+ boost::shared_ptr<Playlist> playlist;
boost::shared_ptr<Region> new_region;
for (RegionSelection::iterator i = dialog.regions.begin(); i != dialog.regions.end(); ) {
diff --git a/gtk2_ardour/playlist_selection.h b/gtk2_ardour/playlist_selection.h
index af0031fec9..813f8a9211 100644
--- a/gtk2_ardour/playlist_selection.h
+++ b/gtk2_ardour/playlist_selection.h
@@ -2,11 +2,12 @@
#define __ardour_gtk_playlist_selection_h__
#include <list>
+#include <boost/shared_ptr.hpp>
namespace ARDOUR {
class Playlist;
}
-struct PlaylistSelection : list<ARDOUR::Playlist*> {};
+struct PlaylistSelection : list<boost::shared_ptr<ARDOUR::Playlist> > {};
#endif /* __ardour_gtk_playlist_selection_h__ */
diff --git a/gtk2_ardour/playlist_selector.cc b/gtk2_ardour/playlist_selector.cc
index ffeaf8f5e9..87531bbbd0 100644
--- a/gtk2_ardour/playlist_selector.cc
+++ b/gtk2_ardour/playlist_selector.cc
@@ -86,6 +86,17 @@ PlaylistSelector::clear_map ()
dspl_map.clear ();
}
+bool
+PlaylistSelector::on_unmap_event (GdkEventAny* ev)
+{
+ cerr << "PLselector unmapped\n";
+ clear_map ();
+ if (model) {
+ model->clear ();
+ }
+ return Dialog::on_unmap_event (ev);
+}
+
void
PlaylistSelector::show_for (RouteUI* ruix)
{
@@ -112,7 +123,8 @@ PlaylistSelector::show_for (RouteUI* ruix)
TreeModel::Row others = *(model->append ());
others[columns.text] = _("Other tracks");
- others[columns.playlist] = 0;
+ boost::shared_ptr<Playlist> proxy = others[columns.playlist];
+ proxy.reset ();
for (DSPL_Map::iterator x = dspl_map.begin(); x != dspl_map.end(); ++x) {
@@ -139,18 +151,20 @@ PlaylistSelector::show_for (RouteUI* ruix)
if (ds == this_ds) {
row = *(model->prepend());
row[columns.text] = nodename;
- row[columns.playlist] = 0;
+ boost::shared_ptr<Playlist> proxy = row[columns.playlist];
+ proxy.reset ();
} else {
row = *(model->append (others.children()));
row[columns.text] = nodename;
- row[columns.playlist] = 0;
+ boost::shared_ptr<Playlist> proxy = row[columns.playlist];
+ proxy.reset ();
}
/* Now insert all the playlists for this diskstream/track in a subtree */
- list<Playlist*> *pls = x->second;
+ list<boost::shared_ptr<Playlist> > *pls = x->second;
- for (list<Playlist*>::iterator p = pls->begin(); p != pls->end(); ++p) {
+ for (list<boost::shared_ptr<Playlist> >::iterator p = pls->begin(); p != pls->end(); ++p) {
TreeModel::Row child_row;
@@ -173,15 +187,15 @@ PlaylistSelector::show_for (RouteUI* ruix)
}
void
-PlaylistSelector::add_playlist_to_map (Playlist *pl)
+PlaylistSelector::add_playlist_to_map (boost::shared_ptr<Playlist> pl)
{
- AudioPlaylist* apl;
+ boost::shared_ptr<AudioPlaylist> apl;
if (pl->frozen()) {
return;
}
-
- if ((apl = dynamic_cast<AudioPlaylist*> (pl)) == 0) {
+
+ if ((apl = boost::dynamic_pointer_cast<AudioPlaylist> (pl)) == 0) {
return;
}
@@ -189,7 +203,7 @@ PlaylistSelector::add_playlist_to_map (Playlist *pl)
if ((x = dspl_map.find (apl->get_orig_diskstream_id())) == dspl_map.end()) {
- pair<PBD::ID,list<Playlist*>*> newp (apl->get_orig_diskstream_id(), new list<Playlist*>);
+ pair<PBD::ID,list<boost::shared_ptr<Playlist> >*> newp (apl->get_orig_diskstream_id(), new list<boost::shared_ptr<Playlist> >);
x = dspl_map.insert (dspl_map.end(), newp);
}
@@ -219,7 +233,7 @@ PlaylistSelector::close_button_click ()
void
PlaylistSelector::selection_changed ()
{
- Playlist *playlist;
+ boost::shared_ptr<Playlist> playlist;
TreeModel::iterator iter = tree.get_selection()->get_selected();
@@ -231,14 +245,14 @@ PlaylistSelector::selection_changed ()
if ((playlist = ((*iter)[columns.playlist])) != 0) {
AudioTrack* at;
- AudioPlaylist* apl;
+ boost::shared_ptr<AudioPlaylist> apl;
if ((at = rui->audio_track()) == 0) {
/* eh? */
return;
}
- if ((apl = dynamic_cast<AudioPlaylist*> (playlist)) == 0) {
+ if ((apl = boost::dynamic_pointer_cast<AudioPlaylist> (playlist)) == 0) {
/* eh? */
return;
}
diff --git a/gtk2_ardour/playlist_selector.h b/gtk2_ardour/playlist_selector.h
index 2829ba54bb..071f82c616 100644
--- a/gtk2_ardour/playlist_selector.h
+++ b/gtk2_ardour/playlist_selector.h
@@ -20,6 +20,8 @@
#ifndef __ardour_playlist_selector_h__
#define __ardour_playlist_selector_h__
+#include <boost/shared_ptr.hpp>
+
#include <gtkmm/box.h>
#include <gtkmm/scrolledwindow.h>
#include <gtkmm/button.h>
@@ -45,8 +47,11 @@ class PlaylistSelector : public ArdourDialog
void set_session (ARDOUR::Session*);
void show_for (RouteUI*);
+ protected:
+ bool on_unmap_event (GdkEventAny*);
+
private:
- typedef std::map<PBD::ID,std::list<ARDOUR::Playlist*>*> DSPL_Map;
+ typedef std::map<PBD::ID,std::list<boost::shared_ptr<ARDOUR::Playlist> >*> DSPL_Map;
ARDOUR::Session* session;
Gtk::ScrolledWindow scroller;
@@ -55,7 +60,7 @@ class PlaylistSelector : public ArdourDialog
sigc::connection select_connection;
- void add_playlist_to_map (ARDOUR::Playlist*);
+ void add_playlist_to_map (boost::shared_ptr<ARDOUR::Playlist>);
void clear_map ();
void close_button_click ();
void selection_changed ();
@@ -66,7 +71,7 @@ class PlaylistSelector : public ArdourDialog
add (playlist);
}
Gtk::TreeModelColumn<std::string> text;
- Gtk::TreeModelColumn<ARDOUR::Playlist*> playlist;
+ Gtk::TreeModelColumn<boost::shared_ptr<ARDOUR::Playlist> > playlist;
};
ModelColumns columns;
diff --git a/gtk2_ardour/public_editor.h b/gtk2_ardour/public_editor.h
index 390cb20ca8..8a105cd0aa 100644
--- a/gtk2_ardour/public_editor.h
+++ b/gtk2_ardour/public_editor.h
@@ -106,7 +106,7 @@ class PublicEditor : public Gtk::Window, public PBD::StatefulThingWithGoingAway
virtual gdouble get_current_zoom () = 0;
virtual PlaylistSelector& playlist_selector() const = 0;
virtual void route_name_changed (TimeAxisView *) = 0;
- virtual void clear_playlist (ARDOUR::Playlist&) = 0;
+ virtual void clear_playlist (boost::shared_ptr<ARDOUR::Playlist>) = 0;
virtual void new_playlists () = 0;
virtual void copy_playlists () = 0;
virtual void clear_playlists () = 0;
diff --git a/gtk2_ardour/route_time_axis.cc b/gtk2_ardour/route_time_axis.cc
index 92af31b19a..bacd9e23f4 100644
--- a/gtk2_ardour/route_time_axis.cc
+++ b/gtk2_ardour/route_time_axis.cc
@@ -245,9 +245,9 @@ RouteTimeAxisView::~RouteTimeAxisView ()
}
void
-RouteTimeAxisView::set_playlist (Playlist *newplaylist)
+RouteTimeAxisView::set_playlist (boost::shared_ptr<Playlist> newplaylist)
{
- Playlist *pl = playlist();
+ boost::shared_ptr<Playlist> pl = playlist();
assert(pl);
modified_connection.disconnect ();
@@ -312,7 +312,7 @@ RouteTimeAxisView::playlist_changed ()
label_view ();
if (is_track()) {
- set_playlist (dynamic_cast<Playlist*>(get_diskstream()->playlist()));
+ set_playlist (get_diskstream()->playlist());
}
}
@@ -843,7 +843,7 @@ RouteTimeAxisView::rename_current_playlist ()
if (!ds || ds->destructive())
return;
- Playlist *const pl = ds->playlist();
+ boost::shared_ptr<Playlist> pl = ds->playlist();
if (!pl)
return;
@@ -874,7 +874,7 @@ RouteTimeAxisView::use_copy_playlist (bool prompt)
if (!ds || ds->destructive())
return;
- Playlist *const pl = ds->playlist();
+ boost::shared_ptr<const Playlist> pl = ds->playlist();
if (!pl)
return;
@@ -922,7 +922,7 @@ RouteTimeAxisView::use_new_playlist (bool prompt)
if (!ds || ds->destructive())
return;
- Playlist *const pl = ds->playlist();
+ boost::shared_ptr<const Playlist> pl = ds->playlist();
if (!pl)
return;
@@ -955,6 +955,7 @@ RouteTimeAxisView::use_new_playlist (bool prompt)
if (name.length()) {
ds->use_new_playlist ();
ds->playlist()->set_name (name);
+ cerr << " installed new PL, UC = " << ds->playlist().use_count() << endl;
}
}
@@ -965,11 +966,11 @@ RouteTimeAxisView::clear_playlist ()
if (!ds || ds->destructive())
return;
- Playlist *const pl = ds->playlist();
+ boost::shared_ptr<Playlist> pl = ds->playlist();
if (!pl)
return;
- editor.clear_playlist (*pl);
+ editor.clear_playlist (pl);
}
void
@@ -1087,7 +1088,7 @@ RouteTimeAxisView::name() const
return _route->name();
}
-Playlist *
+boost::shared_ptr<Playlist>
RouteTimeAxisView::playlist () const
{
boost::shared_ptr<Diskstream> ds;
@@ -1095,7 +1096,7 @@ RouteTimeAxisView::playlist () const
if ((ds = get_diskstream()) != 0) {
return ds->playlist();
} else {
- return 0;
+ return boost::shared_ptr<Playlist> ();
}
}
@@ -1146,7 +1147,7 @@ boost::shared_ptr<Region>
RouteTimeAxisView::find_next_region (nframes_t pos, RegionPoint point, int32_t dir)
{
boost::shared_ptr<Diskstream> stream;
- Playlist *playlist = 0;
+ boost::shared_ptr<Playlist> playlist;
if ((stream = get_diskstream()) != 0 && (playlist = stream->playlist()) != 0) {
return playlist->find_next_region (pos, point, dir);
@@ -1158,9 +1159,9 @@ RouteTimeAxisView::find_next_region (nframes_t pos, RegionPoint point, int32_t d
bool
RouteTimeAxisView::cut_copy_clear (Selection& selection, CutCopyOp op)
{
- Playlist* what_we_got;
+ boost::shared_ptr<Playlist> what_we_got;
boost::shared_ptr<Diskstream> ds = get_diskstream();
- Playlist* playlist;
+ boost::shared_ptr<Playlist> playlist;
bool ret = false;
if (ds == 0) {
@@ -1185,7 +1186,7 @@ RouteTimeAxisView::cut_copy_clear (Selection& selection, CutCopyOp op)
case Cut:
if ((what_we_got = playlist->cut (time)) != 0) {
editor.get_cut_buffer().add (what_we_got);
- _session.add_command( new MementoCommand<Playlist>(*playlist, &before, &playlist->get_state()));
+ _session.add_command( new MementoCommand<Playlist>(*playlist.get(), &before, &playlist->get_state()));
ret = true;
}
break;
@@ -1198,7 +1199,7 @@ RouteTimeAxisView::cut_copy_clear (Selection& selection, CutCopyOp op)
case Clear:
if ((what_we_got = playlist->cut (time)) != 0) {
_session.add_command( new MementoCommand<Playlist>(*playlist, &before, &playlist->get_state()));
- what_we_got->unref ();
+ what_we_got->release ();
ret = true;
}
break;
@@ -1214,7 +1215,7 @@ RouteTimeAxisView::paste (nframes_t pos, float times, Selection& selection, size
return false;
}
- Playlist* playlist = get_diskstream()->playlist();
+ boost::shared_ptr<Playlist> playlist = get_diskstream()->playlist();
PlaylistSelection::iterator p;
for (p = selection.playlists.begin(); p != selection.playlists.end() && nth; ++p, --nth);
@@ -1227,7 +1228,7 @@ RouteTimeAxisView::paste (nframes_t pos, float times, Selection& selection, size
pos = session_frame_to_track_frame(pos, get_diskstream()->speed() );
XMLNode &before = playlist->get_state();
- playlist->paste (**p, pos, times);
+ playlist->paste (*p, pos, times);
_session.add_command( new MementoCommand<Playlist>(*playlist, &before, &playlist->get_state()));
return true;
@@ -1269,29 +1270,29 @@ RouteTimeAxisView::build_playlist_menu (Gtk::Menu * menu)
playlist_menu = new Menu;
playlist_menu->set_name ("ArdourContextMenu");
- vector<Playlist*> playlists;
+ vector<boost::shared_ptr<Playlist> > playlists;
boost::shared_ptr<Diskstream> ds = get_diskstream();
RadioMenuItem::Group playlist_group;
_session.get_playlists (playlists);
- for (vector<Playlist*>::iterator i = playlists.begin(); i != playlists.end(); ++i) {
+ for (vector<boost::shared_ptr<Playlist> >::iterator i = playlists.begin(); i != playlists.end(); ++i) {
if ((*i)->get_orig_diskstream_id() == ds->id()) {
- playlist_items.push_back (RadioMenuElem (playlist_group, (*i)->name(), bind (mem_fun (*this, &RouteTimeAxisView::use_playlist), (*i))));
+ playlist_items.push_back (RadioMenuElem (playlist_group, (*i)->name(), bind (mem_fun (*this, &RouteTimeAxisView::use_playlist),
+ boost::weak_ptr<Playlist> (*i))));
if (ds->playlist()->id() == (*i)->id()) {
static_cast<RadioMenuItem*>(&playlist_items.back())->set_active();
}
} else if (ds->playlist()->id() == (*i)->id()) {
- playlist_items.push_back (RadioMenuElem (playlist_group, (*i)->name(), bind (mem_fun (*this, &RouteTimeAxisView::use_playlist), (*i))));
+ playlist_items.push_back (RadioMenuElem (playlist_group, (*i)->name(), bind (mem_fun (*this, &RouteTimeAxisView::use_playlist),
+ boost::weak_ptr<Playlist>(*i))));
static_cast<RadioMenuItem*>(&playlist_items.back())->set_active();
}
}
-
-
playlist_items.push_back (SeparatorElem());
playlist_items.push_back (MenuElem (_("Rename"), mem_fun(*this, &RouteTimeAxisView::rename_current_playlist)));
playlist_items.push_back (SeparatorElem());
@@ -1306,12 +1307,18 @@ RouteTimeAxisView::build_playlist_menu (Gtk::Menu * menu)
}
void
-RouteTimeAxisView::use_playlist (Playlist* pl)
+RouteTimeAxisView::use_playlist (boost::weak_ptr<Playlist> wpl)
{
- AudioPlaylist* apl = dynamic_cast<AudioPlaylist*> (pl);
-
assert (is_track());
+ boost::shared_ptr<Playlist> pl (wpl.lock());
+
+ if (!pl) {
+ return;
+ }
+
+ boost::shared_ptr<AudioPlaylist> apl = boost::dynamic_pointer_cast<AudioPlaylist> (pl);
+
if (apl) {
get_diskstream()->use_playlist (apl);
}
diff --git a/gtk2_ardour/route_time_axis.h b/gtk2_ardour/route_time_axis.h
index cefe954c9a..1e28a790a6 100644
--- a/gtk2_ardour/route_time_axis.h
+++ b/gtk2_ardour/route_time_axis.h
@@ -99,7 +99,7 @@ public:
string name() const;
StreamView* view() const { return _view; }
ARDOUR::RouteGroup* edit_group() const;
- ARDOUR::Playlist* playlist() const;
+ boost::shared_ptr<ARDOUR::Playlist> playlist() const;
protected:
friend class StreamView;
@@ -176,7 +176,7 @@ protected:
void align_style_changed ();
void set_align_style (ARDOUR::AlignStyle);
- virtual void set_playlist (ARDOUR::Playlist *);
+ virtual void set_playlist (boost::shared_ptr<ARDOUR::Playlist>);
void playlist_click ();
void show_playlist_selector ();
void playlist_changed ();
@@ -229,7 +229,7 @@ protected:
Gtk::Menu* playlist_action_menu;
Gtk::MenuItem* playlist_item;
- void use_playlist (ARDOUR::Playlist*);
+ void use_playlist (boost::weak_ptr<ARDOUR::Playlist>);
ArdourCanvas::SimpleRect* timestretch_rect;
diff --git a/gtk2_ardour/selection.cc b/gtk2_ardour/selection.cc
index 06475aa1d4..38a0cdd8e2 100644
--- a/gtk2_ardour/selection.cc
+++ b/gtk2_ardour/selection.cc
@@ -132,7 +132,7 @@ Selection::clear_playlists ()
/* Selections own their playlists */
for (PlaylistSelection::iterator i = playlists.begin(); i != playlists.end(); ++i) {
- (*i)->unref ();
+ (*i)->release ();
}
if (!playlists.empty()) {
@@ -165,12 +165,12 @@ Selection::toggle (boost::shared_ptr<Redirect> r)
}
void
-Selection::toggle (Playlist* pl)
+Selection::toggle (boost::shared_ptr<Playlist> pl)
{
PlaylistSelection::iterator i;
if ((i = find (playlists.begin(), playlists.end(), pl)) == playlists.end()) {
- pl->ref ();
+ pl->use ();
playlists.push_back(pl);
} else {
playlists.erase (i);
@@ -260,23 +260,23 @@ Selection::add (boost::shared_ptr<Redirect> r)
}
void
-Selection::add (Playlist* pl)
+Selection::add (boost::shared_ptr<Playlist> pl)
{
if (find (playlists.begin(), playlists.end(), pl) == playlists.end()) {
- pl->ref ();
+ pl->use ();
playlists.push_back(pl);
PlaylistsChanged ();
}
}
void
-Selection::add (const list<Playlist*>& pllist)
+Selection::add (const list<boost::shared_ptr<Playlist> >& pllist)
{
bool changed = false;
- for (list<Playlist*>::const_iterator i = pllist.begin(); i != pllist.end(); ++i) {
+ for (list<boost::shared_ptr<Playlist> >::const_iterator i = pllist.begin(); i != pllist.end(); ++i) {
if (find (playlists.begin(), playlists.end(), (*i)) == playlists.end()) {
- (*i)->ref ();
+ (*i)->use ();
playlists.push_back (*i);
changed = true;
}
@@ -429,9 +429,9 @@ Selection::remove (const list<TimeAxisView*>& track_list)
}
void
-Selection::remove (Playlist* track)
+Selection::remove (boost::shared_ptr<Playlist> track)
{
- list<Playlist*>::iterator i;
+ list<boost::shared_ptr<Playlist> >::iterator i;
if ((i = find (playlists.begin(), playlists.end(), track)) != playlists.end()) {
playlists.erase (i);
PlaylistsChanged();
@@ -439,13 +439,13 @@ Selection::remove (Playlist* track)
}
void
-Selection::remove (const list<Playlist*>& pllist)
+Selection::remove (const list<boost::shared_ptr<Playlist> >& pllist)
{
bool changed = false;
- for (list<Playlist*>::const_iterator i = pllist.begin(); i != pllist.end(); ++i) {
+ for (list<boost::shared_ptr<Playlist> >::const_iterator i = pllist.begin(); i != pllist.end(); ++i) {
- list<Playlist*>::iterator x;
+ list<boost::shared_ptr<Playlist> >::iterator x;
if ((x = find (playlists.begin(), playlists.end(), (*i))) != playlists.end()) {
playlists.erase (x);
@@ -520,14 +520,14 @@ Selection::set (const list<TimeAxisView*>& track_list)
}
void
-Selection::set (Playlist* playlist)
+Selection::set (boost::shared_ptr<Playlist> playlist)
{
clear_playlists ();
add (playlist);
}
void
-Selection::set (const list<Playlist*>& pllist)
+Selection::set (const list<boost::shared_ptr<Playlist> >& pllist)
{
clear_playlists ();
add (pllist);
diff --git a/gtk2_ardour/selection.h b/gtk2_ardour/selection.h
index c4336fba21..a2997cd7b5 100644
--- a/gtk2_ardour/selection.h
+++ b/gtk2_ardour/selection.h
@@ -101,8 +101,8 @@ class Selection : public sigc::trackable
void set (std::vector<RegionView*>&);
long set (TimeAxisView*, nframes_t, nframes_t);
void set (ARDOUR::AutomationList*);
- void set (ARDOUR::Playlist*);
- void set (const list<ARDOUR::Playlist*>&);
+ void set (boost::shared_ptr<ARDOUR::Playlist>);
+ void set (const list<boost::shared_ptr<ARDOUR::Playlist> >&);
void set (boost::shared_ptr<ARDOUR::Redirect>);
void set (AutomationSelectable*);
@@ -112,8 +112,8 @@ class Selection : public sigc::trackable
void toggle (std::vector<RegionView*>&);
long toggle (nframes_t, nframes_t);
void toggle (ARDOUR::AutomationList*);
- void toggle (ARDOUR::Playlist*);
- void toggle (const list<ARDOUR::Playlist*>&);
+ void toggle (boost::shared_ptr<ARDOUR::Playlist>);
+ void toggle (const list<boost::shared_ptr<ARDOUR::Playlist> >&);
void toggle (boost::shared_ptr<ARDOUR::Redirect>);
void add (TimeAxisView*);
@@ -122,8 +122,8 @@ class Selection : public sigc::trackable
void add (std::vector<RegionView*>&);
long add (nframes_t, nframes_t);
void add (ARDOUR::AutomationList*);
- void add (ARDOUR::Playlist*);
- void add (const list<ARDOUR::Playlist*>&);
+ void add (boost::shared_ptr<ARDOUR::Playlist>);
+ void add (const list<boost::shared_ptr<ARDOUR::Playlist> >&);
void add (boost::shared_ptr<ARDOUR::Redirect>);
void remove (TimeAxisView*);
@@ -132,8 +132,8 @@ class Selection : public sigc::trackable
void remove (uint32_t selection_id);
void remove (nframes_t, nframes_t);
void remove (ARDOUR::AutomationList*);
- void remove (ARDOUR::Playlist*);
- void remove (const list<ARDOUR::Playlist*>&);
+ void remove (boost::shared_ptr<ARDOUR::Playlist>);
+ void remove (const list<boost::shared_ptr<ARDOUR::Playlist> >&);
void remove (boost::shared_ptr<ARDOUR::Redirect>);
void replace (uint32_t time_index, nframes_t start, nframes_t end);
diff --git a/gtk2_ardour/time_axis_view.h b/gtk2_ardour/time_axis_view.h
index 3a652bd0ea..0700954a54 100644
--- a/gtk2_ardour/time_axis_view.h
+++ b/gtk2_ardour/time_axis_view.h
@@ -168,7 +168,7 @@ class TimeAxisView : public virtual AxisView
virtual void step_height (bool bigger);
virtual ARDOUR::RouteGroup* edit_group() const { return 0; }
- virtual ARDOUR::Playlist* playlist() const { return 0; }
+ virtual boost::shared_ptr<ARDOUR::Playlist> playlist() const { return boost::shared_ptr<ARDOUR::Playlist> (); }
virtual void set_samples_per_unit (double);
virtual void show_selection (TimeSelection&);
diff --git a/libs/ardour/ardour/audio_diskstream.h b/libs/ardour/ardour/audio_diskstream.h
index 5c24697972..7c00885228 100644
--- a/libs/ardour/ardour/audio_diskstream.h
+++ b/libs/ardour/ardour/audio_diskstream.h
@@ -90,9 +90,9 @@ class AudioDiskstream : public Diskstream
}
}
- AudioPlaylist* audio_playlist () { return dynamic_cast<AudioPlaylist*>(_playlist); }
+ boost::shared_ptr<AudioPlaylist> audio_playlist () { return boost::dynamic_pointer_cast<AudioPlaylist>(_playlist); }
- int use_playlist (Playlist *);
+ int use_playlist (boost::shared_ptr<Playlist>);
int use_new_playlist ();
int use_copy_playlist ();
diff --git a/libs/ardour/ardour/audioplaylist.h b/libs/ardour/ardour/audioplaylist.h
index 383ec73531..2f1b127c5a 100644
--- a/libs/ardour/ardour/audioplaylist.h
+++ b/libs/ardour/ardour/audioplaylist.h
@@ -42,8 +42,10 @@ class AudioPlaylist : public ARDOUR::Playlist
public:
AudioPlaylist (Session&, const XMLNode&, bool hidden = false);
AudioPlaylist (Session&, string name, bool hidden = false);
- AudioPlaylist (const AudioPlaylist&, string name, bool hidden = false);
- AudioPlaylist (const AudioPlaylist&, nframes_t start, nframes_t cnt, string name, bool hidden = false);
+ AudioPlaylist (boost::shared_ptr<const AudioPlaylist>, string name, bool hidden = false);
+ AudioPlaylist (boost::shared_ptr<const AudioPlaylist>, nframes_t start, nframes_t cnt, string name, bool hidden = false);
+
+ ~AudioPlaylist (); /* public should use unref() */
void clear (bool with_signals=true);
@@ -70,9 +72,6 @@ class AudioPlaylist : public ARDOUR::Playlist
void check_dependents (boost::shared_ptr<Region> region, bool norefresh);
void remove_dependents (boost::shared_ptr<Region> region);
- protected:
- ~AudioPlaylist (); /* public should use unref() */
-
private:
Crossfades _crossfades; /* xfades currently in use */
Crossfades _pending_xfade_adds;
diff --git a/libs/ardour/ardour/audioregion.h b/libs/ardour/ardour/audioregion.h
index 0d45d20c0d..7a88655afe 100644
--- a/libs/ardour/ardour/audioregion.h
+++ b/libs/ardour/ardour/audioregion.h
@@ -137,7 +137,7 @@ class AudioRegion : public Region
void resume_fade_in ();
void resume_fade_out ();
- void set_playlist (Playlist *);
+ void set_playlist (boost::weak_ptr<Playlist>);
private:
friend class RegionFactory;
diff --git a/libs/ardour/ardour/crossfade.h b/libs/ardour/ardour/crossfade.h
index d29ba47056..0422698c5e 100644
--- a/libs/ardour/ardour/crossfade.h
+++ b/libs/ardour/ardour/crossfade.h
@@ -64,12 +64,13 @@ class Crossfade : public PBD::StatefulDestructible
/* copy constructor to copy a crossfade with new regions. used (for example)
- when a playlist copy is made */
+ when a playlist copy is made
+ */
Crossfade (const Crossfade &, boost::shared_ptr<ARDOUR::AudioRegion>, boost::shared_ptr<ARDOUR::AudioRegion>);
/* the usual XML constructor */
- Crossfade (const ARDOUR::Playlist&, XMLNode&);
+ Crossfade (const Playlist&, XMLNode&);
virtual ~Crossfade();
bool operator== (const ARDOUR::Crossfade&);
diff --git a/libs/ardour/ardour/diskstream.h b/libs/ardour/ardour/diskstream.h
index 6e0725033a..3f30cd9f0e 100644
--- a/libs/ardour/ardour/diskstream.h
+++ b/libs/ardour/ardour/diskstream.h
@@ -104,9 +104,9 @@ class IO;
void set_speed (double);
void non_realtime_set_speed ();
- Playlist* playlist () { return _playlist; }
+ boost::shared_ptr<Playlist> playlist () { return _playlist; }
- virtual int use_playlist (Playlist *);
+ virtual int use_playlist (boost::shared_ptr<Playlist>);
virtual int use_new_playlist () = 0;
virtual int use_copy_playlist () = 0;
@@ -206,7 +206,7 @@ class IO;
virtual void playlist_changed (Change);
virtual void playlist_modified ();
- virtual void playlist_deleted (Playlist*);
+ virtual void playlist_deleted (boost::weak_ptr<Playlist>);
virtual void finish_capture (bool rec_monitors_input) = 0;
virtual void transport_stopped (struct tm&, time_t, bool abort) = 0;
@@ -246,7 +246,8 @@ class IO;
ARDOUR::Session& _session;
ARDOUR::IO* _io;
uint32_t _n_channels;
- Playlist* _playlist;
+
+ boost::shared_ptr<Playlist> _playlist;
mutable gint _record_enabled;
double _visible_speed;
@@ -300,7 +301,6 @@ class IO;
sigc::connection ports_created_c;
sigc::connection plmod_connection;
- sigc::connection plstate_connection;
sigc::connection plgone_connection;
unsigned char _flags;
diff --git a/libs/ardour/ardour/named_selection.h b/libs/ardour/ardour/named_selection.h
index 87b71e73ff..fd5777ccf6 100644
--- a/libs/ardour/ardour/named_selection.h
+++ b/libs/ardour/ardour/named_selection.h
@@ -23,6 +23,7 @@
#include <string>
#include <list>
+#include <boost/shared_ptr.hpp>
#include <pbd/stateful.h>
@@ -35,12 +36,12 @@ class Playlist;
struct NamedSelection : public Stateful
{
- NamedSelection (std::string, std::list<Playlist*>&);
+ NamedSelection (std::string, std::list<boost::shared_ptr<Playlist> >&);
NamedSelection (Session&, const XMLNode&);
virtual ~NamedSelection ();
std::string name;
- std::list<Playlist*> playlists;
+ std::list<boost::shared_ptr<Playlist> > playlists;
XMLNode& get_state (void);
diff --git a/libs/ardour/ardour/playlist.h b/libs/ardour/ardour/playlist.h
index 7b9ae718bc..50282f3331 100644
--- a/libs/ardour/ardour/playlist.h
+++ b/libs/ardour/ardour/playlist.h
@@ -26,6 +26,7 @@
#include <map>
#include <list>
#include <boost/shared_ptr.hpp>
+#include <boost/enable_shared_from_this.hpp>
#include <sys/stat.h>
@@ -46,21 +47,25 @@ namespace ARDOUR {
class Session;
class Region;
-class Playlist : public PBD::StatefulDestructible {
+class Playlist : public PBD::StatefulDestructible, public boost::enable_shared_from_this<Playlist> {
public:
typedef list<boost::shared_ptr<Region> > RegionList;
Playlist (Session&, const XMLNode&, bool hidden = false);
Playlist (Session&, string name, bool hidden = false);
- Playlist (const Playlist&, string name, bool hidden = false);
- Playlist (const Playlist&, nframes_t start, nframes_t cnt, string name, bool hidden = false);
+ Playlist (boost::shared_ptr<const Playlist>, string name, bool hidden = false);
+ Playlist (boost::shared_ptr<const Playlist>, nframes_t start, nframes_t cnt, string name, bool hidden = false);
+
+ virtual ~Playlist ();
+
+ void set_region_ownership ();
virtual void clear (bool with_signals=true);
virtual void dump () const;
- void ref();
- void unref();
- uint32_t refcnt() const { return _refcnt; }
+ void use();
+ void release();
+ bool used () const { return _refcnt != 0; }
std::string name() const { return _name; }
void set_name (std::string str);
@@ -89,9 +94,9 @@ class Playlist : public PBD::StatefulDestructible {
void duplicate (boost::shared_ptr<Region>, nframes_t position, float times);
void nudge_after (nframes_t start, nframes_t distance, bool forwards);
- Playlist* cut (list<AudioRange>&, bool result_is_hidden = true);
- Playlist* copy (list<AudioRange>&, bool result_is_hidden = true);
- int paste (Playlist&, nframes_t position, float times);
+ boost::shared_ptr<Playlist> cut (list<AudioRange>&, bool result_is_hidden = true);
+ boost::shared_ptr<Playlist> copy (list<AudioRange>&, bool result_is_hidden = true);
+ int paste (boost::shared_ptr<Playlist>, nframes_t position, float times);
RegionList* regions_at (nframes_t frame);
RegionList* regions_touched (nframes_t start, nframes_t end);
@@ -106,14 +111,11 @@ class Playlist : public PBD::StatefulDestructible {
int set_state (const XMLNode&);
XMLNode& get_template ();
- sigc::signal<void,Playlist*,bool> InUse;
- sigc::signal<void> Modified;
- sigc::signal<void> NameChanged;
- sigc::signal<void> LengthChanged;
- sigc::signal<void> LayeringChanged;
- sigc::signal<void> StatePushed;
-
- static sigc::signal<void,Playlist*> PlaylistCreated;
+ sigc::signal<void,bool> InUse;
+ sigc::signal<void> Modified;
+ sigc::signal<void> NameChanged;
+ sigc::signal<void> LengthChanged;
+ sigc::signal<void> LayeringChanged;
static string bump_name (string old_name, Session&);
static string bump_name_once (string old_name);
@@ -139,7 +141,6 @@ class Playlist : public PBD::StatefulDestructible {
protected:
friend class Session;
- virtual ~Playlist (); /* members of the public use unref() */
protected:
struct RegionLock {
@@ -240,26 +241,23 @@ class Playlist : public PBD::StatefulDestructible {
boost::shared_ptr<Region> region_by_id (PBD::ID);
- void add_region_internal (boost::shared_ptr<Region>, nframes_t position, bool delay_sort = false);
-
- int remove_region_internal (boost::shared_ptr<Region>, bool delay_sort = false);
+ void add_region_internal (boost::shared_ptr<Region>, nframes_t position);
+
+ int remove_region_internal (boost::shared_ptr<Region>);
RegionList *find_regions_at (nframes_t frame);
void copy_regions (RegionList&) const;
void partition_internal (nframes_t start, nframes_t end, bool cutting, RegionList& thawlist);
nframes_t _get_maximum_extent() const;
- Playlist* cut_copy (Playlist* (Playlist::*pmf)(nframes_t, nframes_t, bool),
- list<AudioRange>& ranges, bool result_is_hidden);
- Playlist *cut (nframes_t start, nframes_t cnt, bool result_is_hidden);
- Playlist *copy (nframes_t start, nframes_t cnt, bool result_is_hidden);
+ boost::shared_ptr<Playlist> cut_copy (boost::shared_ptr<Playlist> (Playlist::*pmf)(nframes_t, nframes_t, bool),
+ list<AudioRange>& ranges, bool result_is_hidden);
+ boost::shared_ptr<Playlist> cut (nframes_t start, nframes_t cnt, bool result_is_hidden);
+ boost::shared_ptr<Playlist> copy (nframes_t start, nframes_t cnt, bool result_is_hidden);
int move_region_to_layer (layer_t, boost::shared_ptr<Region> r, int dir);
void relayer ();
-
- static Playlist* copyPlaylist (const Playlist&, nframes_t start, nframes_t length,
- string name, bool result_is_hidden);
void unset_freeze_parent (Playlist*);
void unset_freeze_child (Playlist*);
diff --git a/libs/ardour/ardour/region.h b/libs/ardour/ardour/region.h
index b27fef48a3..f0262777f3 100644
--- a/libs/ardour/ardour/region.h
+++ b/libs/ardour/ardour/region.h
@@ -162,9 +162,8 @@ class Region : public PBD::StatefulDestructible, public boost::enable_shared_fro
virtual uint32_t read_data_count() const { return _read_data_count; }
- ARDOUR::Playlist* playlist() const { return _playlist; }
-
- virtual void set_playlist (ARDOUR::Playlist*);
+ boost::shared_ptr<ARDOUR::Playlist> playlist() const { return _playlist.lock(); }
+ virtual void set_playlist (boost::weak_ptr<ARDOUR::Playlist>);
/* serialization */
@@ -217,7 +216,7 @@ class Region : public PBD::StatefulDestructible, public boost::enable_shared_fro
mutable RegionEditState _first_edit;
int _frozen;
Glib::Mutex lock;
- ARDOUR::Playlist* _playlist;
+ boost::weak_ptr<ARDOUR::Playlist> _playlist;
mutable uint32_t _read_data_count; // modified in read()
Change pending_changed;
uint64_t _last_layer_op; // timestamp
diff --git a/libs/ardour/ardour/session.h b/libs/ardour/ardour/session.h
index 55376bcd77..6ce7f75832 100644
--- a/libs/ardour/ardour/session.h
+++ b/libs/ardour/ardour/session.h
@@ -604,8 +604,7 @@ class Session : public PBD::StatefulDestructible
this playlist.
*/
- sigc::signal<int,ARDOUR::Playlist*> AskAboutPlaylistDeletion;
-
+ sigc::signal<int,boost::shared_ptr<ARDOUR::Playlist> > AskAboutPlaylistDeletion;
/* handlers should return !0 for use pending state, 0 for
ignore it.
@@ -613,24 +612,21 @@ class Session : public PBD::StatefulDestructible
static sigc::signal<int> AskAboutPendingState;
- sigc::signal<void,boost::shared_ptr<Source> > SourceAdded;
- sigc::signal<void,boost::shared_ptr<Source> > SourceRemoved;
-
boost::shared_ptr<AudioFileSource> create_audio_source_for_session (ARDOUR::AudioDiskstream&, uint32_t which_channel, bool destructive);
boost::shared_ptr<Source> source_by_id (const PBD::ID&);
/* playlist management */
- Playlist* playlist_by_name (string name);
- void add_playlist (Playlist *);
- sigc::signal<void,Playlist*> PlaylistAdded;
- sigc::signal<void,Playlist*> PlaylistRemoved;
+ boost::shared_ptr<Playlist> playlist_by_name (string name);
+ void add_playlist (boost::shared_ptr<Playlist>);
+ sigc::signal<void,boost::shared_ptr<Playlist> > PlaylistAdded;
+ sigc::signal<void,boost::shared_ptr<Playlist> > PlaylistRemoved;
uint32_t n_playlists() const;
- template<class T> void foreach_playlist (T *obj, void (T::*func)(Playlist *));
- void get_playlists (std::vector<Playlist*>&);
+ template<class T> void foreach_playlist (T *obj, void (T::*func)(boost::shared_ptr<Playlist>));
+ void get_playlists (std::vector<boost::shared_ptr<Playlist> >&);
/* named selections */
@@ -1464,19 +1460,19 @@ class Session : public PBD::StatefulDestructible
/* PLAYLISTS */
mutable Glib::Mutex playlist_lock;
- typedef set<Playlist *> PlaylistList;
+ typedef set<boost::shared_ptr<Playlist> > PlaylistList;
PlaylistList playlists;
PlaylistList unused_playlists;
int load_playlists (const XMLNode&);
int load_unused_playlists (const XMLNode&);
- void remove_playlist (Playlist *);
- void track_playlist (Playlist *, bool);
+ void remove_playlist (boost::weak_ptr<Playlist>);
+ void track_playlist (bool, boost::weak_ptr<Playlist>);
- Playlist *playlist_factory (string name);
- Playlist *XMLPlaylistFactory (const XMLNode&);
+ boost::shared_ptr<Playlist> playlist_factory (string name);
+ boost::shared_ptr<Playlist> XMLPlaylistFactory (const XMLNode&);
- void playlist_length_changed (Playlist *);
+ void playlist_length_changed ();
void diskstream_playlist_changed (boost::shared_ptr<Diskstream>);
/* NAMED SELECTIONS */
diff --git a/libs/ardour/ardour/session_playlist.h b/libs/ardour/ardour/session_playlist.h
index 6f1b8dbd12..20cf4d8f2e 100644
--- a/libs/ardour/ardour/session_playlist.h
+++ b/libs/ardour/ardour/session_playlist.h
@@ -27,7 +27,7 @@
namespace ARDOUR {
template<class T> void
-Session::foreach_playlist (T *obj, void (T::*func)(Playlist *))
+Session::foreach_playlist (T *obj, void (T::*func)(boost::shared_ptr<Playlist>))
{
Glib::Mutex::Lock lm (playlist_lock);
for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); i++) {
diff --git a/libs/ardour/ardour/source.h b/libs/ardour/ardour/source.h
index 15e814e946..91b856894d 100644
--- a/libs/ardour/ardour/source.h
+++ b/libs/ardour/ardour/source.h
@@ -54,8 +54,8 @@ class Source : public PBD::StatefulDestructible
void use () { _in_use++; }
void disuse () { if (_in_use) { _in_use--; } }
- void add_playlist (ARDOUR::Playlist*);
- void remove_playlist (ARDOUR::Playlist*);
+ void add_playlist (boost::shared_ptr<ARDOUR::Playlist>);
+ void remove_playlist (boost::weak_ptr<ARDOUR::Playlist>);
uint32_t used() const;
@@ -64,7 +64,7 @@ class Source : public PBD::StatefulDestructible
string _name;
time_t _timestamp;
- std::set<ARDOUR::Playlist*> _playlists;
+ std::set<boost::shared_ptr<ARDOUR::Playlist> > _playlists;
private:
uint32_t _in_use;
diff --git a/libs/ardour/ardour/track.h b/libs/ardour/ardour/track.h
index a2b0b9b90e..9c99ecfd25 100644
--- a/libs/ardour/ardour/track.h
+++ b/libs/ardour/ardour/track.h
@@ -120,13 +120,12 @@ class Track : public Route
struct FreezeRecord {
FreezeRecord()
- : playlist(0)
- , have_mementos(false)
+ : have_mementos(false)
{}
~FreezeRecord();
- Playlist* playlist;
+ boost::shared_ptr<Playlist> playlist;
vector<FreezeRecordInsertInfo*> insert_info;
bool have_mementos;
FreezeState state;
diff --git a/libs/ardour/audio_diskstream.cc b/libs/ardour/audio_diskstream.cc
index 5f682789ef..e30c683d8e 100644
--- a/libs/ardour/audio_diskstream.cc
+++ b/libs/ardour/audio_diskstream.cc
@@ -46,6 +46,7 @@
#include <ardour/send.h>
#include <ardour/region_factory.h>
#include <ardour/audioplaylist.h>
+#include <ardour/playlist_factory.h>
#include <ardour/cycle_timer.h>
#include <ardour/audioregion.h>
#include <ardour/source_factory.h>
@@ -286,15 +287,13 @@ AudioDiskstream::get_input_sources ()
int
AudioDiskstream::find_and_use_playlist (const string& name)
{
- Playlist* pl;
- AudioPlaylist* playlist;
+ boost::shared_ptr<AudioPlaylist> playlist;
- if ((pl = _session.playlist_by_name (name)) == 0) {
- playlist = new AudioPlaylist(_session, name);
- pl = playlist;
+ if ((playlist = boost::dynamic_pointer_cast<AudioPlaylist> (_session.playlist_by_name (name))) == 0) {
+ playlist = boost::dynamic_pointer_cast<AudioPlaylist> (PlaylistFactory::create (_session, name));
}
- if ((playlist = dynamic_cast<AudioPlaylist*> (pl)) == 0) {
+ if (!playlist) {
error << string_compose(_("AudioDiskstream: Playlist \"%1\" isn't an audio playlist"), name) << endmsg;
return -1;
}
@@ -303,9 +302,9 @@ AudioDiskstream::find_and_use_playlist (const string& name)
}
int
-AudioDiskstream::use_playlist (Playlist* playlist)
+AudioDiskstream::use_playlist (boost::shared_ptr<Playlist> playlist)
{
- assert(dynamic_cast<AudioPlaylist*>(playlist));
+ assert(boost::dynamic_pointer_cast<AudioPlaylist>(playlist));
Diskstream::use_playlist(playlist);
@@ -316,7 +315,7 @@ int
AudioDiskstream::use_new_playlist ()
{
string newname;
- AudioPlaylist* playlist;
+ boost::shared_ptr<AudioPlaylist> playlist;
if (!in_set_state && destructive()) {
return 0;
@@ -328,9 +327,11 @@ AudioDiskstream::use_new_playlist ()
newname = Playlist::bump_name (_name, _session);
}
- if ((playlist = new AudioPlaylist (_session, newname, hidden())) != 0) {
+ if ((playlist = boost::dynamic_pointer_cast<AudioPlaylist> (PlaylistFactory::create (_session, newname, hidden()))) != 0) {
+
playlist->set_orig_diskstream_id (id());
return use_playlist (playlist);
+
} else {
return -1;
}
@@ -351,11 +352,11 @@ AudioDiskstream::use_copy_playlist ()
}
string newname;
- AudioPlaylist* playlist;
+ boost::shared_ptr<AudioPlaylist> playlist;
newname = Playlist::bump_name (_playlist->name(), _session);
- if ((playlist = new AudioPlaylist (*audio_playlist(), newname)) != 0) {
+ if ((playlist = boost::dynamic_pointer_cast<AudioPlaylist>(PlaylistFactory::create (audio_playlist(), newname))) != 0) {
playlist->set_orig_diskstream_id (id());
return use_playlist (playlist);
} else {
diff --git a/libs/ardour/audio_playlist.cc b/libs/ardour/audio_playlist.cc
index dd0f313fc4..0c35599332 100644
--- a/libs/ardour/audio_playlist.cc
+++ b/libs/ardour/audio_playlist.cc
@@ -45,39 +45,31 @@ AudioPlaylist::AudioPlaylist (Session& session, const XMLNode& node, bool hidden
in_set_state++;
set_state (node);
in_set_state--;
-
- if (!hidden) {
- PlaylistCreated (this); /* EMIT SIGNAL */
- }
}
AudioPlaylist::AudioPlaylist (Session& session, string name, bool hidden)
: Playlist (session, name, hidden)
{
- if (!hidden) {
- PlaylistCreated (this); /* EMIT SIGNAL */
- }
-
}
-AudioPlaylist::AudioPlaylist (const AudioPlaylist& other, string name, bool hidden)
+AudioPlaylist::AudioPlaylist (boost::shared_ptr<const AudioPlaylist> other, string name, bool hidden)
: Playlist (other, name, hidden)
{
- RegionList::const_iterator in_o = other.regions.begin();
+ RegionList::const_iterator in_o = other->regions.begin();
RegionList::iterator in_n = regions.begin();
- while (in_o != other.regions.end()) {
+ while (in_o != other->regions.end()) {
boost::shared_ptr<AudioRegion> ar = boost::dynamic_pointer_cast<AudioRegion>(*in_o);
// We look only for crossfades which begin with the current region, so we don't get doubles
- for (list<Crossfade *>::const_iterator xfades = other._crossfades.begin(); xfades != other._crossfades.end(); ++xfades) {
+ for (list<Crossfade *>::const_iterator xfades = other->_crossfades.begin(); xfades != other->_crossfades.end(); ++xfades) {
if ((*xfades)->in() == ar) {
// We found one! Now copy it!
- RegionList::const_iterator out_o = other.regions.begin();
+ RegionList::const_iterator out_o = other->regions.begin();
RegionList::const_iterator out_n = regions.begin();
- while (out_o != other.regions.end()) {
+ while (out_o != other->regions.end()) {
boost::shared_ptr<AudioRegion>ar2 = boost::dynamic_pointer_cast<AudioRegion>(*out_o);
@@ -99,13 +91,9 @@ AudioPlaylist::AudioPlaylist (const AudioPlaylist& other, string name, bool hidd
in_o++;
in_n++;
}
-
- if (!hidden) {
- PlaylistCreated (this); /* EMIT SIGNAL */
- }
}
-AudioPlaylist::AudioPlaylist (const AudioPlaylist& other, nframes_t start, nframes_t cnt, string name, bool hidden)
+AudioPlaylist::AudioPlaylist (boost::shared_ptr<const AudioPlaylist> other, nframes_t start, nframes_t cnt, string name, bool hidden)
: Playlist (other, start, cnt, name, hidden)
{
/* this constructor does NOT notify others (session) */
@@ -658,7 +646,7 @@ AudioPlaylist::destroy_region (boost::shared_ptr<Region> region)
x = xtmp;
}
- region->set_playlist (0);
+ region->set_playlist (boost::shared_ptr<Playlist>());
}
for (c = _crossfades.begin(); c != _crossfades.end(); ) {
diff --git a/libs/ardour/audio_track.cc b/libs/ardour/audio_track.cc
index b5a18073f4..33bb478a1c 100644
--- a/libs/ardour/audio_track.cc
+++ b/libs/ardour/audio_track.cc
@@ -32,6 +32,7 @@
#include <ardour/route_group_specialized.h>
#include <ardour/insert.h>
#include <ardour/audioplaylist.h>
+#include <ardour/playlist_factory.h>
#include <ardour/panner.h>
#include <ardour/utils.h>
@@ -395,11 +396,11 @@ AudioTrack::set_state_part_two ()
_freeze_record.insert_info.clear ();
if ((prop = fnode->property (X_("playlist"))) != 0) {
- Playlist* pl = _session.playlist_by_name (prop->value());
+ boost::shared_ptr<Playlist> pl = _session.playlist_by_name (prop->value());
if (pl) {
- _freeze_record.playlist = dynamic_cast<AudioPlaylist*> (pl);
+ _freeze_record.playlist = boost::dynamic_pointer_cast<AudioPlaylist> (pl);
} else {
- _freeze_record.playlist = 0;
+ _freeze_record.playlist.reset ();
_freeze_record.state = NoFreeze;
return;
}
@@ -685,8 +686,7 @@ AudioTrack::export_stuff (vector<Sample*>& buffers, uint32_t nbufs, nframes_t st
Glib::RWLock::ReaderLock rlock (redirect_lock);
- // FIXME
- AudioPlaylist* const apl = dynamic_cast<AudioPlaylist*>(diskstream->playlist());
+ boost::shared_ptr<AudioPlaylist> apl = boost::dynamic_pointer_cast<AudioPlaylist>(diskstream->playlist());
assert(apl);
if (apl->read (buffers[0], mix_buffer, gain_buffer, start, nframes) != nframes) {
@@ -791,12 +791,12 @@ AudioTrack::freeze (InterThreadInfo& itt)
{
vector<boost::shared_ptr<AudioSource> > srcs;
string new_playlist_name;
- Playlist* new_playlist;
+ boost::shared_ptr<Playlist> new_playlist;
string dir;
string region_name;
boost::shared_ptr<AudioDiskstream> diskstream = audio_diskstream();
- if ((_freeze_record.playlist = dynamic_cast<AudioPlaylist*>(diskstream->playlist())) == 0) {
+ if ((_freeze_record.playlist = boost::dynamic_pointer_cast<AudioPlaylist>(diskstream->playlist())) == 0) {
return;
}
@@ -853,7 +853,7 @@ AudioTrack::freeze (InterThreadInfo& itt)
}
}
- new_playlist = new AudioPlaylist (_session, new_playlist_name, false);
+ new_playlist = PlaylistFactory::create (_session, new_playlist_name, false);
region_name = new_playlist_name;
/* create a new region from all filesources, keep it private */
@@ -868,7 +868,7 @@ AudioTrack::freeze (InterThreadInfo& itt)
new_playlist->set_frozen (true);
region->set_locked (true);
- diskstream->use_playlist (dynamic_cast<AudioPlaylist*>(new_playlist));
+ diskstream->use_playlist (boost::dynamic_pointer_cast<AudioPlaylist>(new_playlist));
diskstream->set_record_enabled (false);
_freeze_record.state = Frozen;
@@ -900,7 +900,7 @@ AudioTrack::unfreeze ()
}
}
- _freeze_record.playlist = 0;
+ _freeze_record.playlist.reset ();
}
_freeze_record.state = UnFrozen;
diff --git a/libs/ardour/audioregion.cc b/libs/ardour/audioregion.cc
index 1be0f66125..32bd6cd685 100644
--- a/libs/ardour/audioregion.cc
+++ b/libs/ardour/audioregion.cc
@@ -306,9 +306,11 @@ AudioRegion::AudioRegion (SourceList& srcs, const XMLNode& node)
AudioRegion::~AudioRegion ()
{
- if (_playlist) {
+ boost::shared_ptr<Playlist> pl (playlist());
+
+ if (pl) {
for (SourceList::const_iterator i = sources.begin(); i != sources.end(); ++i) {
- (*i)->remove_playlist (_playlist);
+ (*i)->remove_playlist (pl);
}
}
@@ -1159,11 +1161,13 @@ AudioRegion::exportme (Session& session, AudioExportSpecification& spec)
boost::shared_ptr<Region>
AudioRegion::get_parent() const
{
- if (_playlist) {
+ boost::shared_ptr<Playlist> pl (playlist());
+
+ if (pl) {
boost::shared_ptr<AudioRegion> ar;
boost::shared_ptr<AudioRegion const> grrr2 = boost::dynamic_pointer_cast<AudioRegion const> (shared_from_this());
- if (grrr2 && (ar = _playlist->session().find_whole_file_parent (grrr2))) {
+ if (grrr2 && (ar = pl->session().find_whole_file_parent (grrr2))) {
return boost::static_pointer_cast<Region> (ar);
}
}
@@ -1174,12 +1178,14 @@ AudioRegion::get_parent() const
void
AudioRegion::set_scale_amplitude (gain_t g)
{
+ boost::shared_ptr<Playlist> pl (playlist());
+
_scale_amplitude = g;
/* tell the diskstream we're in */
-
- if (_playlist) {
- _playlist->Modified();
+
+ if (pl) {
+ pl->Modified();
}
/* tell everybody else */
@@ -1246,8 +1252,10 @@ AudioRegion::normalize_to (float target_dB)
/* tell the diskstream we're in */
- if (_playlist) {
- _playlist->Modified();
+ boost::shared_ptr<Playlist> pl (playlist());
+
+ if (pl) {
+ pl->Modified();
}
/* tell everybody else */
@@ -1330,31 +1338,32 @@ AudioRegion::source_offset_changed ()
}
void
-AudioRegion::set_playlist (Playlist* pl)
+AudioRegion::set_playlist (boost::weak_ptr<Playlist> wpl)
{
- if (pl == _playlist) {
+ boost::shared_ptr<Playlist> old_playlist = (_playlist.lock());
+ boost::shared_ptr<Playlist> pl (wpl.lock());
+
+ if (old_playlist == pl) {
return;
}
- Playlist* old_playlist = _playlist;
-
- Region::set_playlist (pl);
+ Region::set_playlist (wpl);
if (pl) {
if (old_playlist) {
for (SourceList::const_iterator i = sources.begin(); i != sources.end(); ++i) {
- (*i)->remove_playlist (old_playlist);
- (*i)->add_playlist (_playlist);
+ (*i)->remove_playlist (_playlist);
+ (*i)->add_playlist (pl);
}
} else {
for (SourceList::const_iterator i = sources.begin(); i != sources.end(); ++i) {
- (*i)->add_playlist (_playlist);
+ (*i)->add_playlist (pl);
}
}
} else {
if (old_playlist) {
for (SourceList::const_iterator i = sources.begin(); i != sources.end(); ++i) {
- (*i)->remove_playlist (old_playlist);
+ (*i)->remove_playlist (_playlist);
}
}
}
diff --git a/libs/ardour/auditioner.cc b/libs/ardour/auditioner.cc
index 0c5e8bc6a2..ce6bcd4143 100644
--- a/libs/ardour/auditioner.cc
+++ b/libs/ardour/auditioner.cc
@@ -75,7 +75,7 @@ AudioPlaylist&
Auditioner::prepare_playlist ()
{
// FIXME auditioner is still audio-only
- AudioPlaylist* const apl = dynamic_cast<AudioPlaylist*>(_diskstream->playlist());
+ boost::shared_ptr<AudioPlaylist> apl = boost::dynamic_pointer_cast<AudioPlaylist>(_diskstream->playlist());
assert(apl);
apl->clear ();
diff --git a/libs/ardour/diskstream.cc b/libs/ardour/diskstream.cc
index 7b3db9aab4..62c3fffeb6 100644
--- a/libs/ardour/diskstream.cc
+++ b/libs/ardour/diskstream.cc
@@ -71,14 +71,12 @@ sigc::signal<void> Diskstream::DiskUnderrun;
Diskstream::Diskstream (Session &sess, const string &name, Flag flag)
: _name (name)
, _session (sess)
- , _playlist(NULL)
{
init (flag);
}
Diskstream::Diskstream (Session& sess, const XMLNode& node)
: _session (sess)
- , _playlist(NULL)
{
init (Recordable);
}
@@ -133,7 +131,7 @@ Diskstream::~Diskstream ()
//Glib::Mutex::Lock lm (state_lock);
if (_playlist)
- _playlist->unref ();
+ _playlist->release ();
}
void
@@ -307,7 +305,7 @@ Diskstream::set_speed (double sp)
}
int
-Diskstream::use_playlist (Playlist* playlist)
+Diskstream::use_playlist (boost::shared_ptr<Playlist> playlist)
{
{
Glib::Mutex::Lock lm (state_lock);
@@ -316,23 +314,22 @@ Diskstream::use_playlist (Playlist* playlist)
return 0;
}
- plstate_connection.disconnect();
plmod_connection.disconnect ();
plgone_connection.disconnect ();
if (_playlist) {
- _playlist->unref();
+ _playlist->release();
}
_playlist = playlist;
- _playlist->ref();
+ _playlist->use();
if (!in_set_state && recordable()) {
reset_write_sources (false);
}
plmod_connection = _playlist->Modified.connect (mem_fun (*this, &Diskstream::playlist_modified));
- plgone_connection = _playlist->GoingAway.connect (bind (mem_fun (*this, &Diskstream::playlist_deleted), _playlist));
+ plgone_connection = _playlist->GoingAway.connect (bind (mem_fun (*this, &Diskstream::playlist_deleted), boost::weak_ptr<Playlist>(_playlist)));
}
if (!overwrite_queued) {
@@ -362,14 +359,21 @@ Diskstream::playlist_modified ()
}
void
-Diskstream::playlist_deleted (Playlist* pl)
+Diskstream::playlist_deleted (boost::weak_ptr<Playlist> wpl)
{
- /* this catches an ordering issue with session destruction. playlists
- are destroyed before diskstreams. we have to invalidate any handles
- we have to the playlist.
- */
+ boost::shared_ptr<Playlist> pl (wpl.lock());
- _playlist = 0;
+ if (pl == _playlist) {
+
+ /* this catches an ordering issue with session destruction. playlists
+ are destroyed before diskstreams. we have to invalidate any handles
+ we have to the playlist.
+ */
+
+ if (_playlist) {
+ _playlist.reset ();
+ }
+ }
}
int
diff --git a/libs/ardour/import.cc b/libs/ardour/import.cc
index 2d409e11f7..0d0a73c7a0 100644
--- a/libs/ardour/import.cc
+++ b/libs/ardour/import.cc
@@ -111,14 +111,14 @@ Session::import_audiofile (import_status& status)
do {
if (info.channels == 2) {
if (n == 0) {
- snprintf (buf, sizeof(buf), "%s%s-L.wav", sounds_dir.c_str(), basepath.c_str());
+ snprintf (buf, sizeof(buf), "%s/%s-L.wav", sounds_dir.c_str(), basepath.c_str());
} else {
- snprintf (buf, sizeof(buf), "%s%s-R.wav", sounds_dir.c_str(), basepath.c_str());
+ snprintf (buf, sizeof(buf), "%s/%s-R.wav", sounds_dir.c_str(), basepath.c_str());
}
} else if (info.channels > 1) {
- snprintf (buf, sizeof(buf), "%s%s-c%lu.wav", sounds_dir.c_str(), basepath.c_str(), n+1);
+ snprintf (buf, sizeof(buf), "%s/%s-c%lu.wav", sounds_dir.c_str(), basepath.c_str(), n+1);
} else {
- snprintf (buf, sizeof(buf), "%s%s.wav", sounds_dir.c_str(), basepath.c_str());
+ snprintf (buf, sizeof(buf), "%s/%s.wav", sounds_dir.c_str(), basepath.c_str());
}
if (::access (buf, F_OK) == 0) {
diff --git a/libs/ardour/named_selection.cc b/libs/ardour/named_selection.cc
index 605d7cae13..ecce09692f 100644
--- a/libs/ardour/named_selection.cc
+++ b/libs/ardour/named_selection.cc
@@ -33,12 +33,14 @@ using namespace PBD;
sigc::signal<void,NamedSelection*> NamedSelection::NamedSelectionCreated;
-NamedSelection::NamedSelection (string n, list<Playlist*>& l)
+typedef std::list<boost::shared_ptr<Playlist> > PlaylistList;
+
+NamedSelection::NamedSelection (string n, PlaylistList& l)
: name (n)
{
playlists = l;
- for (list<Playlist*>::iterator i = playlists.begin(); i != playlists.end(); ++i) {
- (*i)->ref();
+ for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
+ (*i)->use();
}
NamedSelectionCreated (this);
}
@@ -65,13 +67,13 @@ NamedSelection::NamedSelection (Session& session, const XMLNode& node)
const XMLNode* plnode;
string playlist_name;
- Playlist* playlist;
+ boost::shared_ptr<Playlist> playlist;
plnode = *niter;
if ((property = plnode->property ("name")) != 0) {
if ((playlist = session.playlist_by_name (property->value())) != 0) {
- playlist->ref();
+ playlist->use();
playlists.push_back (playlist);
} else {
warning << string_compose (_("Chunk %1 uses an unknown playlist \"%2\""), name, property->value()) << endmsg;
@@ -87,8 +89,8 @@ NamedSelection::NamedSelection (Session& session, const XMLNode& node)
NamedSelection::~NamedSelection ()
{
- for (list<Playlist*>::iterator i = playlists.begin(); i != playlists.end(); ++i) {
- (*i)->unref();
+ for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
+ (*i)->release();
}
}
@@ -107,7 +109,7 @@ NamedSelection::get_state ()
root->add_property ("name", name);
child = root->add_child ("Playlists");
- for (list<Playlist*>::iterator i = playlists.begin(); i != playlists.end(); ++i) {
+ for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
XMLNode* plnode = new XMLNode ("Playlist");
plnode->add_property ("name", (*i)->name());
diff --git a/libs/ardour/playlist.cc b/libs/ardour/playlist.cc
index 77aee9392d..8c1c608e1b 100644
--- a/libs/ardour/playlist.cc
+++ b/libs/ardour/playlist.cc
@@ -36,6 +36,7 @@
#include <ardour/session.h>
#include <ardour/region.h>
#include <ardour/region_factory.h>
+#include <ardour/playlist_factory.h>
#include "i18n.h"
@@ -43,14 +44,12 @@ using namespace std;
using namespace ARDOUR;
using namespace PBD;
-sigc::signal<void,Playlist*> Playlist::PlaylistCreated;
-
struct ShowMeTheList {
- ShowMeTheList (Playlist *pl, const string& n) : playlist (pl), name (n) {}
+ ShowMeTheList (boost::shared_ptr<Playlist> pl, const string& n) : playlist (pl), name (n) {}
~ShowMeTheList () {
cerr << ">>>>" << name << endl; playlist->dump(); cerr << "<<<<" << name << endl << endl;
};
- Playlist *playlist;
+ boost::shared_ptr<Playlist> playlist;
string name;
};
@@ -86,43 +85,42 @@ Playlist::Playlist (Session& sess, const XMLNode& node, bool hide)
init (hide);
_name = "unnamed"; /* reset by set_state */
- /* derived class calls set_state() */
+ /* set state called by derived class */
}
-Playlist::Playlist (const Playlist& other, string namestr, bool hide)
- : _name (namestr), _session (other._session), _orig_diskstream_id(other._orig_diskstream_id)
+Playlist::Playlist (boost::shared_ptr<const Playlist> other, string namestr, bool hide)
+ : _name (namestr), _session (other->_session), _orig_diskstream_id(other->_orig_diskstream_id)
{
init (hide);
RegionList tmp;
- other.copy_regions (tmp);
+ other->copy_regions (tmp);
in_set_state++;
for (list<boost::shared_ptr<Region> >::iterator x = tmp.begin(); x != tmp.end(); ++x) {
- add_region_internal( (*x), (*x)->position() );
+ add_region_internal( (*x), (*x)->position());
}
in_set_state--;
- _splicing = other._splicing;
- _nudging = other._nudging;
- _edit_mode = other._edit_mode;
+ _splicing = other->_splicing;
+ _nudging = other->_nudging;
+ _edit_mode = other->_edit_mode;
in_set_state = 0;
in_flush = false;
in_partition = false;
subcnt = 0;
_read_data_count = 0;
- _frozen = other._frozen;
-
- layer_op_counter = other.layer_op_counter;
- freeze_length = other.freeze_length;
+ _frozen = other->_frozen;
+ layer_op_counter = other->layer_op_counter;
+ freeze_length = other->freeze_length;
}
-Playlist::Playlist (const Playlist& other, nframes_t start, nframes_t cnt, string str, bool hide)
- : _name (str), _session (other._session), _orig_diskstream_id(other._orig_diskstream_id)
+Playlist::Playlist (boost::shared_ptr<const Playlist> other, nframes_t start, nframes_t cnt, string str, bool hide)
+ : _name (str), _session (other->_session), _orig_diskstream_id(other->_orig_diskstream_id)
{
RegionLock rlock2 (&((Playlist&)other));
@@ -130,7 +128,7 @@ Playlist::Playlist (const Playlist& other, nframes_t start, nframes_t cnt, strin
init (hide);
- for (RegionList::const_iterator i = other.regions.begin(); i != other.regions.end(); i++) {
+ for (RegionList::const_iterator i = other->regions.begin(); i != other->regions.end(); i++) {
boost::shared_ptr<Region> region;
boost::shared_ptr<Region> new_region;
@@ -177,32 +175,28 @@ Playlist::Playlist (const Playlist& other, nframes_t start, nframes_t cnt, strin
new_region = RegionFactory::RegionFactory::create (region, offset, len, new_name, region->layer(), region->flags());
- add_region_internal (new_region, position, true);
+ add_region_internal (new_region, position);
}
/* this constructor does NOT notify others (session) */
}
void
-Playlist::ref ()
+Playlist::use ()
{
++_refcnt;
- InUse (this, true); /* EMIT SIGNAL */
+ InUse (true); /* EMIT SIGNAL */
}
void
-Playlist::unref ()
+Playlist::release ()
{
if (_refcnt > 0) {
_refcnt--;
}
+
if (_refcnt == 0) {
- InUse (this, false); /* EMIT SIGNAL */
-
- if (_hidden) {
- /* nobody knows we exist */
- delete this;
- }
+ InUse (false); /* EMIT SIGNAL */
}
}
@@ -259,7 +253,7 @@ Playlist::~Playlist ()
RegionLock rl (this);
for (set<boost::shared_ptr<Region> >::iterator i = all_regions.begin(); i != all_regions.end(); ++i) {
- (*i)->set_playlist (0);
+ (*i)->set_playlist (boost::shared_ptr<Playlist>());
}
}
@@ -460,7 +454,7 @@ Playlist::add_region (boost::shared_ptr<Region> region, nframes_t position, floa
nframes_t pos = position;
if (itimes >= 1) {
- add_region_internal (region, pos, true);
+ add_region_internal (region, pos);
pos += region->length();
--itimes;
}
@@ -477,7 +471,7 @@ Playlist::add_region (boost::shared_ptr<Region> region, nframes_t position, floa
for (int i = 0; i < itimes; ++i) {
boost::shared_ptr<Region> copy = RegionFactory::create (region);
- add_region_internal (copy, pos, true);
+ add_region_internal (copy, pos);
pos += region->length();
}
@@ -486,12 +480,24 @@ Playlist::add_region (boost::shared_ptr<Region> region, nframes_t position, floa
string name;
_session.region_name (name, region->name(), false);
boost::shared_ptr<Region> sub = RegionFactory::create (region, 0, length, name, region->layer(), region->flags());
- add_region_internal (sub, pos, true);
+ add_region_internal (sub, pos);
+ }
+}
+
+void
+Playlist::set_region_ownership ()
+{
+ RegionLock rl (this);
+ RegionList::iterator i;
+ boost::weak_ptr<Playlist> pl (shared_from_this());
+
+ for (i = regions.begin(); i != regions.end(); ++i) {
+ (*i)->set_playlist (pl);
}
}
void
-Playlist::add_region_internal (boost::shared_ptr<Region> region, nframes_t position, bool delay_sort)
+Playlist::add_region_internal (boost::shared_ptr<Region> region, nframes_t position)
{
RegionSortByPosition cmp;
nframes_t old_length = 0;
@@ -500,7 +506,11 @@ Playlist::add_region_internal (boost::shared_ptr<Region> region, nframes_t posit
old_length = _get_maximum_extent();
}
- region->set_playlist (this);
+ if (!in_set_state) {
+ boost::shared_ptr<Playlist> foo (shared_from_this());
+ region->set_playlist (boost::weak_ptr<Playlist>(foo));
+ }
+
region->set_position (position, this);
timestamp_layer_op (region);
@@ -553,7 +563,7 @@ Playlist::remove_region (boost::shared_ptr<Region> region)
}
int
-Playlist::remove_region_internal (boost::shared_ptr<Region>region, bool delay_sort)
+Playlist::remove_region_internal (boost::shared_ptr<Region>region)
{
RegionList::iterator i;
nframes_t old_length = 0;
@@ -687,7 +697,7 @@ Playlist::partition_internal (nframes_t start, nframes_t end, bool cutting, Regi
_session.region_name (new_name, current->name(), false);
region = RegionFactory::create (current, pos2 - pos1, pos3 - pos2, new_name,
regions.size(), Region::Flag(current->flags()|Region::Automatic|Region::LeftOfSplit|Region::RightOfSplit));
- add_region_internal (region, start, true);
+ add_region_internal (region, start);
new_regions.push_back (region);
}
@@ -697,7 +707,7 @@ Playlist::partition_internal (nframes_t start, nframes_t end, bool cutting, Regi
region = RegionFactory::create (current, pos3 - pos1, pos4 - pos3, new_name,
regions.size(), Region::Flag(current->flags()|Region::Automatic|Region::RightOfSplit));
- add_region_internal (region, end, true);
+ add_region_internal (region, end);
new_regions.push_back (region);
/* "front" ***** */
@@ -726,7 +736,7 @@ Playlist::partition_internal (nframes_t start, nframes_t end, bool cutting, Regi
_session.region_name (new_name, current->name(), false);
region = RegionFactory::create (current, pos2 - pos1, pos4 - pos2, new_name, (layer_t) regions.size(),
Region::Flag(current->flags()|Region::Automatic|Region::LeftOfSplit));
- add_region_internal (region, start, true);
+ add_region_internal (region, start);
new_regions.push_back (region);
}
@@ -760,7 +770,7 @@ Playlist::partition_internal (nframes_t start, nframes_t end, bool cutting, Regi
_session.region_name (new_name, current->name(), false);
region = RegionFactory::create (current, 0, pos3 - pos1, new_name,
regions.size(), Region::Flag(current->flags()|Region::Automatic|Region::RightOfSplit));
- add_region_internal (region, pos1, true);
+ add_region_internal (region, pos1);
new_regions.push_back (region);
}
@@ -802,20 +812,19 @@ Playlist::partition_internal (nframes_t start, nframes_t end, bool cutting, Regi
}
}
-Playlist*
-Playlist::cut_copy (Playlist* (Playlist::*pmf)(nframes_t, nframes_t,bool), list<AudioRange>& ranges, bool result_is_hidden)
+boost::shared_ptr<Playlist>
+Playlist::cut_copy (boost::shared_ptr<Playlist> (Playlist::*pmf)(nframes_t, nframes_t,bool), list<AudioRange>& ranges, bool result_is_hidden)
{
- Playlist* ret;
- Playlist* pl;
+ boost::shared_ptr<Playlist> ret;
+ boost::shared_ptr<Playlist> pl;
nframes_t start;
if (ranges.empty()) {
- return 0;
+ return boost::shared_ptr<Playlist>();
}
start = ranges.front().start;
-
for (list<AudioRange>::iterator i = ranges.begin(); i != ranges.end(); ++i) {
pl = (this->*pmf)((*i).start, (*i).length(), result_is_hidden);
@@ -829,39 +838,31 @@ Playlist::cut_copy (Playlist* (Playlist::*pmf)(nframes_t, nframes_t,bool), list<
chopped.
*/
- ret->paste (*pl, (*i).start - start, 1.0f);
- delete pl;
+ ret->paste (pl, (*i).start - start, 1.0f);
}
}
- if (ret) {
- /* manually notify session of new playlist here
- because the playlists were constructed without notifying
- */
- PlaylistCreated (ret);
- }
-
return ret;
}
-Playlist*
+boost::shared_ptr<Playlist>
Playlist::cut (list<AudioRange>& ranges, bool result_is_hidden)
{
- Playlist* (Playlist::*pmf)(nframes_t,nframes_t,bool) = &Playlist::cut;
+ boost::shared_ptr<Playlist> (Playlist::*pmf)(nframes_t,nframes_t,bool) = &Playlist::cut;
return cut_copy (pmf, ranges, result_is_hidden);
}
-Playlist*
+boost::shared_ptr<Playlist>
Playlist::copy (list<AudioRange>& ranges, bool result_is_hidden)
{
- Playlist* (Playlist::*pmf)(nframes_t,nframes_t,bool) = &Playlist::copy;
+ boost::shared_ptr<Playlist> (Playlist::*pmf)(nframes_t,nframes_t,bool) = &Playlist::copy;
return cut_copy (pmf, ranges, result_is_hidden);
}
-Playlist *
+boost::shared_ptr<Playlist>
Playlist::cut (nframes_t start, nframes_t cnt, bool result_is_hidden)
{
- Playlist *the_copy;
+ boost::shared_ptr<Playlist> the_copy;
RegionList thawlist;
char buf[32];
@@ -870,8 +871,8 @@ Playlist::cut (nframes_t start, nframes_t cnt, bool result_is_hidden)
new_name += '.';
new_name += buf;
- if ((the_copy = copyPlaylist (*this, start, cnt, new_name, result_is_hidden)) == 0) {
- return 0;
+ if ((the_copy = PlaylistFactory::create (shared_from_this(), start, cnt, new_name, result_is_hidden)) == 0) {
+ return boost::shared_ptr<Playlist>();
}
partition_internal (start, start+cnt-1, true, thawlist);
@@ -884,7 +885,7 @@ Playlist::cut (nframes_t start, nframes_t cnt, bool result_is_hidden)
return the_copy;
}
-Playlist *
+boost::shared_ptr<Playlist>
Playlist::copy (nframes_t start, nframes_t cnt, bool result_is_hidden)
{
char buf[32];
@@ -895,28 +896,28 @@ Playlist::copy (nframes_t start, nframes_t cnt, bool result_is_hidden)
new_name += buf;
cnt = min (_get_maximum_extent() - start, cnt);
- return copyPlaylist (*this, start, cnt, new_name, result_is_hidden);
+ return PlaylistFactory::create (shared_from_this(), start, cnt, new_name, result_is_hidden);
}
int
-Playlist::paste (Playlist& other, nframes_t position, float times)
+Playlist::paste (boost::shared_ptr<Playlist> other, nframes_t position, float times)
{
times = fabs (times);
nframes_t old_length;
{
RegionLock rl1 (this);
- RegionLock rl2 (&other);
+ RegionLock rl2 (other.get());
old_length = _get_maximum_extent();
int itimes = (int) floor (times);
nframes_t pos = position;
- nframes_t shift = other._get_maximum_extent();
+ nframes_t shift = other->_get_maximum_extent();
layer_t top_layer = regions.size();
while (itimes--) {
- for (RegionList::iterator i = other.regions.begin(); i != other.regions.end(); ++i) {
+ for (RegionList::iterator i = other->regions.begin(); i != other->regions.end(); ++i) {
boost::shared_ptr<Region> copy_of_region = RegionFactory::create (*i);
/* put these new regions on top of all existing ones, but preserve
@@ -955,7 +956,7 @@ Playlist::duplicate (boost::shared_ptr<Region> region, nframes_t position, float
while (itimes--) {
boost::shared_ptr<Region> copy = RegionFactory::create (region);
- add_region_internal (copy, pos, true);
+ add_region_internal (copy, pos);
pos += region->length();
}
@@ -964,7 +965,7 @@ Playlist::duplicate (boost::shared_ptr<Region> region, nframes_t position, float
string name;
_session.region_name (name, region->name(), false);
boost::shared_ptr<Region> sub = RegionFactory::create (region, 0, length, name, region->layer(), region->flags());
- add_region_internal (sub, pos, true);
+ add_region_internal (sub, pos);
}
}
@@ -999,7 +1000,7 @@ Playlist::split_region (boost::shared_ptr<Region> region, nframes_t playlist_pos
_session.region_name (after_name, region->name(), false);
right = RegionFactory::create (region, before, after, after_name, region->layer(), Region::Flag (region->flags()|Region::RightOfSplit));
- add_region_internal (left, region->position(), true);
+ add_region_internal (left, region->position());
add_region_internal (right, region->position() + before);
uint64_t orig_layer_op = region->last_layer_op();
@@ -1016,7 +1017,7 @@ Playlist::split_region (boost::shared_ptr<Region> region, nframes_t playlist_pos
finalize_split_region (region, left, right);
- if (remove_region_internal (region, true)) {
+ if (remove_region_internal (region)) {
return;
}
}
diff --git a/libs/ardour/playlist_factory.cc b/libs/ardour/playlist_factory.cc
index 4461783874..f5f19d5b5b 100644
--- a/libs/ardour/playlist_factory.cc
+++ b/libs/ardour/playlist_factory.cc
@@ -22,24 +22,75 @@
#include <ardour/playlist.h>
#include <ardour/audioplaylist.h>
+#include <ardour/playlist_factory.h>
#include "i18n.h"
using namespace ARDOUR;
using namespace PBD;
-Playlist*
-Playlist::copyPlaylist (const Playlist& playlist, nframes_t start, nframes_t length,
- string name, bool result_is_hidden)
+sigc::signal<void,boost::shared_ptr<Playlist> > PlaylistFactory::PlaylistCreated;
+
+boost::shared_ptr<Playlist>
+PlaylistFactory::create (Session& s, const XMLNode& node, bool hidden)
+{
+ boost::shared_ptr<Playlist> pl;
+
+ pl = boost::shared_ptr<Playlist> (new AudioPlaylist (s, node, hidden));
+
+ pl->set_region_ownership ();
+
+ if (!hidden) {
+ PlaylistCreated (pl);
+ }
+ return pl;
+}
+
+boost::shared_ptr<Playlist>
+PlaylistFactory::create (Session& s, string name, bool hidden)
+{
+ boost::shared_ptr<Playlist> pl;
+
+ pl = boost::shared_ptr<Playlist> (new AudioPlaylist (s, name, hidden));
+
+ if (!hidden) {
+ PlaylistCreated (pl);
+ }
+
+ return pl;
+}
+
+boost::shared_ptr<Playlist>
+PlaylistFactory::create (boost::shared_ptr<const Playlist> old, string name, bool hidden)
{
- const AudioPlaylist* apl;
-
- if ((apl = dynamic_cast<const AudioPlaylist*> (&playlist)) != 0) {
- return new AudioPlaylist (*apl, start, length, name, result_is_hidden);
- } else {
- fatal << _("programming error: Playlist::copyPlaylist called with unknown Playlist type")
- << endmsg;
- /*NOTREACHED*/
- return 0;
+ boost::shared_ptr<Playlist> pl;
+ boost::shared_ptr<const AudioPlaylist> apl;
+
+ if ((apl = boost::dynamic_pointer_cast<const AudioPlaylist> (old)) != 0) {
+ pl = boost::shared_ptr<Playlist> (new AudioPlaylist (apl, name, hidden));
+ pl->set_region_ownership ();
}
+
+ if (!hidden) {
+ PlaylistCreated (pl);
+ }
+
+ return pl;
+}
+
+boost::shared_ptr<Playlist>
+PlaylistFactory::create (boost::shared_ptr<const Playlist> old, nframes_t start, nframes_t cnt, string name, bool hidden)
+{
+ boost::shared_ptr<Playlist> pl;
+ boost::shared_ptr<const AudioPlaylist> apl;
+
+ if ((apl = boost::dynamic_pointer_cast<const AudioPlaylist> (old)) != 0) {
+ pl = boost::shared_ptr<Playlist> (new AudioPlaylist (apl, start, cnt, name, hidden));
+ pl->set_region_ownership ();
+ }
+
+
+ /* this factory method does NOT notify others */
+
+ return pl;
}
diff --git a/libs/ardour/region.cc b/libs/ardour/region.cc
index 5aeecca0e2..9d81cc5907 100644
--- a/libs/ardour/region.cc
+++ b/libs/ardour/region.cc
@@ -54,7 +54,6 @@ Region::Region (nframes_t start, nframes_t length, const string& name, layer_t l
/* basic Region constructor */
_flags = flags;
- _playlist = 0;
_read_data_count = 0;
_frozen = 0;
pending_changed = Change (0);
@@ -76,7 +75,6 @@ Region::Region (boost::shared_ptr<const Region> other, nframes_t offset, nframes
_frozen = 0;
pending_changed = Change (0);
- _playlist = 0;
_read_data_count = 0;
_start = other->_start + offset;
@@ -100,7 +98,6 @@ Region::Region (boost::shared_ptr<const Region> other)
_frozen = 0;
pending_changed = Change (0);
- _playlist = 0;
_read_data_count = 0;
_first_edit = EditChangesID;
@@ -126,7 +123,6 @@ Region::Region (const XMLNode& node)
{
_frozen = 0;
pending_changed = Change (0);
- _playlist = 0;
_read_data_count = 0;
_start = 0;
_sync_position = _start;
@@ -148,7 +144,7 @@ Region::~Region ()
}
void
-Region::set_playlist (Playlist* pl)
+Region::set_playlist (boost::weak_ptr<Playlist> pl)
{
_playlist = pl;
}
@@ -206,9 +202,11 @@ Region::maybe_uncopy ()
void
Region::first_edit ()
{
- if (_first_edit != EditChangesNothing && _playlist) {
+ boost::shared_ptr<Playlist> pl (playlist());
- _name = _playlist->session().new_region_name (_name);
+ if (_first_edit != EditChangesNothing && pl) {
+
+ _name = pl->session().new_region_name (_name);
_first_edit = EditChangesNothing;
send_change (NameChanged);
@@ -219,7 +217,9 @@ Region::first_edit ()
bool
Region::at_natural_position () const
{
- if (!_playlist) {
+ boost::shared_ptr<Playlist> pl (playlist());
+
+ if (!pl) {
return false;
}
@@ -237,7 +237,9 @@ Region::at_natural_position () const
void
Region::move_to_natural_position (void *src)
{
- if (!_playlist) {
+ boost::shared_ptr<Playlist> pl (playlist());
+
+ if (!pl) {
return;
}
@@ -297,7 +299,11 @@ Region::set_position_on_top (nframes_t pos, void *src)
_position = pos;
}
- _playlist->raise_region_to_top (shared_from_this ());
+ boost::shared_ptr<Playlist> pl (playlist());
+
+ if (pl) {
+ pl->raise_region_to_top (shared_from_this ());
+ }
/* do this even if the position is the same. this helps out
a GUI that has moved its representation already.
@@ -684,42 +690,37 @@ Region::sync_position() const
void
Region::raise ()
{
- if (_playlist == 0) {
- return;
+ boost::shared_ptr<Playlist> pl (playlist());
+ if (pl) {
+ pl->raise_region (shared_from_this ());
}
-
- _playlist->raise_region (shared_from_this ());
}
void
Region::lower ()
{
- if (_playlist == 0) {
- return;
+ boost::shared_ptr<Playlist> pl (playlist());
+ if (pl) {
+ pl->lower_region (shared_from_this ());
}
-
- _playlist->lower_region (shared_from_this ());
}
void
Region::raise_to_top ()
{
-
- if (_playlist == 0) {
- return;
+ boost::shared_ptr<Playlist> pl (playlist());
+ if (pl) {
+ pl->raise_region_to_top (shared_from_this());
}
-
- _playlist->raise_region_to_top (shared_from_this());
}
void
Region::lower_to_bottom ()
{
- if (_playlist == 0) {
- return;
+ boost::shared_ptr<Playlist> pl (playlist());
+ if (pl) {
+ pl->lower_region_to_bottom (shared_from_this());
}
-
- _playlist->lower_region_to_bottom (shared_from_this());
}
void
diff --git a/libs/ardour/session.cc b/libs/ardour/session.cc
index 14c5bde996..caea881383 100644
--- a/libs/ardour/session.cc
+++ b/libs/ardour/session.cc
@@ -468,10 +468,24 @@ Session::~Session ()
tmp = i;
++tmp;
- delete *i;
+ (*i)->drop_references ();
+
+ i = tmp;
+ }
+
+ for (PlaylistList::iterator i = unused_playlists.begin(); i != unused_playlists.end(); ) {
+ PlaylistList::iterator tmp;
+
+ tmp = i;
+ ++tmp;
+
+ (*i)->drop_references ();
i = tmp;
}
+
+ playlists.clear ();
+ unused_playlists.clear ();
#ifdef TRACK_DESTRUCTION
cerr << "delete audio regions\n";
@@ -918,7 +932,7 @@ Session::hookup_io ()
}
void
-Session::playlist_length_changed (Playlist* pl)
+Session::playlist_length_changed ()
{
/* we can't just increase end_location->end() if pl->get_maximum_extent()
if larger. if the playlist used to be the longest playlist,
@@ -932,10 +946,10 @@ Session::playlist_length_changed (Playlist* pl)
void
Session::diskstream_playlist_changed (boost::shared_ptr<Diskstream> dstream)
{
- Playlist *playlist;
+ boost::shared_ptr<Playlist> playlist;
if ((playlist = dstream->playlist()) != 0) {
- playlist->LengthChanged.connect (sigc::bind (mem_fun (this, &Session::playlist_length_changed), playlist));
+ playlist->LengthChanged.connect (mem_fun (this, &Session::playlist_length_changed));
}
/* see comment in playlist_length_changed () */
@@ -2268,7 +2282,7 @@ Session::get_maximum_extent () const
boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
for (DiskstreamList::const_iterator i = dsl->begin(); i != dsl->end(); ++i) {
- Playlist* pl = (*i)->playlist();
+ boost::shared_ptr<Playlist> pl = (*i)->playlist();
if ((me = pl->get_maximum_extent()) > max) {
max = me;
}
@@ -2671,17 +2685,11 @@ Session::add_source (boost::shared_ptr<Source> source)
result = audio_sources.insert (entry);
}
- if (!result.second) {
- cerr << "\tNOT inserted ? " << result.second << endl;
+ if (result.second) {
+ source->GoingAway.connect (sigc::bind (mem_fun (this, &Session::remove_source), boost::weak_ptr<Source> (source)));
+ set_dirty();
}
-
- source->GoingAway.connect (sigc::bind (mem_fun (this, &Session::remove_source), boost::weak_ptr<Source> (source)));
- set_dirty();
-
- SourceAdded (source); /* EMIT SIGNAL */
- } else {
- cerr << "\tNOT AUDIO FILE\n";
- }
+ }
}
void
@@ -2710,8 +2718,6 @@ Session::remove_source (boost::weak_ptr<Source> src)
save_state (_current_snapshot_name);
}
-
- SourceRemoved(source); /* EMIT SIGNAL */
}
boost::shared_ptr<Source>
@@ -2897,6 +2903,7 @@ Session::audio_path_from_name (string name, uint32_t nchan, uint32_t chan, bool
} else {
snprintf (buf, sizeof(buf), "%s/T%04d-%s.wav", spath.c_str(), cnt, legalized.c_str());
}
+
} else {
spath += '/';
@@ -2940,6 +2947,7 @@ Session::audio_path_from_name (string name, uint32_t nchan, uint32_t chan, bool
string foo = buf;
spath = discover_best_sound_dir ();
+ spath += '/';
string::size_type pos = foo.find_last_of ('/');
@@ -2961,7 +2969,7 @@ Session::create_audio_source_for_session (AudioDiskstream& ds, uint32_t chan, bo
/* Playlist management */
-Playlist *
+boost::shared_ptr<Playlist>
Session::playlist_by_name (string name)
{
Glib::Mutex::Lock lm (playlist_lock);
@@ -2975,11 +2983,12 @@ Session::playlist_by_name (string name)
return* i;
}
}
- return 0;
+
+ return boost::shared_ptr<Playlist>();
}
void
-Session::add_playlist (Playlist* playlist)
+Session::add_playlist (boost::shared_ptr<Playlist> playlist)
{
if (playlist->hidden()) {
return;
@@ -2989,9 +2998,8 @@ Session::add_playlist (Playlist* playlist)
Glib::Mutex::Lock lm (playlist_lock);
if (find (playlists.begin(), playlists.end(), playlist) == playlists.end()) {
playlists.insert (playlists.begin(), playlist);
- // playlist->ref();
- playlist->InUse.connect (mem_fun (*this, &Session::track_playlist));
- playlist->GoingAway.connect (sigc::bind (mem_fun (*this, &Session::remove_playlist), playlist));
+ playlist->InUse.connect (sigc::bind (mem_fun (*this, &Session::track_playlist), boost::weak_ptr<Playlist>(playlist)));
+ playlist->GoingAway.connect (sigc::bind (mem_fun (*this, &Session::remove_playlist), boost::weak_ptr<Playlist>(playlist)));
}
}
@@ -3001,7 +3009,7 @@ Session::add_playlist (Playlist* playlist)
}
void
-Session::get_playlists (vector<Playlist*>& s)
+Session::get_playlists (vector<boost::shared_ptr<Playlist> >& s)
{
{
Glib::Mutex::Lock lm (playlist_lock);
@@ -3015,15 +3023,25 @@ Session::get_playlists (vector<Playlist*>& s)
}
void
-Session::track_playlist (Playlist* pl, bool inuse)
+Session::track_playlist (bool inuse, boost::weak_ptr<Playlist> wpl)
{
+ boost::shared_ptr<Playlist> pl(wpl.lock());
+
+ if (!pl) {
+ return;
+ }
+
PlaylistList::iterator x;
+ if (pl->hidden()) {
+ /* its not supposed to be visible */
+ return;
+ }
+
{
Glib::Mutex::Lock lm (playlist_lock);
if (!inuse) {
- //cerr << "shifting playlist to unused: " << pl->name() << endl;
unused_playlists.insert (pl);
@@ -3033,8 +3051,7 @@ Session::track_playlist (Playlist* pl, bool inuse)
} else {
- //cerr << "shifting playlist to used: " << pl->name() << endl;
-
+
playlists.insert (pl);
if ((x = unused_playlists.find (pl)) != unused_playlists.end()) {
@@ -3045,26 +3062,33 @@ Session::track_playlist (Playlist* pl, bool inuse)
}
void
-Session::remove_playlist (Playlist* playlist)
+Session::remove_playlist (boost::weak_ptr<Playlist> weak_playlist)
{
if (_state_of_the_state & Deletion) {
return;
}
+ boost::shared_ptr<Playlist> playlist (weak_playlist.lock());
+
+ if (!playlist) {
+ return;
+ }
+
{
Glib::Mutex::Lock lm (playlist_lock);
- // cerr << "removing playlist: " << playlist->name() << endl;
+ cerr << "removing playlist: " << playlist->name() << endl;
PlaylistList::iterator i;
i = find (playlists.begin(), playlists.end(), playlist);
-
if (i != playlists.end()) {
+ cerr << "\tfound it in used playlist\n";
playlists.erase (i);
}
i = find (unused_playlists.begin(), unused_playlists.end(), playlist);
if (i != unused_playlists.end()) {
+ cerr << "\tfound it in unused playlist\n";
unused_playlists.erase (i);
}
@@ -3617,7 +3641,7 @@ Session::write_one_audio_track (AudioTrack& track, nframes_t start, nframes_t le
bool overwrite, vector<boost::shared_ptr<AudioSource> >& srcs, InterThreadInfo& itt)
{
int ret = -1;
- Playlist* playlist;
+ boost::shared_ptr<Playlist> playlist;
boost::shared_ptr<AudioFileSource> fsource;
uint32_t x;
char buf[PATH_MAX+1];
diff --git a/libs/ardour/session_command.cc b/libs/ardour/session_command.cc
index 3d2da887b0..06ed44f722 100644
--- a/libs/ardour/session_command.cc
+++ b/libs/ardour/session_command.cc
@@ -70,8 +70,9 @@ Command *Session::memento_command_factory(XMLNode *n)
} else if (obj_T == typeid (TempoMap).name()) {
return new MementoCommand<TempoMap>(*_tempo_map, before, after);
} else if (obj_T == typeid (Playlist).name() || obj_T == typeid (AudioPlaylist).name()) {
- if (Playlist *pl = playlist_by_name(child->property("name")->value()))
- return new MementoCommand<Playlist>(*pl, before, after);
+ if (boost::shared_ptr<Playlist> pl = playlist_by_name(child->property("name")->value())) {
+ return new MementoCommand<Playlist>(*(pl.get()), before, after);
+ }
} else if (obj_T == typeid (Route).name() || obj_T == typeid (AudioTrack).name()) {
return new MementoCommand<Route>(*route_by_id(id), before, after);
} else if (obj_T == typeid (Curve).name() || obj_T == typeid (AutomationList).name()) {
diff --git a/libs/ardour/session_state.cc b/libs/ardour/session_state.cc
index 95449d6c1a..2ae8a833e1 100644
--- a/libs/ardour/session_state.cc
+++ b/libs/ardour/session_state.cc
@@ -83,6 +83,7 @@
#include <ardour/control_protocol_manager.h>
#include <ardour/region_factory.h>
#include <ardour/source_factory.h>
+#include <ardour/playlist_factory.h>
#include <control_protocol/control_protocol.h>
@@ -236,7 +237,7 @@ Session::first_stage_init (string fullpath, string snapshot_name)
RegionFactory::CheckNewRegion.connect (mem_fun (*this, &Session::add_region));
SourceFactory::SourceCreated.connect (mem_fun (*this, &Session::add_source));
- Playlist::PlaylistCreated.connect (mem_fun (*this, &Session::add_playlist));
+ PlaylistFactory::PlaylistCreated.connect (mem_fun (*this, &Session::add_playlist));
Redirect::RedirectCreated.connect (mem_fun (*this, &Session::add_redirect));
NamedSelection::NamedSelectionCreated.connect (mem_fun (*this, &Session::add_named_selection));
AutomationList::AutomationListCreated.connect (mem_fun (*this, &Session::add_automation_list));
@@ -380,6 +381,7 @@ Session::setup_raid_path (string path)
if (fspath[fspath.length()-1] != '/') {
fspath += '/';
}
+
fspath += sound_dir (false);
AudioFileSource::set_search_path (fspath);
@@ -1681,7 +1683,7 @@ Session::load_playlists (const XMLNode& node)
{
XMLNodeList nlist;
XMLNodeConstIterator niter;
- Playlist *playlist;
+ boost::shared_ptr<Playlist> playlist;
nlist = node.children();
@@ -1702,7 +1704,7 @@ Session::load_unused_playlists (const XMLNode& node)
{
XMLNodeList nlist;
XMLNodeConstIterator niter;
- Playlist *playlist;
+ boost::shared_ptr<Playlist> playlist;
nlist = node.children();
@@ -1717,22 +1719,22 @@ Session::load_unused_playlists (const XMLNode& node)
// now manually untrack it
- track_playlist (playlist, false);
+ track_playlist (false, boost::weak_ptr<Playlist> (playlist));
}
return 0;
}
-Playlist *
+boost::shared_ptr<Playlist>
Session::XMLPlaylistFactory (const XMLNode& node)
{
try {
- return new AudioPlaylist (*this, node);
+ return PlaylistFactory::create (*this, node);
}
catch (failed_constructor& err) {
- return 0;
+ return boost::shared_ptr<Playlist>();
}
}
@@ -1792,7 +1794,6 @@ Session::sound_dir (bool with_path) const
old_withpath = _path;
old_withpath += old_sound_dir_name;
- old_withpath += '/';
if (stat (old_withpath.c_str(), &statbuf) == 0) {
if (with_path)
@@ -1812,7 +1813,6 @@ Session::sound_dir (bool with_path) const
res += legalize_for_path (_name);
res += '/';
res += sound_dir_name;
- res += '/';
return res;
}
@@ -2385,11 +2385,22 @@ Session::find_all_sources_across_snapshots (set<string>& result, bool exclude_th
return 0;
}
+struct RegionCounter {
+ typedef std::map<PBD::ID,boost::shared_ptr<AudioSource> > AudioSourceList;
+ AudioSourceList::iterator iter;
+ boost::shared_ptr<Region> region;
+ uint32_t count;
+
+ RegionCounter() : count (0) {}
+};
+
int
Session::cleanup_sources (Session::cleanup_report& rep)
{
- vector<boost::shared_ptr<Source> > dead_sources;
- vector<Playlist*> playlists_tbd;
+ typedef map<boost::shared_ptr<Source>, RegionCounter> SourceRegionMap;
+ SourceRegionMap dead_sources;
+
+ vector<boost::shared_ptr<Playlist> > playlists_tbd;
PathScanner scanner;
string sound_path;
vector<space_and_path>::iterator i;
@@ -2428,74 +2439,114 @@ Session::cleanup_sources (Session::cleanup_report& rep)
/* now delete any that were marked for deletion */
- for (vector<Playlist*>::iterator x = playlists_tbd.begin(); x != playlists_tbd.end(); ++x) {
- PlaylistList::iterator foo;
-
- if ((foo = unused_playlists.find (*x)) != unused_playlists.end()) {
- unused_playlists.erase (foo);
- }
- delete *x;
+ for (vector<boost::shared_ptr<Playlist> >::iterator x = playlists_tbd.begin(); x != playlists_tbd.end(); ++x) {
+ (*x)->drop_references ();
}
+ playlists_tbd.clear ();
+
/* step 2: find all un-referenced sources */
rep.paths.clear ();
rep.space = 0;
- for (AudioSourceList::iterator i = audio_sources.begin(); i != audio_sources.end(); ) {
-
- AudioSourceList::iterator tmp;
-
- tmp = i;
- ++tmp;
+ for (AudioSourceList::iterator i = audio_sources.begin(); i != audio_sources.end(); ++i) {
+
+ /* we expect the use_count() to be at least 2: one for the shared_ptr<> in the sources
+ list and one for the iterator. if its used by 1 region, we'd expect a value of 3.
- /* only remove files that are not in use and have some size
- to them. otherwise we remove the current "nascent"
+ do not bother with files that are zero size, otherwise we remove the current "nascent"
capture files.
*/
- cerr << "checking out source " << i->second->name() << " use_count = " << i->second.use_count() << endl;
+ if (i->second.use_count() <= 3 && i->second->length() > 0) {
- if (i->second.use_count() == 1 && i->second->length() > 0) {
- dead_sources.push_back (i->second);
+ pair<boost::shared_ptr<Source>, RegionCounter> newpair;
- /* remove this source from our own list to avoid us
- adding it to the list of all sources below
- */
-
- audio_sources.erase (i);
- }
+ newpair.first = i->second;
+ newpair.second.iter = i;
- i = tmp;
+ dead_sources.insert (newpair);
+ }
}
- /* Step 3: get rid of all regions in the region list that use any dead sources
- in case the sources themselves don't go away (they might be referenced in
- other snapshots).
- */
-
- for (vector<boost::shared_ptr<Source> >::iterator i = dead_sources.begin(); i != dead_sources.end();++i) {
+ /* Search the region list to find out the state of the supposedly unreferenced regions
+ */
- for (AudioRegionList::iterator r = audio_regions.begin(); r != audio_regions.end(); ) {
- AudioRegionList::iterator tmp;
- boost::shared_ptr<AudioRegion> ar;
+ for (SourceRegionMap::iterator i = dead_sources.begin(); i != dead_sources.end();++i) {
- tmp = r;
- ++tmp;
+ for (AudioRegionList::iterator r = audio_regions.begin(); r != audio_regions.end(); ++r) {
- ar = r->second;
+ boost::shared_ptr<AudioRegion> ar = r->second;
for (uint32_t n = 0; n < ar->n_channels(); ++n) {
- if (ar->source (n) == (*i)) {
- /* this region is dead */
- remove_region (ar);
+
+ if (ar->source (n) == i->first) {
+
+ /* this region uses this source */
+
+ i->second.region = ar;
+ i->second.count++;
+
+ if (i->second.count > 1) {
+ break;
+ }
}
}
-
- r = tmp;
}
}
+ /* next, get rid of all regions in the region list that use any dead sources
+ in case the sources themselves don't go away (they might be referenced in
+ other snapshots).
+
+ this is also where we remove the apparently unused sources from our source
+ list. this doesn't rename them or delete them, but it means they are
+ potential candidates for renaming after we find all soundfiles
+ and scan for use across all snapshots (including this one).
+ */
+
+ for (SourceRegionMap::iterator i = dead_sources.begin(); i != dead_sources.end(); ) {
+
+ SourceRegionMap::iterator tmp;
+
+ tmp = i;
+ ++tmp;
+
+ if (i->second.count == 0) {
+
+ /* no regions use this source */
+
+ /* remove this source from our own list to avoid us
+ adding it to the list of all sources below
+ */
+
+ audio_sources.erase (i->second.iter);
+
+ } else if (i->second.count == 1) {
+
+ /* the use_count for the source was 3. this means that there is only reference to it in addition to the source
+ list and an iterator used to traverse that list. since there is a single region using the source, that
+ must be the extra reference. this implies that its a whole-file region
+ with no children, so remove the region and the source.
+ */
+
+ remove_region (i->second.region);
+
+ /* remove this source from our own list to avoid us
+ adding it to the list of all sources below
+ */
+
+ audio_sources.erase (i->second.iter);
+
+ } else {
+ /* more than one region uses this source, do not remove it */
+ dead_sources.erase (i);
+ }
+
+ i = tmp;
+ }
+
/* build a list of all the possible sound directories for the session */
for (i = session_dirs.begin(); i != session_dirs.end(); ) {
@@ -2504,7 +2555,7 @@ Session::cleanup_sources (Session::cleanup_report& rep)
++nexti;
sound_path += (*i).path;
- sound_path += sound_dir_name;
+ sound_path += sound_dir (false);
if (nexti != session_dirs.end()) {
sound_path += ':';
@@ -2512,7 +2563,7 @@ Session::cleanup_sources (Session::cleanup_report& rep)
i = nexti;
}
-
+
/* now do the same thing for the files that ended up in the sounds dir(s)
but are not referenced as sources in any snapshot.
*/
@@ -2577,8 +2628,12 @@ Session::cleanup_sources (Session::cleanup_report& rep)
on whichever filesystem it was already on.
*/
- newpath = Glib::path_get_dirname (*x);
- newpath = Glib::path_get_dirname (newpath);
+ /* XXX this is a hack ... go up 4 levels */
+
+ newpath = Glib::path_get_dirname (*x); // "audiofiles"
+ newpath = Glib::path_get_dirname (newpath); // "session-name"
+ newpath = Glib::path_get_dirname (newpath); // "interchange"
+ newpath = Glib::path_get_dirname (newpath); // "session-dir"
newpath += '/';
newpath += dead_sound_dir_name;
@@ -2639,7 +2694,6 @@ Session::cleanup_sources (Session::cleanup_report& rep)
goto out;
}
}
-
}
ret = 0;
diff --git a/libs/ardour/source.cc b/libs/ardour/source.cc
index 74ca0afcd4..39a83cb6de 100644
--- a/libs/ardour/source.cc
+++ b/libs/ardour/source.cc
@@ -110,15 +110,22 @@ Source::set_state (const XMLNode& node)
}
void
-Source::add_playlist (Playlist* pl)
+Source::add_playlist (boost::shared_ptr<Playlist> pl)
{
_playlists.insert (pl);
+ pl->GoingAway.connect (bind (mem_fun (*this, &Source::remove_playlist), boost::weak_ptr<Playlist> (pl)));
}
void
-Source::remove_playlist (Playlist* pl)
+Source::remove_playlist (boost::weak_ptr<Playlist> wpl)
{
- std::set<Playlist*>::iterator x;
+ boost::shared_ptr<Playlist> pl (wpl.lock());
+
+ if (!pl) {
+ return;
+ }
+
+ std::set<boost::shared_ptr<Playlist> >::iterator x;
if ((x = _playlists.find (pl)) != _playlists.end()) {
_playlists.erase (x);
diff --git a/libs/ardour/source_factory.cc b/libs/ardour/source_factory.cc
index cb36d3cc35..9b8382c39f 100644
--- a/libs/ardour/source_factory.cc
+++ b/libs/ardour/source_factory.cc
@@ -83,10 +83,13 @@ boost::shared_ptr<Source>
SourceFactory::create (Session& s, const XMLNode& node)
{
boost::shared_ptr<Source> ret (new SndFileSource (s, node));
+
if (setup_peakfile (ret)) {
return boost::shared_ptr<Source>();
}
+
SourceCreated (ret);
+
return ret;
}
@@ -141,12 +144,15 @@ boost::shared_ptr<Source>
SourceFactory::createReadable (Session& s, string idstr, AudioFileSource::Flag flags, bool announce)
{
boost::shared_ptr<Source> ret (new SndFileSource (s, idstr, flags));
+
if (setup_peakfile (ret)) {
return boost::shared_ptr<Source>();
}
+
if (announce) {
SourceCreated (ret);
}
+
return ret;
}