use shared_ptr for all Playlist handling; cleanup works again

git-svn-id: svn://localhost/ardour2/trunk@1209 d708f5d6-7413-0410-9779-e7cbd77b26cf
This commit is contained in:
Paul Davis 2006-12-14 14:15:43 +00:00
parent c0924280e9
commit af12adb34f
50 changed files with 723 additions and 542 deletions

View File

@ -228,8 +228,8 @@ AnalysisWindow::analyze_data (Gtk::Button *button)
for (TrackSelection::iterator i = s.tracks.begin(); i != s.tracks.end(); ++i) { for (TrackSelection::iterator i = s.tracks.begin(); i != s.tracks.end(); ++i) {
ARDOUR::AudioPlaylist *pl boost::shared_ptr<AudioPlaylist> pl
= dynamic_cast<ARDOUR::AudioPlaylist*>((*i)->playlist()); = boost::dynamic_pointer_cast<AudioPlaylist*>((*i)->playlist());
if (!pl) if (!pl)
continue; continue;
@ -246,7 +246,7 @@ AnalysisWindow::analyze_data (Gtk::Button *button)
if (source_selection_ranges_rb.get_active()) { if (source_selection_ranges_rb.get_active()) {
// cerr << "Analyzing ranges on track " << *&rui->route().name() << endl; // 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; nframes_t i = 0;
int n; int n;

View File

@ -201,7 +201,7 @@ AudioRegionEditor::start_clock_changed ()
{ {
_session.begin_reversible_command (_("change region start position")); _session.begin_reversible_command (_("change region start position"));
Playlist* const pl = _region->playlist(); boost::shared_ptr<Playlist> pl = _region->playlist();
if (pl) { if (pl) {
XMLNode &before = pl->get_state(); XMLNode &before = pl->get_state();
@ -218,8 +218,8 @@ AudioRegionEditor::end_clock_changed ()
{ {
_session.begin_reversible_command (_("change region end position")); _session.begin_reversible_command (_("change region end position"));
Playlist* const pl = _region->playlist(); boost::shared_ptr<Playlist> pl = _region->playlist();
if (pl) { if (pl) {
XMLNode &before = pl->get_state(); XMLNode &before = pl->get_state();
_region->trim_end (end_clock.current_time(), this); _region->trim_end (end_clock.current_time(), this);
@ -239,7 +239,7 @@ AudioRegionEditor::length_clock_changed ()
_session.begin_reversible_command (_("change region length")); _session.begin_reversible_command (_("change region length"));
Playlist* const pl = _region->playlist(); boost::shared_ptr<Playlist> pl = _region->playlist();
if (pl) { if (pl) {
XMLNode &before = pl->get_state(); XMLNode &before = pl->get_state();

View File

@ -239,7 +239,7 @@ AudioStreamView::playlist_changed (boost::shared_ptr<Diskstream> ds)
StreamView::playlist_changed(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) if (apl)
playlist_connections.push_back (apl->NewCrossfade.connect (mem_fun (*this, &AudioStreamView::add_crossfade))); 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()) { if (_trackview.is_audio_track()) {
_trackview.get_diskstream()->playlist()->foreach_region (static_cast<StreamView*>(this), &StreamView::add_region_view); _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) if (apl)
apl->foreach_crossfade (this, &AudioStreamView::add_crossfade); apl->foreach_crossfade (this, &AudioStreamView::add_crossfade);
} }

View File

@ -1538,7 +1538,7 @@ Editor::build_track_region_context_menu (nframes_t frame)
if (atv) { if (atv) {
boost::shared_ptr<Diskstream> ds; boost::shared_ptr<Diskstream> ds;
Playlist* pl = 0; boost::shared_ptr<Playlist> pl;
if ((ds = atv->get_diskstream()) && ((pl = ds->playlist()))) { if ((ds = atv->get_diskstream()) && ((pl = ds->playlist()))) {
Playlist::RegionList* regions = pl->regions_at ((nframes_t) floor ( (double)frame * ds->speed())); 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) { if (atv) {
boost::shared_ptr<Diskstream> ds; boost::shared_ptr<Diskstream> ds;
Playlist* pl = 0; boost::shared_ptr<Playlist> pl;
AudioPlaylist* apl = 0; 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); Playlist::RegionList* regions = pl->regions_at (frame);
AudioPlaylist::Crossfades xfades; AudioPlaylist::Crossfades xfades;
@ -2996,7 +2996,7 @@ void
Editor::mapped_set_selected_regionview_from_click (RouteTimeAxisView& tv, uint32_t ignored, Editor::mapped_set_selected_regionview_from_click (RouteTimeAxisView& tv, uint32_t ignored,
RegionView* basis, vector<RegionView*>* all_equivs) RegionView* basis, vector<RegionView*>* all_equivs)
{ {
Playlist* pl; boost::shared_ptr<Playlist> pl;
vector<boost::shared_ptr<Region> > results; vector<boost::shared_ptr<Region> > results;
RegionView* marv; RegionView* marv;
boost::shared_ptr<Diskstream> ds; 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); 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) { if ((tatv = dynamic_cast<RouteTimeAxisView*> (*i)) != 0) {
Playlist* pl; boost::shared_ptr<Playlist> pl;
vector<boost::shared_ptr<Region> > results; vector<boost::shared_ptr<Region> > results;
RegionView* marv; RegionView* marv;
boost::shared_ptr<Diskstream> ds; boost::shared_ptr<Diskstream> ds;
@ -3222,8 +3222,8 @@ Editor::set_selected_regionview_from_region_list (boost::shared_ptr<Region> regi
/* bus */ /* bus */
continue; continue;
} }
if ((pl = dynamic_cast<Playlist*>(ds->playlist())) != 0) { if ((pl = (ds->playlist())) != 0) {
pl->get_region_list_equivalent_regions (region, results); pl->get_region_list_equivalent_regions (region, results);
} }
@ -3844,17 +3844,19 @@ Editor::end_location_changed (Location* location)
} }
int int
Editor::playlist_deletion_dialog (Playlist* pl) Editor::playlist_deletion_dialog (boost::shared_ptr<Playlist> pl)
{ {
ArdourDialog dialog ("playlist deletion dialog"); ArdourDialog dialog ("playlist deletion dialog");
Label label (string_compose (_("Playlist %1 is currently unused.\n" Label label (string_compose (_("Playlist %1 is currently unused.\n"
"If left alone, no audio files used by it will be cleaned.\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."), "If deleted, audio files used by it alone by will cleaned."),
pl->name())); pl->name()));
dialog.set_position (WIN_POS_CENTER); dialog.set_position (WIN_POS_CENTER);
dialog.get_vbox()->pack_start (label); dialog.get_vbox()->pack_start (label);
label.show ();
dialog.add_button (_("Delete playlist"), RESPONSE_ACCEPT); dialog.add_button (_("Delete playlist"), RESPONSE_ACCEPT);
dialog.add_button (_("Keep playlist"), RESPONSE_CANCEL); dialog.add_button (_("Keep playlist"), RESPONSE_CANCEL);
dialog.add_button (_("Cancel"), RESPONSE_CANCEL); dialog.add_button (_("Cancel"), RESPONSE_CANCEL);

View File

@ -257,7 +257,7 @@ class Editor : public PublicEditor
void route_name_changed (TimeAxisView *); void route_name_changed (TimeAxisView *);
gdouble frames_per_unit; gdouble frames_per_unit;
nframes_t leftmost_frame; nframes_t leftmost_frame;
void clear_playlist (ARDOUR::Playlist&); void clear_playlist (boost::shared_ptr<ARDOUR::Playlist>);
void new_playlists (); void new_playlists ();
void copy_playlists (); void copy_playlists ();
@ -1039,7 +1039,7 @@ class Editor : public PublicEditor
void fade_in_drag_finished_callback (ArdourCanvas::Item*, GdkEvent*); void fade_in_drag_finished_callback (ArdourCanvas::Item*, GdkEvent*);
void fade_out_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_motion_callback (ArdourCanvas::Item*, GdkEvent*);
void region_drag_finished_callback (ArdourCanvas::Item*, GdkEvent*); void region_drag_finished_callback (ArdourCanvas::Item*, GdkEvent*);
@ -1754,7 +1754,7 @@ class Editor : public PublicEditor
/* handling cleanup */ /* handling cleanup */
int playlist_deletion_dialog (ARDOUR::Playlist*); int playlist_deletion_dialog (boost::shared_ptr<ARDOUR::Playlist>);
vector<sigc::connection> session_connections; vector<sigc::connection> session_connections;

View File

@ -325,7 +325,7 @@ Editor::finish_bringing_in_audio (boost::shared_ptr<AudioRegion> region, uint32_
case ImportToTrack: case ImportToTrack:
if (track) { 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))); boost::shared_ptr<AudioRegion> copy (boost::dynamic_pointer_cast<AudioRegion> (RegionFactory::create (region)));
begin_reversible_command (_("insert sndfile")); begin_reversible_command (_("insert sndfile"));

View File

@ -513,8 +513,8 @@ Editor::canvas_crossfade_view_event (GdkEvent* event, ArdourCanvas::Item* item,
if (atv->is_audio_track()) { if (atv->is_audio_track()) {
AudioPlaylist* pl; boost::shared_ptr<AudioPlaylist> pl;
if ((pl = dynamic_cast<AudioPlaylist*> (atv->get_diskstream()->playlist())) != 0) { if ((pl = boost::dynamic_pointer_cast<AudioPlaylist> (atv->get_diskstream()->playlist())) != 0) {
Playlist::RegionList* rl = pl->regions_at (event_frame (event)); Playlist::RegionList* rl = pl->regions_at (event_frame (event));

View File

@ -288,7 +288,7 @@ Editor::write_audio_selection (TimeSelection& ts)
if (atv->is_audio_track()) { 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) { if (playlist && write_audio_range (*playlist, atv->get_diskstream()->n_channels(), ts) == 0) {
ret = -1; ret = -1;

View File

@ -2791,8 +2791,8 @@ Editor::region_drag_motion_callback (ArdourCanvas::Item* item, GdkEvent* event)
vector<RegionView*> new_regionviews; vector<RegionView*> new_regionviews;
set<Playlist*> affected_playlists; set<boost::shared_ptr<Playlist> > affected_playlists;
pair<set<Playlist*>::iterator,bool> insert_result; pair<set<boost::shared_ptr<Playlist> >::iterator,bool> insert_result;
// TODO: Crossfades need to be copied! // TODO: Crossfades need to be copied!
for (list<RegionView*>::const_iterator i = selection->regions.by_layer().begin(); i != selection->regions.by_layer().end(); ++i) { 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); 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()); RouteTimeAxisView* atv = dynamic_cast<RouteTimeAxisView*>(&rv->get_time_axis_view());
insert_result = affected_playlists.insert (to_playlist); insert_result = affected_playlists.insert (to_playlist);
@ -3128,7 +3128,7 @@ Editor::region_drag_motion_callback (ArdourCanvas::Item* item, GdkEvent* event)
MOTION 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(); const list<RegionView*>& layered_regions = selection->regions.by_layer();
for (list<RegionView*>::const_iterator i = layered_regions.begin(); i != layered_regions.end(); ++i) { 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()); AudioTimeAxisView* atv = dynamic_cast<AudioTimeAxisView*> (&rv->get_time_axis_view());
if (atv && atv->is_audio_track()) { 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) { if (pl) {
/* only freeze and capture state once */ /* only freeze and capture state once */
@ -3278,7 +3278,7 @@ Editor::region_drag_finished_callback (ArdourCanvas::Item* item, GdkEvent* event
{ {
nframes_t where; nframes_t where;
RegionView* rv = reinterpret_cast<RegionView *> (drag_info.data); 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; bool nocommit = true;
double speed; double speed;
RouteTimeAxisView* atv; 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++ ) { for (list<RegionView*>::const_iterator i = new_selection.begin(); i != new_selection.end();i++ ) {
Playlist* from_playlist; boost::shared_ptr<Playlist> from_playlist;
Playlist* to_playlist; boost::shared_ptr<Playlist> to_playlist;
double ix1, ix2, iy1, iy2; 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++ ) { for (list<RegionView*>::const_iterator i = new_selection.begin(); i != new_selection.end();i++ ) {
Playlist* from_playlist; boost::shared_ptr<Playlist> from_playlist;
Playlist* to_playlist; boost::shared_ptr<Playlist> to_playlist;
double ix1, ix2, iy1, iy2; double ix1, ix2, iy1, iy2;
@ -3459,9 +3459,9 @@ Editor::region_drag_finished_callback (ArdourCanvas::Item* item, GdkEvent* event
} }
out: 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 (); (*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 (); motion_frozen_playlists.clear ();
@ -3654,7 +3654,7 @@ Editor::start_selection_grab (ArdourCanvas::Item* item, GdkEvent* event)
begin_reversible_command (_("selection grab")); begin_reversible_command (_("selection grab"));
Playlist* playlist = clicked_trackview->playlist(); boost::shared_ptr<Playlist> playlist = clicked_trackview->playlist();
XMLNode *before = &(playlist->get_state()); XMLNode *before = &(playlist->get_state());
clicked_trackview->playlist()->add_region (region, selection->time[clicked_selection].start); 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; double speed = 1.0;
TimeAxisView* tvp = clicked_trackview; TimeAxisView* tvp = clicked_trackview;
RouteTimeAxisView* tv = dynamic_cast<RouteTimeAxisView*>(tvp); 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()) { if (tv && tv->is_audio_track()) {
speed = tv->get_diskstream()->speed(); speed = tv->get_diskstream()->speed();
@ -4024,7 +4024,7 @@ Editor::trim_motion_callback (ArdourCanvas::Item* item, GdkEvent* event)
if (arv) if (arv)
arv->temporarily_hide_envelope (); arv->temporarily_hide_envelope ();
Playlist * pl = (*i)->region()->playlist(); boost::shared_ptr<Playlist> pl = (*i)->region()->playlist();
insert_result = motion_frozen_playlists.insert (pl); insert_result = motion_frozen_playlists.insert (pl);
if (insert_result.second) { if (insert_result.second) {
session->add_command(new MementoCommand<Playlist>(*pl, &pl->get_state(), 0)); 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 (); //(*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 (); motion_frozen_playlists.clear ();
@ -4252,22 +4252,22 @@ Editor::point_trim (GdkEvent* event)
i != selection->regions.by_layer().end(); ++i) i != selection->regions.by_layer().end(); ++i)
{ {
if (!(*i)->region()->locked()) { if (!(*i)->region()->locked()) {
Playlist *pl = (*i)->region()->playlist(); boost::shared_ptr<Playlist> pl = (*i)->region()->playlist();
XMLNode &before = pl->get_state(); XMLNode &before = pl->get_state();
(*i)->region()->trim_front (new_bound, this); (*i)->region()->trim_front (new_bound, this);
XMLNode &after = pl->get_state(); 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 { } else {
if (!rv->region()->locked()) { if (!rv->region()->locked()) {
Playlist *pl = rv->region()->playlist(); boost::shared_ptr<Playlist> pl = rv->region()->playlist();
XMLNode &before = pl->get_state(); XMLNode &before = pl->get_state();
rv->region()->trim_front (new_bound, this); rv->region()->trim_front (new_bound, this);
XMLNode &after = pl->get_state(); 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) for (list<RegionView*>::const_iterator i = selection->regions.by_layer().begin(); i != selection->regions.by_layer().end(); ++i)
{ {
if (!(*i)->region()->locked()) { if (!(*i)->region()->locked()) {
Playlist *pl = (*i)->region()->playlist(); boost::shared_ptr<Playlist> pl = (*i)->region()->playlist();
XMLNode &before = pl->get_state(); XMLNode &before = pl->get_state();
(*i)->region()->trim_end (new_bound, this); (*i)->region()->trim_end (new_bound, this);
XMLNode &after = pl->get_state(); 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 { } else {
if (!rv->region()->locked()) { if (!rv->region()->locked()) {
Playlist *pl = rv->region()->playlist(); boost::shared_ptr<Playlist> pl = rv->region()->playlist();
XMLNode &before = pl->get_state(); XMLNode &before = pl->get_state();
rv->region()->trim_end (new_bound, this); rv->region()->trim_end (new_bound, this);
XMLNode &after = pl->get_state(); 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; return;
} }
Playlist* playlist = atv->playlist(); boost::shared_ptr<Playlist> playlist = atv->playlist();
double speed = atv->get_diskstream()->speed(); double speed = atv->get_diskstream()->speed();
XMLNode &before = playlist->get_state(); XMLNode &before = playlist->get_state();
playlist->add_region (boost::dynamic_pointer_cast<AudioRegion> (RegionFactory::create (arv->audio_region())), (nframes_t) (pos * speed)); playlist->add_region (boost::dynamic_pointer_cast<AudioRegion> (RegionFactory::create (arv->audio_region())), (nframes_t) (pos * speed));
XMLNode &after = playlist->get_state(); 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 // playlist is frozen, so we have to update manually

View File

@ -44,6 +44,7 @@
#include <ardour/audio_track.h> #include <ardour/audio_track.h>
#include <ardour/audioplaylist.h> #include <ardour/audioplaylist.h>
#include <ardour/region_factory.h> #include <ardour/region_factory.h>
#include <ardour/playlist_factory.h>
#include <ardour/reverse.h> #include <ardour/reverse.h>
#include "ardour_ui.h" #include "ardour_ui.h"
@ -122,7 +123,7 @@ Editor::split_regions_at (nframes_t where, RegionSelection& regions)
tmp = a; tmp = a;
++tmp; ++tmp;
Playlist* pl = (*a)->region()->playlist(); boost::shared_ptr<Playlist> pl = (*a)->region()->playlist();
AudioRegionView* const arv = dynamic_cast<AudioRegionView*>(*a); AudioRegionView* const arv = dynamic_cast<AudioRegionView*>(*a);
if (arv) if (arv)
@ -149,7 +150,7 @@ Editor::remove_clicked_region ()
return; return;
} }
Playlist* playlist = clicked_audio_trackview->playlist(); boost::shared_ptr<Playlist> playlist = clicked_audio_trackview->playlist();
begin_reversible_command (_("remove region")); begin_reversible_command (_("remove region"));
XMLNode &before = playlist->get_state(); XMLNode &before = playlist->get_state();
@ -232,7 +233,7 @@ Editor::select_region_for_operation (int dir, TimeAxisView **tv)
RouteTimeAxisView* rtv; RouteTimeAxisView* rtv;
if ((rtv = dynamic_cast<RouteTimeAxisView*> (*tv)) != 0) { if ((rtv = dynamic_cast<RouteTimeAxisView*> (*tv)) != 0) {
Playlist *pl; boost::shared_ptr<Playlist> pl;
if ((pl = rtv->playlist()) == 0) { if ((pl = rtv->playlist()) == 0) {
return region; return region;
@ -1719,7 +1720,7 @@ Editor::insert_region_list_drag (boost::shared_ptr<AudioRegion> region, int x, i
TimeAxisView *tv; TimeAxisView *tv;
nframes_t where; nframes_t where;
AudioTimeAxisView *atv = 0; AudioTimeAxisView *atv = 0;
Playlist *playlist; boost::shared_ptr<Playlist> playlist;
track_canvas.window_to_world (x, y, wx, wy); track_canvas.window_to_world (x, y, wx, wy);
wx += horizontal_adjustment.get_value(); wx += horizontal_adjustment.get_value();
@ -1749,20 +1750,26 @@ Editor::insert_region_list_drag (boost::shared_ptr<AudioRegion> region, int x, i
return; return;
} }
cerr << "drop target playlist, UC = " << playlist.use_count() << endl;
snap_to (where); snap_to (where);
begin_reversible_command (_("insert dragged region")); begin_reversible_command (_("insert dragged region"));
XMLNode &before = playlist->get_state(); XMLNode &before = playlist->get_state();
cerr << "pre add target playlist, UC = " << playlist.use_count() << endl;
playlist->add_region (RegionFactory::create (region), where, 1.0); 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())); session->add_command(new MementoCommand<Playlist>(*playlist, &before, &playlist->get_state()));
commit_reversible_command (); commit_reversible_command ();
cerr << "post drop target playlist, UC = " << playlist.use_count() << endl;
} }
void void
Editor::insert_region_list_selection (float times) Editor::insert_region_list_selection (float times)
{ {
RouteTimeAxisView *tv = 0; RouteTimeAxisView *tv = 0;
Playlist *playlist; boost::shared_ptr<Playlist> playlist;
if (clicked_audio_trackview != 0) { if (clicked_audio_trackview != 0) {
tv = clicked_audio_trackview; tv = clicked_audio_trackview;
@ -2097,7 +2104,7 @@ Editor::region_from_selection ()
for (TrackSelection::iterator i = selection->tracks.begin(); i != selection->tracks.end(); ++i) { for (TrackSelection::iterator i = selection->tracks.begin(); i != selection->tracks.end(); ++i) {
boost::shared_ptr<AudioRegion> current; boost::shared_ptr<AudioRegion> current;
boost::shared_ptr<Region> current_r; boost::shared_ptr<Region> current_r;
Playlist *pl; boost::shared_ptr<Playlist> pl;
nframes_t internal_start; nframes_t internal_start;
string new_name; 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<AudioRegion> current;
boost::shared_ptr<Region> current_r; boost::shared_ptr<Region> current_r;
Playlist* playlist; boost::shared_ptr<Playlist> playlist;
nframes_t internal_start; nframes_t internal_start;
string new_name; string new_name;
@ -2189,7 +2196,7 @@ Editor::separate_region_from_selection ()
return; return;
} }
Playlist *playlist; boost::shared_ptr<Playlist> playlist;
for (TrackSelection::iterator i = selection->tracks.begin(); i != selection->tracks.end(); ++i) { for (TrackSelection::iterator i = selection->tracks.begin(); i != selection->tracks.end(); ++i) {
@ -2235,7 +2242,7 @@ Editor::separate_regions_using_location (Location& loc)
return; return;
} }
Playlist *playlist; boost::shared_ptr<Playlist> playlist;
/* XXX i'm unsure as to whether this should operate on selected tracks only /* 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 or the entire enchillada. uncomment the below line to correct the behaviour
@ -2284,8 +2291,8 @@ Editor::crop_region_to_selection ()
return; return;
} }
vector<Playlist*> playlists; vector<boost::shared_ptr<Playlist> > playlists;
Playlist *playlist; boost::shared_ptr<Playlist> playlist;
if (clicked_trackview != 0) { if (clicked_trackview != 0) {
@ -2321,7 +2328,7 @@ Editor::crop_region_to_selection ()
begin_reversible_command (_("trim 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; boost::shared_ptr<Region> region;
@ -2371,7 +2378,7 @@ Editor::region_fill_track ()
if (!ar) if (!ar)
continue; continue;
Playlist* pl = region->playlist(); boost::shared_ptr<Playlist> pl = region->playlist();
if (end <= region->last_frame()) { if (end <= region->last_frame()) {
return; return;
@ -2415,7 +2422,7 @@ Editor::region_fill_selection ()
nframes_t start = selection->time[clicked_selection].start; nframes_t start = selection->time[clicked_selection].start;
nframes_t end = selection->time[clicked_selection].end; nframes_t end = selection->time[clicked_selection].end;
Playlist *playlist; boost::shared_ptr<Playlist> playlist;
if (selection->tracks.empty()) { if (selection->tracks.empty()) {
return; return;
@ -2781,7 +2788,7 @@ Editor::bounce_range_selection ()
continue; continue;
} }
Playlist* playlist; boost::shared_ptr<Playlist> playlist;
if ((playlist = atv->playlist()) == 0) { if ((playlist = atv->playlist()) == 0) {
return; return;
@ -2897,7 +2904,7 @@ Editor::cut_copy_points (CutCopyOp op)
} }
struct PlaylistState { struct PlaylistState {
Playlist* playlist; boost::shared_ptr<Playlist> playlist;
XMLNode* before; XMLNode* before;
}; };
@ -2910,7 +2917,7 @@ struct lt_playlist {
void void
Editor::cut_copy_regions (CutCopyOp op) 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; PlaylistMapping pmap;
nframes_t first_position = max_frames; nframes_t first_position = max_frames;
@ -2921,7 +2928,8 @@ Editor::cut_copy_regions (CutCopyOp op)
first_position = min ((*x)->region()->position(), first_position); first_position = min ((*x)->region()->position(), first_position);
if (op == Cut || op == Clear) { 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) { if (pl) {
PlaylistState before; PlaylistState before;
@ -2939,8 +2947,8 @@ Editor::cut_copy_regions (CutCopyOp op)
for (RegionSelection::iterator x = selection->regions.begin(); x != selection->regions.end(); ) { for (RegionSelection::iterator x = selection->regions.begin(); x != selection->regions.end(); ) {
AudioPlaylist *pl = dynamic_cast<AudioPlaylist*>((*x)->region()->playlist()); boost::shared_ptr<AudioPlaylist> pl = boost::dynamic_pointer_cast<AudioPlaylist>((*x)->region()->playlist());
AudioPlaylist* npl; boost::shared_ptr<AudioPlaylist> npl;
RegionSelection::iterator tmp; RegionSelection::iterator tmp;
tmp = x; tmp = x;
@ -2951,7 +2959,7 @@ Editor::cut_copy_regions (CutCopyOp op)
PlaylistMapping::iterator pi = pmap.find (pl); PlaylistMapping::iterator pi = pmap.find (pl);
if (pi == pmap.end()) { if (pi == pmap.end()) {
npl = new AudioPlaylist (*session, "cutlist", true); npl = boost::dynamic_pointer_cast<AudioPlaylist> (PlaylistFactory::create (*session, "cutlist", true));
npl->freeze(); npl->freeze();
pmap[pl] = npl; pmap[pl] = npl;
} else { } else {
@ -2983,7 +2991,7 @@ Editor::cut_copy_regions (CutCopyOp op)
x = tmp; x = tmp;
} }
list<Playlist*> foo; list<boost::shared_ptr<Playlist> > foo;
for (PlaylistMapping::iterator i = pmap.begin(); i != pmap.end(); ++i) { for (PlaylistMapping::iterator i = pmap.begin(); i != pmap.end(); ++i) {
foo.push_back (i->second); foo.push_back (i->second);
@ -3080,8 +3088,8 @@ Editor::paste_named_selection (float times)
TreeModel::iterator i = selected->get_selected(); TreeModel::iterator i = selected->get_selected();
NamedSelection* ns = (*i)[named_selection_columns.selection]; NamedSelection* ns = (*i)[named_selection_columns.selection];
list<Playlist*>::iterator chunk; list<boost::shared_ptr<Playlist> >::iterator chunk;
list<Playlist*>::iterator tmp; list<boost::shared_ptr<Playlist> >::iterator tmp;
chunk = ns->playlists.begin(); chunk = ns->playlists.begin();
@ -3090,8 +3098,8 @@ Editor::paste_named_selection (float times)
for (t = selection->tracks.begin(); t != selection->tracks.end(); ++t) { for (t = selection->tracks.begin(); t != selection->tracks.end(); ++t) {
AudioTimeAxisView* atv; AudioTimeAxisView* atv;
Playlist* pl; boost::shared_ptr<Playlist> pl;
AudioPlaylist* apl; boost::shared_ptr<AudioPlaylist> apl;
if ((atv = dynamic_cast<AudioTimeAxisView*> (*t)) == 0) { if ((atv = dynamic_cast<AudioTimeAxisView*> (*t)) == 0) {
continue; continue;
@ -3100,8 +3108,8 @@ Editor::paste_named_selection (float times)
if ((pl = atv->playlist()) == 0) { if ((pl = atv->playlist()) == 0) {
continue; continue;
} }
if ((apl = dynamic_cast<AudioPlaylist*> (pl)) == 0) { if ((apl = boost::dynamic_pointer_cast<AudioPlaylist> (pl)) == 0) {
continue; continue;
} }
@ -3109,7 +3117,7 @@ Editor::paste_named_selection (float times)
++tmp; ++tmp;
XMLNode &before = apl->get_state(); 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())); session->add_command(new MementoCommand<AudioPlaylist>(*apl, &before, &apl->get_state()));
if (tmp != ns->playlists.end()) { if (tmp != ns->playlists.end()) {
@ -3123,7 +3131,7 @@ Editor::paste_named_selection (float times)
void void
Editor::duplicate_some_regions (RegionSelection& regions, float times) 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 RegionSelection sel = regions; // clear (below) will clear the argument list
begin_reversible_command (_("duplicate region")); begin_reversible_command (_("duplicate region"));
@ -3161,7 +3169,7 @@ Editor::duplicate_selection (float times)
return; return;
} }
Playlist *playlist; boost::shared_ptr<Playlist> playlist;
vector<boost::shared_ptr<AudioRegion> > new_regions; vector<boost::shared_ptr<AudioRegion> > new_regions;
vector<boost::shared_ptr<AudioRegion> >::iterator ri; vector<boost::shared_ptr<AudioRegion> >::iterator ri;
@ -3227,20 +3235,20 @@ Editor::center_edit_cursor ()
} }
void void
Editor::clear_playlist (Playlist& playlist) Editor::clear_playlist (boost::shared_ptr<Playlist> playlist)
{ {
begin_reversible_command (_("clear playlist")); begin_reversible_command (_("clear playlist"));
XMLNode &before = playlist.get_state(); XMLNode &before = playlist->get_state();
playlist.clear (); playlist->clear ();
XMLNode &after = playlist.get_state(); XMLNode &after = playlist->get_state();
session->add_command (new MementoCommand<Playlist>(playlist, &before, &after)); session->add_command (new MementoCommand<Playlist>(*playlist.get(), &before, &after));
commit_reversible_command (); commit_reversible_command ();
} }
void void
Editor::nudge_track (bool use_edit_cursor, bool forwards) Editor::nudge_track (bool use_edit_cursor, bool forwards)
{ {
Playlist *playlist; boost::shared_ptr<Playlist> playlist;
nframes_t distance; nframes_t distance;
nframes_t next_distance; nframes_t next_distance;
nframes_t start; nframes_t start;
@ -3388,7 +3396,7 @@ Editor::apply_filter (AudioFilter& filter, string command)
if (!arv) if (!arv)
continue; continue;
Playlist* playlist = arv->region()->playlist(); boost::shared_ptr<Playlist> playlist = arv->region()->playlist();
RegionSelection::iterator tmp; RegionSelection::iterator tmp;

View File

@ -101,7 +101,8 @@ Editor::add_audio_region_to_region_display (boost::shared_ptr<AudioRegion> regio
parent = *(region_list_model->append()); parent = *(region_list_model->append());
parent[region_list_columns.name] = _("Hidden"); 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 { } 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_model->insert(iter));
parent[region_list_columns.name] = _("Hidden"); 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 { } else {
parent = *iter; parent = *iter;

View File

@ -150,12 +150,12 @@ Editor::create_named_selection (const string & name)
return; return;
} }
Playlist* what_we_found; boost::shared_ptr<Playlist> what_we_found;
list<Playlist*> thelist; list<boost::shared_ptr<Playlist> > thelist;
for (TrackViewList::iterator i = views->begin(); i != views->end(); ++i) { for (TrackViewList::iterator i = views->begin(); i != views->end(); ++i) {
Playlist *pl = (*i)->playlist(); boost::shared_ptr<Playlist> pl = (*i)->playlist();
if (pl) { if (pl) {

View File

@ -159,7 +159,7 @@ void
Editor::do_timestretch (TimeStretchDialog& dialog) Editor::do_timestretch (TimeStretchDialog& dialog)
{ {
Track* t; Track* t;
Playlist* playlist; boost::shared_ptr<Playlist> playlist;
boost::shared_ptr<Region> new_region; boost::shared_ptr<Region> new_region;
for (RegionSelection::iterator i = dialog.regions.begin(); i != dialog.regions.end(); ) { for (RegionSelection::iterator i = dialog.regions.begin(); i != dialog.regions.end(); ) {

View File

@ -2,11 +2,12 @@
#define __ardour_gtk_playlist_selection_h__ #define __ardour_gtk_playlist_selection_h__
#include <list> #include <list>
#include <boost/shared_ptr.hpp>
namespace ARDOUR { namespace ARDOUR {
class Playlist; class Playlist;
} }
struct PlaylistSelection : list<ARDOUR::Playlist*> {}; struct PlaylistSelection : list<boost::shared_ptr<ARDOUR::Playlist> > {};
#endif /* __ardour_gtk_playlist_selection_h__ */ #endif /* __ardour_gtk_playlist_selection_h__ */

View File

@ -86,6 +86,17 @@ PlaylistSelector::clear_map ()
dspl_map.clear (); 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 void
PlaylistSelector::show_for (RouteUI* ruix) PlaylistSelector::show_for (RouteUI* ruix)
{ {
@ -112,7 +123,8 @@ PlaylistSelector::show_for (RouteUI* ruix)
TreeModel::Row others = *(model->append ()); TreeModel::Row others = *(model->append ());
others[columns.text] = _("Other tracks"); 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) { 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) { if (ds == this_ds) {
row = *(model->prepend()); row = *(model->prepend());
row[columns.text] = nodename; row[columns.text] = nodename;
row[columns.playlist] = 0; boost::shared_ptr<Playlist> proxy = row[columns.playlist];
proxy.reset ();
} else { } else {
row = *(model->append (others.children())); row = *(model->append (others.children()));
row[columns.text] = nodename; 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 */ /* 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; TreeModel::Row child_row;
@ -173,15 +187,15 @@ PlaylistSelector::show_for (RouteUI* ruix)
} }
void 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()) { if (pl->frozen()) {
return; return;
} }
if ((apl = dynamic_cast<AudioPlaylist*> (pl)) == 0) { if ((apl = boost::dynamic_pointer_cast<AudioPlaylist> (pl)) == 0) {
return; 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()) { 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); x = dspl_map.insert (dspl_map.end(), newp);
} }
@ -219,7 +233,7 @@ PlaylistSelector::close_button_click ()
void void
PlaylistSelector::selection_changed () PlaylistSelector::selection_changed ()
{ {
Playlist *playlist; boost::shared_ptr<Playlist> playlist;
TreeModel::iterator iter = tree.get_selection()->get_selected(); TreeModel::iterator iter = tree.get_selection()->get_selected();
@ -231,14 +245,14 @@ PlaylistSelector::selection_changed ()
if ((playlist = ((*iter)[columns.playlist])) != 0) { if ((playlist = ((*iter)[columns.playlist])) != 0) {
AudioTrack* at; AudioTrack* at;
AudioPlaylist* apl; boost::shared_ptr<AudioPlaylist> apl;
if ((at = rui->audio_track()) == 0) { if ((at = rui->audio_track()) == 0) {
/* eh? */ /* eh? */
return; return;
} }
if ((apl = dynamic_cast<AudioPlaylist*> (playlist)) == 0) { if ((apl = boost::dynamic_pointer_cast<AudioPlaylist> (playlist)) == 0) {
/* eh? */ /* eh? */
return; return;
} }

View File

@ -20,6 +20,8 @@
#ifndef __ardour_playlist_selector_h__ #ifndef __ardour_playlist_selector_h__
#define __ardour_playlist_selector_h__ #define __ardour_playlist_selector_h__
#include <boost/shared_ptr.hpp>
#include <gtkmm/box.h> #include <gtkmm/box.h>
#include <gtkmm/scrolledwindow.h> #include <gtkmm/scrolledwindow.h>
#include <gtkmm/button.h> #include <gtkmm/button.h>
@ -45,8 +47,11 @@ class PlaylistSelector : public ArdourDialog
void set_session (ARDOUR::Session*); void set_session (ARDOUR::Session*);
void show_for (RouteUI*); void show_for (RouteUI*);
protected:
bool on_unmap_event (GdkEventAny*);
private: 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; ARDOUR::Session* session;
Gtk::ScrolledWindow scroller; Gtk::ScrolledWindow scroller;
@ -55,7 +60,7 @@ class PlaylistSelector : public ArdourDialog
sigc::connection select_connection; 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 clear_map ();
void close_button_click (); void close_button_click ();
void selection_changed (); void selection_changed ();
@ -66,7 +71,7 @@ class PlaylistSelector : public ArdourDialog
add (playlist); add (playlist);
} }
Gtk::TreeModelColumn<std::string> text; Gtk::TreeModelColumn<std::string> text;
Gtk::TreeModelColumn<ARDOUR::Playlist*> playlist; Gtk::TreeModelColumn<boost::shared_ptr<ARDOUR::Playlist> > playlist;
}; };
ModelColumns columns; ModelColumns columns;

View File

@ -106,7 +106,7 @@ class PublicEditor : public Gtk::Window, public PBD::StatefulThingWithGoingAway
virtual gdouble get_current_zoom () = 0; virtual gdouble get_current_zoom () = 0;
virtual PlaylistSelector& playlist_selector() const = 0; virtual PlaylistSelector& playlist_selector() const = 0;
virtual void route_name_changed (TimeAxisView *) = 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 new_playlists () = 0;
virtual void copy_playlists () = 0; virtual void copy_playlists () = 0;
virtual void clear_playlists () = 0; virtual void clear_playlists () = 0;

View File

@ -245,9 +245,9 @@ RouteTimeAxisView::~RouteTimeAxisView ()
} }
void 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); assert(pl);
modified_connection.disconnect (); modified_connection.disconnect ();
@ -312,7 +312,7 @@ RouteTimeAxisView::playlist_changed ()
label_view (); label_view ();
if (is_track()) { 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()) if (!ds || ds->destructive())
return; return;
Playlist *const pl = ds->playlist(); boost::shared_ptr<Playlist> pl = ds->playlist();
if (!pl) if (!pl)
return; return;
@ -874,7 +874,7 @@ RouteTimeAxisView::use_copy_playlist (bool prompt)
if (!ds || ds->destructive()) if (!ds || ds->destructive())
return; return;
Playlist *const pl = ds->playlist(); boost::shared_ptr<const Playlist> pl = ds->playlist();
if (!pl) if (!pl)
return; return;
@ -922,7 +922,7 @@ RouteTimeAxisView::use_new_playlist (bool prompt)
if (!ds || ds->destructive()) if (!ds || ds->destructive())
return; return;
Playlist *const pl = ds->playlist(); boost::shared_ptr<const Playlist> pl = ds->playlist();
if (!pl) if (!pl)
return; return;
@ -955,6 +955,7 @@ RouteTimeAxisView::use_new_playlist (bool prompt)
if (name.length()) { if (name.length()) {
ds->use_new_playlist (); ds->use_new_playlist ();
ds->playlist()->set_name (name); 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()) if (!ds || ds->destructive())
return; return;
Playlist *const pl = ds->playlist(); boost::shared_ptr<Playlist> pl = ds->playlist();
if (!pl) if (!pl)
return; return;
editor.clear_playlist (*pl); editor.clear_playlist (pl);
} }
void void
@ -1087,7 +1088,7 @@ RouteTimeAxisView::name() const
return _route->name(); return _route->name();
} }
Playlist * boost::shared_ptr<Playlist>
RouteTimeAxisView::playlist () const RouteTimeAxisView::playlist () const
{ {
boost::shared_ptr<Diskstream> ds; boost::shared_ptr<Diskstream> ds;
@ -1095,7 +1096,7 @@ RouteTimeAxisView::playlist () const
if ((ds = get_diskstream()) != 0) { if ((ds = get_diskstream()) != 0) {
return ds->playlist(); return ds->playlist();
} else { } 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) RouteTimeAxisView::find_next_region (nframes_t pos, RegionPoint point, int32_t dir)
{ {
boost::shared_ptr<Diskstream> stream; boost::shared_ptr<Diskstream> stream;
Playlist *playlist = 0; boost::shared_ptr<Playlist> playlist;
if ((stream = get_diskstream()) != 0 && (playlist = stream->playlist()) != 0) { if ((stream = get_diskstream()) != 0 && (playlist = stream->playlist()) != 0) {
return playlist->find_next_region (pos, point, dir); 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 bool
RouteTimeAxisView::cut_copy_clear (Selection& selection, CutCopyOp op) 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(); boost::shared_ptr<Diskstream> ds = get_diskstream();
Playlist* playlist; boost::shared_ptr<Playlist> playlist;
bool ret = false; bool ret = false;
if (ds == 0) { if (ds == 0) {
@ -1185,7 +1186,7 @@ RouteTimeAxisView::cut_copy_clear (Selection& selection, CutCopyOp op)
case Cut: case Cut:
if ((what_we_got = playlist->cut (time)) != 0) { if ((what_we_got = playlist->cut (time)) != 0) {
editor.get_cut_buffer().add (what_we_got); 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; ret = true;
} }
break; break;
@ -1198,7 +1199,7 @@ RouteTimeAxisView::cut_copy_clear (Selection& selection, CutCopyOp op)
case Clear: case Clear:
if ((what_we_got = playlist->cut (time)) != 0) { if ((what_we_got = playlist->cut (time)) != 0) {
_session.add_command( new MementoCommand<Playlist>(*playlist, &before, &playlist->get_state())); _session.add_command( new MementoCommand<Playlist>(*playlist, &before, &playlist->get_state()));
what_we_got->unref (); what_we_got->release ();
ret = true; ret = true;
} }
break; break;
@ -1214,7 +1215,7 @@ RouteTimeAxisView::paste (nframes_t pos, float times, Selection& selection, size
return false; return false;
} }
Playlist* playlist = get_diskstream()->playlist(); boost::shared_ptr<Playlist> playlist = get_diskstream()->playlist();
PlaylistSelection::iterator p; PlaylistSelection::iterator p;
for (p = selection.playlists.begin(); p != selection.playlists.end() && nth; ++p, --nth); 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() ); pos = session_frame_to_track_frame(pos, get_diskstream()->speed() );
XMLNode &before = playlist->get_state(); 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())); _session.add_command( new MementoCommand<Playlist>(*playlist, &before, &playlist->get_state()));
return true; return true;
@ -1269,29 +1270,29 @@ RouteTimeAxisView::build_playlist_menu (Gtk::Menu * menu)
playlist_menu = new Menu; playlist_menu = new Menu;
playlist_menu->set_name ("ArdourContextMenu"); playlist_menu->set_name ("ArdourContextMenu");
vector<Playlist*> playlists; vector<boost::shared_ptr<Playlist> > playlists;
boost::shared_ptr<Diskstream> ds = get_diskstream(); boost::shared_ptr<Diskstream> ds = get_diskstream();
RadioMenuItem::Group playlist_group; RadioMenuItem::Group playlist_group;
_session.get_playlists (playlists); _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()) { 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()) { if (ds->playlist()->id() == (*i)->id()) {
static_cast<RadioMenuItem*>(&playlist_items.back())->set_active(); static_cast<RadioMenuItem*>(&playlist_items.back())->set_active();
} }
} else if (ds->playlist()->id() == (*i)->id()) { } 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(); static_cast<RadioMenuItem*>(&playlist_items.back())->set_active();
} }
} }
playlist_items.push_back (SeparatorElem()); playlist_items.push_back (SeparatorElem());
playlist_items.push_back (MenuElem (_("Rename"), mem_fun(*this, &RouteTimeAxisView::rename_current_playlist))); playlist_items.push_back (MenuElem (_("Rename"), mem_fun(*this, &RouteTimeAxisView::rename_current_playlist)));
playlist_items.push_back (SeparatorElem()); playlist_items.push_back (SeparatorElem());
@ -1306,12 +1307,18 @@ RouteTimeAxisView::build_playlist_menu (Gtk::Menu * menu)
} }
void void
RouteTimeAxisView::use_playlist (Playlist* pl) RouteTimeAxisView::use_playlist (boost::weak_ptr<Playlist> wpl)
{ {
AudioPlaylist* apl = dynamic_cast<AudioPlaylist*> (pl);
assert (is_track()); 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) { if (apl) {
get_diskstream()->use_playlist (apl); get_diskstream()->use_playlist (apl);
} }

View File

@ -99,7 +99,7 @@ public:
string name() const; string name() const;
StreamView* view() const { return _view; } StreamView* view() const { return _view; }
ARDOUR::RouteGroup* edit_group() const; ARDOUR::RouteGroup* edit_group() const;
ARDOUR::Playlist* playlist() const; boost::shared_ptr<ARDOUR::Playlist> playlist() const;
protected: protected:
friend class StreamView; friend class StreamView;
@ -176,7 +176,7 @@ protected:
void align_style_changed (); void align_style_changed ();
void set_align_style (ARDOUR::AlignStyle); 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 playlist_click ();
void show_playlist_selector (); void show_playlist_selector ();
void playlist_changed (); void playlist_changed ();
@ -229,7 +229,7 @@ protected:
Gtk::Menu* playlist_action_menu; Gtk::Menu* playlist_action_menu;
Gtk::MenuItem* playlist_item; Gtk::MenuItem* playlist_item;
void use_playlist (ARDOUR::Playlist*); void use_playlist (boost::weak_ptr<ARDOUR::Playlist>);
ArdourCanvas::SimpleRect* timestretch_rect; ArdourCanvas::SimpleRect* timestretch_rect;

View File

@ -132,7 +132,7 @@ Selection::clear_playlists ()
/* Selections own their playlists */ /* Selections own their playlists */
for (PlaylistSelection::iterator i = playlists.begin(); i != playlists.end(); ++i) { for (PlaylistSelection::iterator i = playlists.begin(); i != playlists.end(); ++i) {
(*i)->unref (); (*i)->release ();
} }
if (!playlists.empty()) { if (!playlists.empty()) {
@ -165,12 +165,12 @@ Selection::toggle (boost::shared_ptr<Redirect> r)
} }
void void
Selection::toggle (Playlist* pl) Selection::toggle (boost::shared_ptr<Playlist> pl)
{ {
PlaylistSelection::iterator i; PlaylistSelection::iterator i;
if ((i = find (playlists.begin(), playlists.end(), pl)) == playlists.end()) { if ((i = find (playlists.begin(), playlists.end(), pl)) == playlists.end()) {
pl->ref (); pl->use ();
playlists.push_back(pl); playlists.push_back(pl);
} else { } else {
playlists.erase (i); playlists.erase (i);
@ -260,23 +260,23 @@ Selection::add (boost::shared_ptr<Redirect> r)
} }
void void
Selection::add (Playlist* pl) Selection::add (boost::shared_ptr<Playlist> pl)
{ {
if (find (playlists.begin(), playlists.end(), pl) == playlists.end()) { if (find (playlists.begin(), playlists.end(), pl) == playlists.end()) {
pl->ref (); pl->use ();
playlists.push_back(pl); playlists.push_back(pl);
PlaylistsChanged (); PlaylistsChanged ();
} }
} }
void void
Selection::add (const list<Playlist*>& pllist) Selection::add (const list<boost::shared_ptr<Playlist> >& pllist)
{ {
bool changed = false; 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()) { if (find (playlists.begin(), playlists.end(), (*i)) == playlists.end()) {
(*i)->ref (); (*i)->use ();
playlists.push_back (*i); playlists.push_back (*i);
changed = true; changed = true;
} }
@ -429,9 +429,9 @@ Selection::remove (const list<TimeAxisView*>& track_list)
} }
void 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()) { if ((i = find (playlists.begin(), playlists.end(), track)) != playlists.end()) {
playlists.erase (i); playlists.erase (i);
PlaylistsChanged(); PlaylistsChanged();
@ -439,13 +439,13 @@ Selection::remove (Playlist* track)
} }
void void
Selection::remove (const list<Playlist*>& pllist) Selection::remove (const list<boost::shared_ptr<Playlist> >& pllist)
{ {
bool changed = false; 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()) { if ((x = find (playlists.begin(), playlists.end(), (*i))) != playlists.end()) {
playlists.erase (x); playlists.erase (x);
@ -520,14 +520,14 @@ Selection::set (const list<TimeAxisView*>& track_list)
} }
void void
Selection::set (Playlist* playlist) Selection::set (boost::shared_ptr<Playlist> playlist)
{ {
clear_playlists (); clear_playlists ();
add (playlist); add (playlist);
} }
void void
Selection::set (const list<Playlist*>& pllist) Selection::set (const list<boost::shared_ptr<Playlist> >& pllist)
{ {
clear_playlists (); clear_playlists ();
add (pllist); add (pllist);

View File

@ -101,8 +101,8 @@ class Selection : public sigc::trackable
void set (std::vector<RegionView*>&); void set (std::vector<RegionView*>&);
long set (TimeAxisView*, nframes_t, nframes_t); long set (TimeAxisView*, nframes_t, nframes_t);
void set (ARDOUR::AutomationList*); void set (ARDOUR::AutomationList*);
void set (ARDOUR::Playlist*); void set (boost::shared_ptr<ARDOUR::Playlist>);
void set (const list<ARDOUR::Playlist*>&); void set (const list<boost::shared_ptr<ARDOUR::Playlist> >&);
void set (boost::shared_ptr<ARDOUR::Redirect>); void set (boost::shared_ptr<ARDOUR::Redirect>);
void set (AutomationSelectable*); void set (AutomationSelectable*);
@ -112,8 +112,8 @@ class Selection : public sigc::trackable
void toggle (std::vector<RegionView*>&); void toggle (std::vector<RegionView*>&);
long toggle (nframes_t, nframes_t); long toggle (nframes_t, nframes_t);
void toggle (ARDOUR::AutomationList*); void toggle (ARDOUR::AutomationList*);
void toggle (ARDOUR::Playlist*); void toggle (boost::shared_ptr<ARDOUR::Playlist>);
void toggle (const list<ARDOUR::Playlist*>&); void toggle (const list<boost::shared_ptr<ARDOUR::Playlist> >&);
void toggle (boost::shared_ptr<ARDOUR::Redirect>); void toggle (boost::shared_ptr<ARDOUR::Redirect>);
void add (TimeAxisView*); void add (TimeAxisView*);
@ -122,8 +122,8 @@ class Selection : public sigc::trackable
void add (std::vector<RegionView*>&); void add (std::vector<RegionView*>&);
long add (nframes_t, nframes_t); long add (nframes_t, nframes_t);
void add (ARDOUR::AutomationList*); void add (ARDOUR::AutomationList*);
void add (ARDOUR::Playlist*); void add (boost::shared_ptr<ARDOUR::Playlist>);
void add (const list<ARDOUR::Playlist*>&); void add (const list<boost::shared_ptr<ARDOUR::Playlist> >&);
void add (boost::shared_ptr<ARDOUR::Redirect>); void add (boost::shared_ptr<ARDOUR::Redirect>);
void remove (TimeAxisView*); void remove (TimeAxisView*);
@ -132,8 +132,8 @@ class Selection : public sigc::trackable
void remove (uint32_t selection_id); void remove (uint32_t selection_id);
void remove (nframes_t, nframes_t); void remove (nframes_t, nframes_t);
void remove (ARDOUR::AutomationList*); void remove (ARDOUR::AutomationList*);
void remove (ARDOUR::Playlist*); void remove (boost::shared_ptr<ARDOUR::Playlist>);
void remove (const list<ARDOUR::Playlist*>&); void remove (const list<boost::shared_ptr<ARDOUR::Playlist> >&);
void remove (boost::shared_ptr<ARDOUR::Redirect>); void remove (boost::shared_ptr<ARDOUR::Redirect>);
void replace (uint32_t time_index, nframes_t start, nframes_t end); void replace (uint32_t time_index, nframes_t start, nframes_t end);

View File

@ -168,7 +168,7 @@ class TimeAxisView : public virtual AxisView
virtual void step_height (bool bigger); virtual void step_height (bool bigger);
virtual ARDOUR::RouteGroup* edit_group() const { return 0; } 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 set_samples_per_unit (double);
virtual void show_selection (TimeSelection&); virtual void show_selection (TimeSelection&);

View File

@ -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_new_playlist ();
int use_copy_playlist (); int use_copy_playlist ();

View File

@ -42,8 +42,10 @@ class AudioPlaylist : public ARDOUR::Playlist
public: public:
AudioPlaylist (Session&, const XMLNode&, bool hidden = false); AudioPlaylist (Session&, const XMLNode&, bool hidden = false);
AudioPlaylist (Session&, string name, bool hidden = false); AudioPlaylist (Session&, string name, bool hidden = false);
AudioPlaylist (const AudioPlaylist&, string name, bool hidden = false); AudioPlaylist (boost::shared_ptr<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>, nframes_t start, nframes_t cnt, string name, bool hidden = false);
~AudioPlaylist (); /* public should use unref() */
void clear (bool with_signals=true); 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 check_dependents (boost::shared_ptr<Region> region, bool norefresh);
void remove_dependents (boost::shared_ptr<Region> region); void remove_dependents (boost::shared_ptr<Region> region);
protected:
~AudioPlaylist (); /* public should use unref() */
private: private:
Crossfades _crossfades; /* xfades currently in use */ Crossfades _crossfades; /* xfades currently in use */
Crossfades _pending_xfade_adds; Crossfades _pending_xfade_adds;

View File

@ -137,7 +137,7 @@ class AudioRegion : public Region
void resume_fade_in (); void resume_fade_in ();
void resume_fade_out (); void resume_fade_out ();
void set_playlist (Playlist *); void set_playlist (boost::weak_ptr<Playlist>);
private: private:
friend class RegionFactory; friend class RegionFactory;

View File

@ -64,12 +64,13 @@ class Crossfade : public PBD::StatefulDestructible
/* copy constructor to copy a crossfade with new regions. used (for example) /* 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>); Crossfade (const Crossfade &, boost::shared_ptr<ARDOUR::AudioRegion>, boost::shared_ptr<ARDOUR::AudioRegion>);
/* the usual XML constructor */ /* the usual XML constructor */
Crossfade (const ARDOUR::Playlist&, XMLNode&); Crossfade (const Playlist&, XMLNode&);
virtual ~Crossfade(); virtual ~Crossfade();
bool operator== (const ARDOUR::Crossfade&); bool operator== (const ARDOUR::Crossfade&);

View File

@ -104,9 +104,9 @@ class IO;
void set_speed (double); void set_speed (double);
void non_realtime_set_speed (); 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_new_playlist () = 0;
virtual int use_copy_playlist () = 0; virtual int use_copy_playlist () = 0;
@ -206,7 +206,7 @@ class IO;
virtual void playlist_changed (Change); virtual void playlist_changed (Change);
virtual void playlist_modified (); 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 finish_capture (bool rec_monitors_input) = 0;
virtual void transport_stopped (struct tm&, time_t, bool abort) = 0; virtual void transport_stopped (struct tm&, time_t, bool abort) = 0;
@ -246,7 +246,8 @@ class IO;
ARDOUR::Session& _session; ARDOUR::Session& _session;
ARDOUR::IO* _io; ARDOUR::IO* _io;
uint32_t _n_channels; uint32_t _n_channels;
Playlist* _playlist;
boost::shared_ptr<Playlist> _playlist;
mutable gint _record_enabled; mutable gint _record_enabled;
double _visible_speed; double _visible_speed;
@ -300,7 +301,6 @@ class IO;
sigc::connection ports_created_c; sigc::connection ports_created_c;
sigc::connection plmod_connection; sigc::connection plmod_connection;
sigc::connection plstate_connection;
sigc::connection plgone_connection; sigc::connection plgone_connection;
unsigned char _flags; unsigned char _flags;

View File

@ -23,6 +23,7 @@
#include <string> #include <string>
#include <list> #include <list>
#include <boost/shared_ptr.hpp>
#include <pbd/stateful.h> #include <pbd/stateful.h>
@ -35,12 +36,12 @@ class Playlist;
struct NamedSelection : public Stateful struct NamedSelection : public Stateful
{ {
NamedSelection (std::string, std::list<Playlist*>&); NamedSelection (std::string, std::list<boost::shared_ptr<Playlist> >&);
NamedSelection (Session&, const XMLNode&); NamedSelection (Session&, const XMLNode&);
virtual ~NamedSelection (); virtual ~NamedSelection ();
std::string name; std::string name;
std::list<Playlist*> playlists; std::list<boost::shared_ptr<Playlist> > playlists;
XMLNode& get_state (void); XMLNode& get_state (void);

View File

@ -26,6 +26,7 @@
#include <map> #include <map>
#include <list> #include <list>
#include <boost/shared_ptr.hpp> #include <boost/shared_ptr.hpp>
#include <boost/enable_shared_from_this.hpp>
#include <sys/stat.h> #include <sys/stat.h>
@ -46,21 +47,25 @@ namespace ARDOUR {
class Session; class Session;
class Region; class Region;
class Playlist : public PBD::StatefulDestructible { class Playlist : public PBD::StatefulDestructible, public boost::enable_shared_from_this<Playlist> {
public: public:
typedef list<boost::shared_ptr<Region> > RegionList; typedef list<boost::shared_ptr<Region> > RegionList;
Playlist (Session&, const XMLNode&, bool hidden = false); Playlist (Session&, const XMLNode&, bool hidden = false);
Playlist (Session&, string name, bool hidden = false); Playlist (Session&, string name, bool hidden = false);
Playlist (const Playlist&, string name, bool hidden = false); Playlist (boost::shared_ptr<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>, 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 clear (bool with_signals=true);
virtual void dump () const; virtual void dump () const;
void ref(); void use();
void unref(); void release();
uint32_t refcnt() const { return _refcnt; } bool used () const { return _refcnt != 0; }
std::string name() const { return _name; } std::string name() const { return _name; }
void set_name (std::string str); 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 duplicate (boost::shared_ptr<Region>, nframes_t position, float times);
void nudge_after (nframes_t start, nframes_t distance, bool forwards); void nudge_after (nframes_t start, nframes_t distance, bool forwards);
Playlist* cut (list<AudioRange>&, bool result_is_hidden = true); boost::shared_ptr<Playlist> cut (list<AudioRange>&, bool result_is_hidden = true);
Playlist* copy (list<AudioRange>&, bool result_is_hidden = true); boost::shared_ptr<Playlist> copy (list<AudioRange>&, bool result_is_hidden = true);
int paste (Playlist&, nframes_t position, float times); int paste (boost::shared_ptr<Playlist>, nframes_t position, float times);
RegionList* regions_at (nframes_t frame); RegionList* regions_at (nframes_t frame);
RegionList* regions_touched (nframes_t start, nframes_t end); RegionList* regions_touched (nframes_t start, nframes_t end);
@ -106,14 +111,11 @@ class Playlist : public PBD::StatefulDestructible {
int set_state (const XMLNode&); int set_state (const XMLNode&);
XMLNode& get_template (); XMLNode& get_template ();
sigc::signal<void,Playlist*,bool> InUse; sigc::signal<void,bool> InUse;
sigc::signal<void> Modified; sigc::signal<void> Modified;
sigc::signal<void> NameChanged; sigc::signal<void> NameChanged;
sigc::signal<void> LengthChanged; sigc::signal<void> LengthChanged;
sigc::signal<void> LayeringChanged; sigc::signal<void> LayeringChanged;
sigc::signal<void> StatePushed;
static sigc::signal<void,Playlist*> PlaylistCreated;
static string bump_name (string old_name, Session&); static string bump_name (string old_name, Session&);
static string bump_name_once (string old_name); static string bump_name_once (string old_name);
@ -139,7 +141,6 @@ class Playlist : public PBD::StatefulDestructible {
protected: protected:
friend class Session; friend class Session;
virtual ~Playlist (); /* members of the public use unref() */
protected: protected:
struct RegionLock { struct RegionLock {
@ -240,26 +241,23 @@ class Playlist : public PBD::StatefulDestructible {
boost::shared_ptr<Region> region_by_id (PBD::ID); boost::shared_ptr<Region> region_by_id (PBD::ID);
void add_region_internal (boost::shared_ptr<Region>, nframes_t position, bool delay_sort = false); void add_region_internal (boost::shared_ptr<Region>, nframes_t position);
int remove_region_internal (boost::shared_ptr<Region>, bool delay_sort = false); int remove_region_internal (boost::shared_ptr<Region>);
RegionList *find_regions_at (nframes_t frame); RegionList *find_regions_at (nframes_t frame);
void copy_regions (RegionList&) const; void copy_regions (RegionList&) const;
void partition_internal (nframes_t start, nframes_t end, bool cutting, RegionList& thawlist); void partition_internal (nframes_t start, nframes_t end, bool cutting, RegionList& thawlist);
nframes_t _get_maximum_extent() const; nframes_t _get_maximum_extent() const;
Playlist* cut_copy (Playlist* (Playlist::*pmf)(nframes_t, nframes_t, bool), boost::shared_ptr<Playlist> cut_copy (boost::shared_ptr<Playlist> (Playlist::*pmf)(nframes_t, nframes_t, bool),
list<AudioRange>& ranges, bool result_is_hidden); list<AudioRange>& ranges, bool result_is_hidden);
Playlist *cut (nframes_t start, nframes_t cnt, bool result_is_hidden); boost::shared_ptr<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> 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); int move_region_to_layer (layer_t, boost::shared_ptr<Region> r, int dir);
void relayer (); 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_parent (Playlist*);
void unset_freeze_child (Playlist*); void unset_freeze_child (Playlist*);

View File

@ -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; } virtual uint32_t read_data_count() const { return _read_data_count; }
ARDOUR::Playlist* playlist() const { return _playlist; } boost::shared_ptr<ARDOUR::Playlist> playlist() const { return _playlist.lock(); }
virtual void set_playlist (boost::weak_ptr<ARDOUR::Playlist>);
virtual void set_playlist (ARDOUR::Playlist*);
/* serialization */ /* serialization */
@ -217,7 +216,7 @@ class Region : public PBD::StatefulDestructible, public boost::enable_shared_fro
mutable RegionEditState _first_edit; mutable RegionEditState _first_edit;
int _frozen; int _frozen;
Glib::Mutex lock; Glib::Mutex lock;
ARDOUR::Playlist* _playlist; boost::weak_ptr<ARDOUR::Playlist> _playlist;
mutable uint32_t _read_data_count; // modified in read() mutable uint32_t _read_data_count; // modified in read()
Change pending_changed; Change pending_changed;
uint64_t _last_layer_op; // timestamp uint64_t _last_layer_op; // timestamp

View File

@ -604,8 +604,7 @@ class Session : public PBD::StatefulDestructible
this playlist. 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 /* handlers should return !0 for use pending state, 0 for
ignore it. ignore it.
@ -613,24 +612,21 @@ class Session : public PBD::StatefulDestructible
static sigc::signal<int> AskAboutPendingState; 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<AudioFileSource> create_audio_source_for_session (ARDOUR::AudioDiskstream&, uint32_t which_channel, bool destructive);
boost::shared_ptr<Source> source_by_id (const PBD::ID&); boost::shared_ptr<Source> source_by_id (const PBD::ID&);
/* playlist management */ /* playlist management */
Playlist* playlist_by_name (string name); boost::shared_ptr<Playlist> playlist_by_name (string name);
void add_playlist (Playlist *); void add_playlist (boost::shared_ptr<Playlist>);
sigc::signal<void,Playlist*> PlaylistAdded; sigc::signal<void,boost::shared_ptr<Playlist> > PlaylistAdded;
sigc::signal<void,Playlist*> PlaylistRemoved; sigc::signal<void,boost::shared_ptr<Playlist> > PlaylistRemoved;
uint32_t n_playlists() const; uint32_t n_playlists() const;
template<class T> void foreach_playlist (T *obj, void (T::*func)(Playlist *)); template<class T> void foreach_playlist (T *obj, void (T::*func)(boost::shared_ptr<Playlist>));
void get_playlists (std::vector<Playlist*>&); void get_playlists (std::vector<boost::shared_ptr<Playlist> >&);
/* named selections */ /* named selections */
@ -1464,19 +1460,19 @@ class Session : public PBD::StatefulDestructible
/* PLAYLISTS */ /* PLAYLISTS */
mutable Glib::Mutex playlist_lock; mutable Glib::Mutex playlist_lock;
typedef set<Playlist *> PlaylistList; typedef set<boost::shared_ptr<Playlist> > PlaylistList;
PlaylistList playlists; PlaylistList playlists;
PlaylistList unused_playlists; PlaylistList unused_playlists;
int load_playlists (const XMLNode&); int load_playlists (const XMLNode&);
int load_unused_playlists (const XMLNode&); int load_unused_playlists (const XMLNode&);
void remove_playlist (Playlist *); void remove_playlist (boost::weak_ptr<Playlist>);
void track_playlist (Playlist *, bool); void track_playlist (bool, boost::weak_ptr<Playlist>);
Playlist *playlist_factory (string name); boost::shared_ptr<Playlist> playlist_factory (string name);
Playlist *XMLPlaylistFactory (const XMLNode&); boost::shared_ptr<Playlist> XMLPlaylistFactory (const XMLNode&);
void playlist_length_changed (Playlist *); void playlist_length_changed ();
void diskstream_playlist_changed (boost::shared_ptr<Diskstream>); void diskstream_playlist_changed (boost::shared_ptr<Diskstream>);
/* NAMED SELECTIONS */ /* NAMED SELECTIONS */

View File

@ -27,7 +27,7 @@
namespace ARDOUR { namespace ARDOUR {
template<class T> void 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); Glib::Mutex::Lock lm (playlist_lock);
for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); i++) { for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); i++) {

View File

@ -54,8 +54,8 @@ class Source : public PBD::StatefulDestructible
void use () { _in_use++; } void use () { _in_use++; }
void disuse () { if (_in_use) { _in_use--; } } void disuse () { if (_in_use) { _in_use--; } }
void add_playlist (ARDOUR::Playlist*); void add_playlist (boost::shared_ptr<ARDOUR::Playlist>);
void remove_playlist (ARDOUR::Playlist*); void remove_playlist (boost::weak_ptr<ARDOUR::Playlist>);
uint32_t used() const; uint32_t used() const;
@ -64,7 +64,7 @@ class Source : public PBD::StatefulDestructible
string _name; string _name;
time_t _timestamp; time_t _timestamp;
std::set<ARDOUR::Playlist*> _playlists; std::set<boost::shared_ptr<ARDOUR::Playlist> > _playlists;
private: private:
uint32_t _in_use; uint32_t _in_use;

View File

@ -120,13 +120,12 @@ class Track : public Route
struct FreezeRecord { struct FreezeRecord {
FreezeRecord() FreezeRecord()
: playlist(0) : have_mementos(false)
, have_mementos(false)
{} {}
~FreezeRecord(); ~FreezeRecord();
Playlist* playlist; boost::shared_ptr<Playlist> playlist;
vector<FreezeRecordInsertInfo*> insert_info; vector<FreezeRecordInsertInfo*> insert_info;
bool have_mementos; bool have_mementos;
FreezeState state; FreezeState state;

View File

@ -46,6 +46,7 @@
#include <ardour/send.h> #include <ardour/send.h>
#include <ardour/region_factory.h> #include <ardour/region_factory.h>
#include <ardour/audioplaylist.h> #include <ardour/audioplaylist.h>
#include <ardour/playlist_factory.h>
#include <ardour/cycle_timer.h> #include <ardour/cycle_timer.h>
#include <ardour/audioregion.h> #include <ardour/audioregion.h>
#include <ardour/source_factory.h> #include <ardour/source_factory.h>
@ -286,15 +287,13 @@ AudioDiskstream::get_input_sources ()
int int
AudioDiskstream::find_and_use_playlist (const string& name) AudioDiskstream::find_and_use_playlist (const string& name)
{ {
Playlist* pl; boost::shared_ptr<AudioPlaylist> playlist;
AudioPlaylist* playlist;
if ((pl = _session.playlist_by_name (name)) == 0) { if ((playlist = boost::dynamic_pointer_cast<AudioPlaylist> (_session.playlist_by_name (name))) == 0) {
playlist = new AudioPlaylist(_session, name); playlist = boost::dynamic_pointer_cast<AudioPlaylist> (PlaylistFactory::create (_session, name));
pl = playlist;
} }
if ((playlist = dynamic_cast<AudioPlaylist*> (pl)) == 0) { if (!playlist) {
error << string_compose(_("AudioDiskstream: Playlist \"%1\" isn't an audio playlist"), name) << endmsg; error << string_compose(_("AudioDiskstream: Playlist \"%1\" isn't an audio playlist"), name) << endmsg;
return -1; return -1;
} }
@ -303,9 +302,9 @@ AudioDiskstream::find_and_use_playlist (const string& name)
} }
int 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); Diskstream::use_playlist(playlist);
@ -316,7 +315,7 @@ int
AudioDiskstream::use_new_playlist () AudioDiskstream::use_new_playlist ()
{ {
string newname; string newname;
AudioPlaylist* playlist; boost::shared_ptr<AudioPlaylist> playlist;
if (!in_set_state && destructive()) { if (!in_set_state && destructive()) {
return 0; return 0;
@ -328,9 +327,11 @@ AudioDiskstream::use_new_playlist ()
newname = Playlist::bump_name (_name, _session); 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()); playlist->set_orig_diskstream_id (id());
return use_playlist (playlist); return use_playlist (playlist);
} else { } else {
return -1; return -1;
} }
@ -351,11 +352,11 @@ AudioDiskstream::use_copy_playlist ()
} }
string newname; string newname;
AudioPlaylist* playlist; boost::shared_ptr<AudioPlaylist> playlist;
newname = Playlist::bump_name (_playlist->name(), _session); 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()); playlist->set_orig_diskstream_id (id());
return use_playlist (playlist); return use_playlist (playlist);
} else { } else {

View File

@ -45,39 +45,31 @@ AudioPlaylist::AudioPlaylist (Session& session, const XMLNode& node, bool hidden
in_set_state++; in_set_state++;
set_state (node); set_state (node);
in_set_state--; in_set_state--;
if (!hidden) {
PlaylistCreated (this); /* EMIT SIGNAL */
}
} }
AudioPlaylist::AudioPlaylist (Session& session, string name, bool hidden) AudioPlaylist::AudioPlaylist (Session& session, string name, bool hidden)
: Playlist (session, name, 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) : 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(); 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); 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 // 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) { if ((*xfades)->in() == ar) {
// We found one! Now copy it! // 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(); 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); 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_o++;
in_n++; 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) : Playlist (other, start, cnt, name, hidden)
{ {
/* this constructor does NOT notify others (session) */ /* this constructor does NOT notify others (session) */
@ -658,7 +646,7 @@ AudioPlaylist::destroy_region (boost::shared_ptr<Region> region)
x = xtmp; x = xtmp;
} }
region->set_playlist (0); region->set_playlist (boost::shared_ptr<Playlist>());
} }
for (c = _crossfades.begin(); c != _crossfades.end(); ) { for (c = _crossfades.begin(); c != _crossfades.end(); ) {

View File

@ -32,6 +32,7 @@
#include <ardour/route_group_specialized.h> #include <ardour/route_group_specialized.h>
#include <ardour/insert.h> #include <ardour/insert.h>
#include <ardour/audioplaylist.h> #include <ardour/audioplaylist.h>
#include <ardour/playlist_factory.h>
#include <ardour/panner.h> #include <ardour/panner.h>
#include <ardour/utils.h> #include <ardour/utils.h>
@ -395,11 +396,11 @@ AudioTrack::set_state_part_two ()
_freeze_record.insert_info.clear (); _freeze_record.insert_info.clear ();
if ((prop = fnode->property (X_("playlist"))) != 0) { 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) { if (pl) {
_freeze_record.playlist = dynamic_cast<AudioPlaylist*> (pl); _freeze_record.playlist = boost::dynamic_pointer_cast<AudioPlaylist> (pl);
} else { } else {
_freeze_record.playlist = 0; _freeze_record.playlist.reset ();
_freeze_record.state = NoFreeze; _freeze_record.state = NoFreeze;
return; return;
} }
@ -685,8 +686,7 @@ AudioTrack::export_stuff (vector<Sample*>& buffers, uint32_t nbufs, nframes_t st
Glib::RWLock::ReaderLock rlock (redirect_lock); Glib::RWLock::ReaderLock rlock (redirect_lock);
// FIXME boost::shared_ptr<AudioPlaylist> apl = boost::dynamic_pointer_cast<AudioPlaylist>(diskstream->playlist());
AudioPlaylist* const apl = dynamic_cast<AudioPlaylist*>(diskstream->playlist());
assert(apl); assert(apl);
if (apl->read (buffers[0], mix_buffer, gain_buffer, start, nframes) != nframes) { 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; vector<boost::shared_ptr<AudioSource> > srcs;
string new_playlist_name; string new_playlist_name;
Playlist* new_playlist; boost::shared_ptr<Playlist> new_playlist;
string dir; string dir;
string region_name; string region_name;
boost::shared_ptr<AudioDiskstream> diskstream = audio_diskstream(); 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; 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; region_name = new_playlist_name;
/* create a new region from all filesources, keep it private */ /* create a new region from all filesources, keep it private */
@ -868,7 +868,7 @@ AudioTrack::freeze (InterThreadInfo& itt)
new_playlist->set_frozen (true); new_playlist->set_frozen (true);
region->set_locked (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); diskstream->set_record_enabled (false);
_freeze_record.state = Frozen; _freeze_record.state = Frozen;
@ -900,7 +900,7 @@ AudioTrack::unfreeze ()
} }
} }
_freeze_record.playlist = 0; _freeze_record.playlist.reset ();
} }
_freeze_record.state = UnFrozen; _freeze_record.state = UnFrozen;

View File

@ -306,9 +306,11 @@ AudioRegion::AudioRegion (SourceList& srcs, const XMLNode& node)
AudioRegion::~AudioRegion () AudioRegion::~AudioRegion ()
{ {
if (_playlist) { boost::shared_ptr<Playlist> pl (playlist());
if (pl) {
for (SourceList::const_iterator i = sources.begin(); i != sources.end(); ++i) { 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> boost::shared_ptr<Region>
AudioRegion::get_parent() const AudioRegion::get_parent() const
{ {
if (_playlist) { boost::shared_ptr<Playlist> pl (playlist());
if (pl) {
boost::shared_ptr<AudioRegion> ar; boost::shared_ptr<AudioRegion> ar;
boost::shared_ptr<AudioRegion const> grrr2 = boost::dynamic_pointer_cast<AudioRegion const> (shared_from_this()); 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); return boost::static_pointer_cast<Region> (ar);
} }
} }
@ -1174,12 +1178,14 @@ AudioRegion::get_parent() const
void void
AudioRegion::set_scale_amplitude (gain_t g) AudioRegion::set_scale_amplitude (gain_t g)
{ {
boost::shared_ptr<Playlist> pl (playlist());
_scale_amplitude = g; _scale_amplitude = g;
/* tell the diskstream we're in */ /* tell the diskstream we're in */
if (_playlist) { if (pl) {
_playlist->Modified(); pl->Modified();
} }
/* tell everybody else */ /* tell everybody else */
@ -1246,8 +1252,10 @@ AudioRegion::normalize_to (float target_dB)
/* tell the diskstream we're in */ /* tell the diskstream we're in */
if (_playlist) { boost::shared_ptr<Playlist> pl (playlist());
_playlist->Modified();
if (pl) {
pl->Modified();
} }
/* tell everybody else */ /* tell everybody else */
@ -1330,31 +1338,32 @@ AudioRegion::source_offset_changed ()
} }
void 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; return;
} }
Playlist* old_playlist = _playlist; Region::set_playlist (wpl);
Region::set_playlist (pl);
if (pl) { if (pl) {
if (old_playlist) { if (old_playlist) {
for (SourceList::const_iterator i = sources.begin(); i != sources.end(); ++i) { for (SourceList::const_iterator i = sources.begin(); i != sources.end(); ++i) {
(*i)->remove_playlist (old_playlist); (*i)->remove_playlist (_playlist);
(*i)->add_playlist (_playlist); (*i)->add_playlist (pl);
} }
} else { } else {
for (SourceList::const_iterator i = sources.begin(); i != sources.end(); ++i) { for (SourceList::const_iterator i = sources.begin(); i != sources.end(); ++i) {
(*i)->add_playlist (_playlist); (*i)->add_playlist (pl);
} }
} }
} else { } else {
if (old_playlist) { if (old_playlist) {
for (SourceList::const_iterator i = sources.begin(); i != sources.end(); ++i) { for (SourceList::const_iterator i = sources.begin(); i != sources.end(); ++i) {
(*i)->remove_playlist (old_playlist); (*i)->remove_playlist (_playlist);
} }
} }
} }

View File

@ -75,7 +75,7 @@ AudioPlaylist&
Auditioner::prepare_playlist () Auditioner::prepare_playlist ()
{ {
// FIXME auditioner is still audio-only // 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); assert(apl);
apl->clear (); apl->clear ();

View File

@ -71,14 +71,12 @@ sigc::signal<void> Diskstream::DiskUnderrun;
Diskstream::Diskstream (Session &sess, const string &name, Flag flag) Diskstream::Diskstream (Session &sess, const string &name, Flag flag)
: _name (name) : _name (name)
, _session (sess) , _session (sess)
, _playlist(NULL)
{ {
init (flag); init (flag);
} }
Diskstream::Diskstream (Session& sess, const XMLNode& node) Diskstream::Diskstream (Session& sess, const XMLNode& node)
: _session (sess) : _session (sess)
, _playlist(NULL)
{ {
init (Recordable); init (Recordable);
} }
@ -133,7 +131,7 @@ Diskstream::~Diskstream ()
//Glib::Mutex::Lock lm (state_lock); //Glib::Mutex::Lock lm (state_lock);
if (_playlist) if (_playlist)
_playlist->unref (); _playlist->release ();
} }
void void
@ -307,7 +305,7 @@ Diskstream::set_speed (double sp)
} }
int int
Diskstream::use_playlist (Playlist* playlist) Diskstream::use_playlist (boost::shared_ptr<Playlist> playlist)
{ {
{ {
Glib::Mutex::Lock lm (state_lock); Glib::Mutex::Lock lm (state_lock);
@ -316,23 +314,22 @@ Diskstream::use_playlist (Playlist* playlist)
return 0; return 0;
} }
plstate_connection.disconnect();
plmod_connection.disconnect (); plmod_connection.disconnect ();
plgone_connection.disconnect (); plgone_connection.disconnect ();
if (_playlist) { if (_playlist) {
_playlist->unref(); _playlist->release();
} }
_playlist = playlist; _playlist = playlist;
_playlist->ref(); _playlist->use();
if (!in_set_state && recordable()) { if (!in_set_state && recordable()) {
reset_write_sources (false); reset_write_sources (false);
} }
plmod_connection = _playlist->Modified.connect (mem_fun (*this, &Diskstream::playlist_modified)); 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) { if (!overwrite_queued) {
@ -362,14 +359,21 @@ Diskstream::playlist_modified ()
} }
void void
Diskstream::playlist_deleted (Playlist* pl) Diskstream::playlist_deleted (boost::weak_ptr<Playlist> wpl)
{ {
/* this catches an ordering issue with session destruction. playlists boost::shared_ptr<Playlist> pl (wpl.lock());
are destroyed before diskstreams. we have to invalidate any handles
we have to the playlist.
*/
_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 int

View File

@ -111,14 +111,14 @@ Session::import_audiofile (import_status& status)
do { do {
if (info.channels == 2) { if (info.channels == 2) {
if (n == 0) { 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 { } 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) { } 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 { } 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) { if (::access (buf, F_OK) == 0) {

View File

@ -33,12 +33,14 @@ using namespace PBD;
sigc::signal<void,NamedSelection*> NamedSelection::NamedSelectionCreated; 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) : name (n)
{ {
playlists = l; playlists = l;
for (list<Playlist*>::iterator i = playlists.begin(); i != playlists.end(); ++i) { for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
(*i)->ref(); (*i)->use();
} }
NamedSelectionCreated (this); NamedSelectionCreated (this);
} }
@ -65,13 +67,13 @@ NamedSelection::NamedSelection (Session& session, const XMLNode& node)
const XMLNode* plnode; const XMLNode* plnode;
string playlist_name; string playlist_name;
Playlist* playlist; boost::shared_ptr<Playlist> playlist;
plnode = *niter; plnode = *niter;
if ((property = plnode->property ("name")) != 0) { if ((property = plnode->property ("name")) != 0) {
if ((playlist = session.playlist_by_name (property->value())) != 0) { if ((playlist = session.playlist_by_name (property->value())) != 0) {
playlist->ref(); playlist->use();
playlists.push_back (playlist); playlists.push_back (playlist);
} else { } else {
warning << string_compose (_("Chunk %1 uses an unknown playlist \"%2\""), name, property->value()) << endmsg; 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 () NamedSelection::~NamedSelection ()
{ {
for (list<Playlist*>::iterator i = playlists.begin(); i != playlists.end(); ++i) { for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
(*i)->unref(); (*i)->release();
} }
} }
@ -107,7 +109,7 @@ NamedSelection::get_state ()
root->add_property ("name", name); root->add_property ("name", name);
child = root->add_child ("Playlists"); 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"); XMLNode* plnode = new XMLNode ("Playlist");
plnode->add_property ("name", (*i)->name()); plnode->add_property ("name", (*i)->name());

View File

@ -36,6 +36,7 @@
#include <ardour/session.h> #include <ardour/session.h>
#include <ardour/region.h> #include <ardour/region.h>
#include <ardour/region_factory.h> #include <ardour/region_factory.h>
#include <ardour/playlist_factory.h>
#include "i18n.h" #include "i18n.h"
@ -43,14 +44,12 @@ using namespace std;
using namespace ARDOUR; using namespace ARDOUR;
using namespace PBD; using namespace PBD;
sigc::signal<void,Playlist*> Playlist::PlaylistCreated;
struct ShowMeTheList { 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 () { ~ShowMeTheList () {
cerr << ">>>>" << name << endl; playlist->dump(); cerr << "<<<<" << name << endl << endl; cerr << ">>>>" << name << endl; playlist->dump(); cerr << "<<<<" << name << endl << endl;
}; };
Playlist *playlist; boost::shared_ptr<Playlist> playlist;
string name; string name;
}; };
@ -86,43 +85,42 @@ Playlist::Playlist (Session& sess, const XMLNode& node, bool hide)
init (hide); init (hide);
_name = "unnamed"; /* reset by set_state */ _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) Playlist::Playlist (boost::shared_ptr<const Playlist> other, string namestr, bool hide)
: _name (namestr), _session (other._session), _orig_diskstream_id(other._orig_diskstream_id) : _name (namestr), _session (other->_session), _orig_diskstream_id(other->_orig_diskstream_id)
{ {
init (hide); init (hide);
RegionList tmp; RegionList tmp;
other.copy_regions (tmp); other->copy_regions (tmp);
in_set_state++; in_set_state++;
for (list<boost::shared_ptr<Region> >::iterator x = tmp.begin(); x != tmp.end(); ++x) { 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--; in_set_state--;
_splicing = other._splicing; _splicing = other->_splicing;
_nudging = other._nudging; _nudging = other->_nudging;
_edit_mode = other._edit_mode; _edit_mode = other->_edit_mode;
in_set_state = 0; in_set_state = 0;
in_flush = false; in_flush = false;
in_partition = false; in_partition = false;
subcnt = 0; subcnt = 0;
_read_data_count = 0; _read_data_count = 0;
_frozen = other._frozen; _frozen = other->_frozen;
layer_op_counter = other.layer_op_counter;
freeze_length = other.freeze_length;
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) 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) : _name (str), _session (other->_session), _orig_diskstream_id(other->_orig_diskstream_id)
{ {
RegionLock rlock2 (&((Playlist&)other)); RegionLock rlock2 (&((Playlist&)other));
@ -130,7 +128,7 @@ Playlist::Playlist (const Playlist& other, nframes_t start, nframes_t cnt, strin
init (hide); 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> region;
boost::shared_ptr<Region> new_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()); 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) */ /* this constructor does NOT notify others (session) */
} }
void void
Playlist::ref () Playlist::use ()
{ {
++_refcnt; ++_refcnt;
InUse (this, true); /* EMIT SIGNAL */ InUse (true); /* EMIT SIGNAL */
} }
void void
Playlist::unref () Playlist::release ()
{ {
if (_refcnt > 0) { if (_refcnt > 0) {
_refcnt--; _refcnt--;
} }
if (_refcnt == 0) { if (_refcnt == 0) {
InUse (this, false); /* EMIT SIGNAL */ InUse (false); /* EMIT SIGNAL */
if (_hidden) {
/* nobody knows we exist */
delete this;
}
} }
} }
@ -259,7 +253,7 @@ Playlist::~Playlist ()
RegionLock rl (this); RegionLock rl (this);
for (set<boost::shared_ptr<Region> >::iterator i = all_regions.begin(); i != all_regions.end(); ++i) { 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; nframes_t pos = position;
if (itimes >= 1) { if (itimes >= 1) {
add_region_internal (region, pos, true); add_region_internal (region, pos);
pos += region->length(); pos += region->length();
--itimes; --itimes;
} }
@ -477,7 +471,7 @@ Playlist::add_region (boost::shared_ptr<Region> region, nframes_t position, floa
for (int i = 0; i < itimes; ++i) { for (int i = 0; i < itimes; ++i) {
boost::shared_ptr<Region> copy = RegionFactory::create (region); boost::shared_ptr<Region> copy = RegionFactory::create (region);
add_region_internal (copy, pos, true); add_region_internal (copy, pos);
pos += region->length(); pos += region->length();
} }
@ -486,12 +480,24 @@ Playlist::add_region (boost::shared_ptr<Region> region, nframes_t position, floa
string name; string name;
_session.region_name (name, region->name(), false); _session.region_name (name, region->name(), false);
boost::shared_ptr<Region> sub = RegionFactory::create (region, 0, length, name, region->layer(), region->flags()); 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 void
Playlist::add_region_internal (boost::shared_ptr<Region> region, nframes_t position, bool delay_sort) 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)
{ {
RegionSortByPosition cmp; RegionSortByPosition cmp;
nframes_t old_length = 0; 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(); 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); region->set_position (position, this);
timestamp_layer_op (region); timestamp_layer_op (region);
@ -553,7 +563,7 @@ Playlist::remove_region (boost::shared_ptr<Region> region)
} }
int 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; RegionList::iterator i;
nframes_t old_length = 0; 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); _session.region_name (new_name, current->name(), false);
region = RegionFactory::create (current, pos2 - pos1, pos3 - pos2, new_name, region = RegionFactory::create (current, pos2 - pos1, pos3 - pos2, new_name,
regions.size(), Region::Flag(current->flags()|Region::Automatic|Region::LeftOfSplit|Region::RightOfSplit)); 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); 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, region = RegionFactory::create (current, pos3 - pos1, pos4 - pos3, new_name,
regions.size(), Region::Flag(current->flags()|Region::Automatic|Region::RightOfSplit)); 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); new_regions.push_back (region);
/* "front" ***** */ /* "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); _session.region_name (new_name, current->name(), false);
region = RegionFactory::create (current, pos2 - pos1, pos4 - pos2, new_name, (layer_t) regions.size(), region = RegionFactory::create (current, pos2 - pos1, pos4 - pos2, new_name, (layer_t) regions.size(),
Region::Flag(current->flags()|Region::Automatic|Region::LeftOfSplit)); Region::Flag(current->flags()|Region::Automatic|Region::LeftOfSplit));
add_region_internal (region, start, true); add_region_internal (region, start);
new_regions.push_back (region); 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); _session.region_name (new_name, current->name(), false);
region = RegionFactory::create (current, 0, pos3 - pos1, new_name, region = RegionFactory::create (current, 0, pos3 - pos1, new_name,
regions.size(), Region::Flag(current->flags()|Region::Automatic|Region::RightOfSplit)); 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); new_regions.push_back (region);
} }
@ -802,20 +812,19 @@ Playlist::partition_internal (nframes_t start, nframes_t end, bool cutting, Regi
} }
} }
Playlist* boost::shared_ptr<Playlist>
Playlist::cut_copy (Playlist* (Playlist::*pmf)(nframes_t, nframes_t,bool), list<AudioRange>& ranges, bool result_is_hidden) Playlist::cut_copy (boost::shared_ptr<Playlist> (Playlist::*pmf)(nframes_t, nframes_t,bool), list<AudioRange>& ranges, bool result_is_hidden)
{ {
Playlist* ret; boost::shared_ptr<Playlist> ret;
Playlist* pl; boost::shared_ptr<Playlist> pl;
nframes_t start; nframes_t start;
if (ranges.empty()) { if (ranges.empty()) {
return 0; return boost::shared_ptr<Playlist>();
} }
start = ranges.front().start; start = ranges.front().start;
for (list<AudioRange>::iterator i = ranges.begin(); i != ranges.end(); ++i) { for (list<AudioRange>::iterator i = ranges.begin(); i != ranges.end(); ++i) {
pl = (this->*pmf)((*i).start, (*i).length(), result_is_hidden); 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. chopped.
*/ */
ret->paste (*pl, (*i).start - start, 1.0f); ret->paste (pl, (*i).start - start, 1.0f);
delete pl;
} }
} }
if (ret) {
/* manually notify session of new playlist here
because the playlists were constructed without notifying
*/
PlaylistCreated (ret);
}
return ret; return ret;
} }
Playlist* boost::shared_ptr<Playlist>
Playlist::cut (list<AudioRange>& ranges, bool result_is_hidden) 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); return cut_copy (pmf, ranges, result_is_hidden);
} }
Playlist* boost::shared_ptr<Playlist>
Playlist::copy (list<AudioRange>& ranges, bool result_is_hidden) 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); 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::cut (nframes_t start, nframes_t cnt, bool result_is_hidden)
{ {
Playlist *the_copy; boost::shared_ptr<Playlist> the_copy;
RegionList thawlist; RegionList thawlist;
char buf[32]; char buf[32];
@ -870,8 +871,8 @@ Playlist::cut (nframes_t start, nframes_t cnt, bool result_is_hidden)
new_name += '.'; new_name += '.';
new_name += buf; new_name += buf;
if ((the_copy = copyPlaylist (*this, start, cnt, new_name, result_is_hidden)) == 0) { if ((the_copy = PlaylistFactory::create (shared_from_this(), start, cnt, new_name, result_is_hidden)) == 0) {
return 0; return boost::shared_ptr<Playlist>();
} }
partition_internal (start, start+cnt-1, true, thawlist); 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; return the_copy;
} }
Playlist * boost::shared_ptr<Playlist>
Playlist::copy (nframes_t start, nframes_t cnt, bool result_is_hidden) Playlist::copy (nframes_t start, nframes_t cnt, bool result_is_hidden)
{ {
char buf[32]; char buf[32];
@ -895,28 +896,28 @@ Playlist::copy (nframes_t start, nframes_t cnt, bool result_is_hidden)
new_name += buf; new_name += buf;
cnt = min (_get_maximum_extent() - start, cnt); 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 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); times = fabs (times);
nframes_t old_length; nframes_t old_length;
{ {
RegionLock rl1 (this); RegionLock rl1 (this);
RegionLock rl2 (&other); RegionLock rl2 (other.get());
old_length = _get_maximum_extent(); old_length = _get_maximum_extent();
int itimes = (int) floor (times); int itimes = (int) floor (times);
nframes_t pos = position; nframes_t pos = position;
nframes_t shift = other._get_maximum_extent(); nframes_t shift = other->_get_maximum_extent();
layer_t top_layer = regions.size(); layer_t top_layer = regions.size();
while (itimes--) { 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); boost::shared_ptr<Region> copy_of_region = RegionFactory::create (*i);
/* put these new regions on top of all existing ones, but preserve /* 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--) { while (itimes--) {
boost::shared_ptr<Region> copy = RegionFactory::create (region); boost::shared_ptr<Region> copy = RegionFactory::create (region);
add_region_internal (copy, pos, true); add_region_internal (copy, pos);
pos += region->length(); pos += region->length();
} }
@ -964,7 +965,7 @@ Playlist::duplicate (boost::shared_ptr<Region> region, nframes_t position, float
string name; string name;
_session.region_name (name, region->name(), false); _session.region_name (name, region->name(), false);
boost::shared_ptr<Region> sub = RegionFactory::create (region, 0, length, name, region->layer(), region->flags()); 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); _session.region_name (after_name, region->name(), false);
right = RegionFactory::create (region, before, after, after_name, region->layer(), Region::Flag (region->flags()|Region::RightOfSplit)); 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); add_region_internal (right, region->position() + before);
uint64_t orig_layer_op = region->last_layer_op(); 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); finalize_split_region (region, left, right);
if (remove_region_internal (region, true)) { if (remove_region_internal (region)) {
return; return;
} }
} }

View File

@ -22,24 +22,75 @@
#include <ardour/playlist.h> #include <ardour/playlist.h>
#include <ardour/audioplaylist.h> #include <ardour/audioplaylist.h>
#include <ardour/playlist_factory.h>
#include "i18n.h" #include "i18n.h"
using namespace ARDOUR; using namespace ARDOUR;
using namespace PBD; using namespace PBD;
Playlist* sigc::signal<void,boost::shared_ptr<Playlist> > PlaylistFactory::PlaylistCreated;
Playlist::copyPlaylist (const Playlist& playlist, nframes_t start, nframes_t length,
string name, bool result_is_hidden)
{
const AudioPlaylist* apl;
if ((apl = dynamic_cast<const AudioPlaylist*> (&playlist)) != 0) { boost::shared_ptr<Playlist>
return new AudioPlaylist (*apl, start, length, name, result_is_hidden); PlaylistFactory::create (Session& s, const XMLNode& node, bool hidden)
} else { {
fatal << _("programming error: Playlist::copyPlaylist called with unknown Playlist type") boost::shared_ptr<Playlist> pl;
<< endmsg;
/*NOTREACHED*/ pl = boost::shared_ptr<Playlist> (new AudioPlaylist (s, node, hidden));
return 0;
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)
{
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;
} }

View File

@ -54,7 +54,6 @@ Region::Region (nframes_t start, nframes_t length, const string& name, layer_t l
/* basic Region constructor */ /* basic Region constructor */
_flags = flags; _flags = flags;
_playlist = 0;
_read_data_count = 0; _read_data_count = 0;
_frozen = 0; _frozen = 0;
pending_changed = Change (0); pending_changed = Change (0);
@ -76,7 +75,6 @@ Region::Region (boost::shared_ptr<const Region> other, nframes_t offset, nframes
_frozen = 0; _frozen = 0;
pending_changed = Change (0); pending_changed = Change (0);
_playlist = 0;
_read_data_count = 0; _read_data_count = 0;
_start = other->_start + offset; _start = other->_start + offset;
@ -100,7 +98,6 @@ Region::Region (boost::shared_ptr<const Region> other)
_frozen = 0; _frozen = 0;
pending_changed = Change (0); pending_changed = Change (0);
_playlist = 0;
_read_data_count = 0; _read_data_count = 0;
_first_edit = EditChangesID; _first_edit = EditChangesID;
@ -126,7 +123,6 @@ Region::Region (const XMLNode& node)
{ {
_frozen = 0; _frozen = 0;
pending_changed = Change (0); pending_changed = Change (0);
_playlist = 0;
_read_data_count = 0; _read_data_count = 0;
_start = 0; _start = 0;
_sync_position = _start; _sync_position = _start;
@ -148,7 +144,7 @@ Region::~Region ()
} }
void void
Region::set_playlist (Playlist* pl) Region::set_playlist (boost::weak_ptr<Playlist> pl)
{ {
_playlist = pl; _playlist = pl;
} }
@ -206,9 +202,11 @@ Region::maybe_uncopy ()
void void
Region::first_edit () 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; _first_edit = EditChangesNothing;
send_change (NameChanged); send_change (NameChanged);
@ -219,7 +217,9 @@ Region::first_edit ()
bool bool
Region::at_natural_position () const Region::at_natural_position () const
{ {
if (!_playlist) { boost::shared_ptr<Playlist> pl (playlist());
if (!pl) {
return false; return false;
} }
@ -237,7 +237,9 @@ Region::at_natural_position () const
void void
Region::move_to_natural_position (void *src) Region::move_to_natural_position (void *src)
{ {
if (!_playlist) { boost::shared_ptr<Playlist> pl (playlist());
if (!pl) {
return; return;
} }
@ -297,7 +299,11 @@ Region::set_position_on_top (nframes_t pos, void *src)
_position = pos; _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 /* do this even if the position is the same. this helps out
a GUI that has moved its representation already. a GUI that has moved its representation already.
@ -684,42 +690,37 @@ Region::sync_position() const
void void
Region::raise () Region::raise ()
{ {
if (_playlist == 0) { boost::shared_ptr<Playlist> pl (playlist());
return; if (pl) {
pl->raise_region (shared_from_this ());
} }
_playlist->raise_region (shared_from_this ());
} }
void void
Region::lower () Region::lower ()
{ {
if (_playlist == 0) { boost::shared_ptr<Playlist> pl (playlist());
return; if (pl) {
pl->lower_region (shared_from_this ());
} }
_playlist->lower_region (shared_from_this ());
} }
void void
Region::raise_to_top () Region::raise_to_top ()
{ {
boost::shared_ptr<Playlist> pl (playlist());
if (_playlist == 0) { if (pl) {
return; pl->raise_region_to_top (shared_from_this());
} }
_playlist->raise_region_to_top (shared_from_this());
} }
void void
Region::lower_to_bottom () Region::lower_to_bottom ()
{ {
if (_playlist == 0) { boost::shared_ptr<Playlist> pl (playlist());
return; if (pl) {
pl->lower_region_to_bottom (shared_from_this());
} }
_playlist->lower_region_to_bottom (shared_from_this());
} }
void void

View File

@ -468,10 +468,24 @@ Session::~Session ()
tmp = i; tmp = i;
++tmp; ++tmp;
delete *i; (*i)->drop_references ();
i = tmp; 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 #ifdef TRACK_DESTRUCTION
cerr << "delete audio regions\n"; cerr << "delete audio regions\n";
@ -918,7 +932,7 @@ Session::hookup_io ()
} }
void void
Session::playlist_length_changed (Playlist* pl) Session::playlist_length_changed ()
{ {
/* we can't just increase end_location->end() if pl->get_maximum_extent() /* we can't just increase end_location->end() if pl->get_maximum_extent()
if larger. if the playlist used to be the longest playlist, if larger. if the playlist used to be the longest playlist,
@ -932,10 +946,10 @@ Session::playlist_length_changed (Playlist* pl)
void void
Session::diskstream_playlist_changed (boost::shared_ptr<Diskstream> dstream) Session::diskstream_playlist_changed (boost::shared_ptr<Diskstream> dstream)
{ {
Playlist *playlist; boost::shared_ptr<Playlist> playlist;
if ((playlist = dstream->playlist()) != 0) { 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 () */ /* see comment in playlist_length_changed () */
@ -2268,7 +2282,7 @@ Session::get_maximum_extent () const
boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader(); boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
for (DiskstreamList::const_iterator i = dsl->begin(); i != dsl->end(); ++i) { 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) { if ((me = pl->get_maximum_extent()) > max) {
max = me; max = me;
} }
@ -2671,17 +2685,11 @@ Session::add_source (boost::shared_ptr<Source> source)
result = audio_sources.insert (entry); result = audio_sources.insert (entry);
} }
if (!result.second) { if (result.second) {
cerr << "\tNOT inserted ? " << result.second << endl; 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 void
@ -2710,8 +2718,6 @@ Session::remove_source (boost::weak_ptr<Source> src)
save_state (_current_snapshot_name); save_state (_current_snapshot_name);
} }
SourceRemoved(source); /* EMIT SIGNAL */
} }
boost::shared_ptr<Source> boost::shared_ptr<Source>
@ -2897,6 +2903,7 @@ Session::audio_path_from_name (string name, uint32_t nchan, uint32_t chan, bool
} else { } else {
snprintf (buf, sizeof(buf), "%s/T%04d-%s.wav", spath.c_str(), cnt, legalized.c_str()); snprintf (buf, sizeof(buf), "%s/T%04d-%s.wav", spath.c_str(), cnt, legalized.c_str());
} }
} else { } else {
spath += '/'; spath += '/';
@ -2940,6 +2947,7 @@ Session::audio_path_from_name (string name, uint32_t nchan, uint32_t chan, bool
string foo = buf; string foo = buf;
spath = discover_best_sound_dir (); spath = discover_best_sound_dir ();
spath += '/';
string::size_type pos = foo.find_last_of ('/'); 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 management */
Playlist * boost::shared_ptr<Playlist>
Session::playlist_by_name (string name) Session::playlist_by_name (string name)
{ {
Glib::Mutex::Lock lm (playlist_lock); Glib::Mutex::Lock lm (playlist_lock);
@ -2975,11 +2983,12 @@ Session::playlist_by_name (string name)
return* i; return* i;
} }
} }
return 0;
return boost::shared_ptr<Playlist>();
} }
void void
Session::add_playlist (Playlist* playlist) Session::add_playlist (boost::shared_ptr<Playlist> playlist)
{ {
if (playlist->hidden()) { if (playlist->hidden()) {
return; return;
@ -2989,9 +2998,8 @@ Session::add_playlist (Playlist* playlist)
Glib::Mutex::Lock lm (playlist_lock); Glib::Mutex::Lock lm (playlist_lock);
if (find (playlists.begin(), playlists.end(), playlist) == playlists.end()) { if (find (playlists.begin(), playlists.end(), playlist) == playlists.end()) {
playlists.insert (playlists.begin(), playlist); playlists.insert (playlists.begin(), playlist);
// playlist->ref(); playlist->InUse.connect (sigc::bind (mem_fun (*this, &Session::track_playlist), boost::weak_ptr<Playlist>(playlist)));
playlist->InUse.connect (mem_fun (*this, &Session::track_playlist)); playlist->GoingAway.connect (sigc::bind (mem_fun (*this, &Session::remove_playlist), boost::weak_ptr<Playlist>(playlist)));
playlist->GoingAway.connect (sigc::bind (mem_fun (*this, &Session::remove_playlist), playlist));
} }
} }
@ -3001,7 +3009,7 @@ Session::add_playlist (Playlist* playlist)
} }
void void
Session::get_playlists (vector<Playlist*>& s) Session::get_playlists (vector<boost::shared_ptr<Playlist> >& s)
{ {
{ {
Glib::Mutex::Lock lm (playlist_lock); Glib::Mutex::Lock lm (playlist_lock);
@ -3015,15 +3023,25 @@ Session::get_playlists (vector<Playlist*>& s)
} }
void 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; PlaylistList::iterator x;
if (pl->hidden()) {
/* its not supposed to be visible */
return;
}
{ {
Glib::Mutex::Lock lm (playlist_lock); Glib::Mutex::Lock lm (playlist_lock);
if (!inuse) { if (!inuse) {
//cerr << "shifting playlist to unused: " << pl->name() << endl;
unused_playlists.insert (pl); unused_playlists.insert (pl);
@ -3033,8 +3051,7 @@ Session::track_playlist (Playlist* pl, bool inuse)
} else { } else {
//cerr << "shifting playlist to used: " << pl->name() << endl;
playlists.insert (pl); playlists.insert (pl);
if ((x = unused_playlists.find (pl)) != unused_playlists.end()) { if ((x = unused_playlists.find (pl)) != unused_playlists.end()) {
@ -3045,26 +3062,33 @@ Session::track_playlist (Playlist* pl, bool inuse)
} }
void void
Session::remove_playlist (Playlist* playlist) Session::remove_playlist (boost::weak_ptr<Playlist> weak_playlist)
{ {
if (_state_of_the_state & Deletion) { if (_state_of_the_state & Deletion) {
return; return;
} }
boost::shared_ptr<Playlist> playlist (weak_playlist.lock());
if (!playlist) {
return;
}
{ {
Glib::Mutex::Lock lm (playlist_lock); Glib::Mutex::Lock lm (playlist_lock);
// cerr << "removing playlist: " << playlist->name() << endl; cerr << "removing playlist: " << playlist->name() << endl;
PlaylistList::iterator i; PlaylistList::iterator i;
i = find (playlists.begin(), playlists.end(), playlist); i = find (playlists.begin(), playlists.end(), playlist);
if (i != playlists.end()) { if (i != playlists.end()) {
cerr << "\tfound it in used playlist\n";
playlists.erase (i); playlists.erase (i);
} }
i = find (unused_playlists.begin(), unused_playlists.end(), playlist); i = find (unused_playlists.begin(), unused_playlists.end(), playlist);
if (i != unused_playlists.end()) { if (i != unused_playlists.end()) {
cerr << "\tfound it in unused playlist\n";
unused_playlists.erase (i); 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) bool overwrite, vector<boost::shared_ptr<AudioSource> >& srcs, InterThreadInfo& itt)
{ {
int ret = -1; int ret = -1;
Playlist* playlist; boost::shared_ptr<Playlist> playlist;
boost::shared_ptr<AudioFileSource> fsource; boost::shared_ptr<AudioFileSource> fsource;
uint32_t x; uint32_t x;
char buf[PATH_MAX+1]; char buf[PATH_MAX+1];

View File

@ -70,8 +70,9 @@ Command *Session::memento_command_factory(XMLNode *n)
} else if (obj_T == typeid (TempoMap).name()) { } else if (obj_T == typeid (TempoMap).name()) {
return new MementoCommand<TempoMap>(*_tempo_map, before, after); return new MementoCommand<TempoMap>(*_tempo_map, before, after);
} else if (obj_T == typeid (Playlist).name() || obj_T == typeid (AudioPlaylist).name()) { } else if (obj_T == typeid (Playlist).name() || obj_T == typeid (AudioPlaylist).name()) {
if (Playlist *pl = playlist_by_name(child->property("name")->value())) if (boost::shared_ptr<Playlist> pl = playlist_by_name(child->property("name")->value())) {
return new MementoCommand<Playlist>(*pl, before, after); return new MementoCommand<Playlist>(*(pl.get()), before, after);
}
} else if (obj_T == typeid (Route).name() || obj_T == typeid (AudioTrack).name()) { } else if (obj_T == typeid (Route).name() || obj_T == typeid (AudioTrack).name()) {
return new MementoCommand<Route>(*route_by_id(id), before, after); return new MementoCommand<Route>(*route_by_id(id), before, after);
} else if (obj_T == typeid (Curve).name() || obj_T == typeid (AutomationList).name()) { } else if (obj_T == typeid (Curve).name() || obj_T == typeid (AutomationList).name()) {

View File

@ -83,6 +83,7 @@
#include <ardour/control_protocol_manager.h> #include <ardour/control_protocol_manager.h>
#include <ardour/region_factory.h> #include <ardour/region_factory.h>
#include <ardour/source_factory.h> #include <ardour/source_factory.h>
#include <ardour/playlist_factory.h>
#include <control_protocol/control_protocol.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)); RegionFactory::CheckNewRegion.connect (mem_fun (*this, &Session::add_region));
SourceFactory::SourceCreated.connect (mem_fun (*this, &Session::add_source)); 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)); Redirect::RedirectCreated.connect (mem_fun (*this, &Session::add_redirect));
NamedSelection::NamedSelectionCreated.connect (mem_fun (*this, &Session::add_named_selection)); NamedSelection::NamedSelectionCreated.connect (mem_fun (*this, &Session::add_named_selection));
AutomationList::AutomationListCreated.connect (mem_fun (*this, &Session::add_automation_list)); 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] != '/') { if (fspath[fspath.length()-1] != '/') {
fspath += '/'; fspath += '/';
} }
fspath += sound_dir (false); fspath += sound_dir (false);
AudioFileSource::set_search_path (fspath); AudioFileSource::set_search_path (fspath);
@ -1681,7 +1683,7 @@ Session::load_playlists (const XMLNode& node)
{ {
XMLNodeList nlist; XMLNodeList nlist;
XMLNodeConstIterator niter; XMLNodeConstIterator niter;
Playlist *playlist; boost::shared_ptr<Playlist> playlist;
nlist = node.children(); nlist = node.children();
@ -1702,7 +1704,7 @@ Session::load_unused_playlists (const XMLNode& node)
{ {
XMLNodeList nlist; XMLNodeList nlist;
XMLNodeConstIterator niter; XMLNodeConstIterator niter;
Playlist *playlist; boost::shared_ptr<Playlist> playlist;
nlist = node.children(); nlist = node.children();
@ -1717,22 +1719,22 @@ Session::load_unused_playlists (const XMLNode& node)
// now manually untrack it // now manually untrack it
track_playlist (playlist, false); track_playlist (false, boost::weak_ptr<Playlist> (playlist));
} }
return 0; return 0;
} }
Playlist * boost::shared_ptr<Playlist>
Session::XMLPlaylistFactory (const XMLNode& node) Session::XMLPlaylistFactory (const XMLNode& node)
{ {
try { try {
return new AudioPlaylist (*this, node); return PlaylistFactory::create (*this, node);
} }
catch (failed_constructor& err) { 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 = _path;
old_withpath += old_sound_dir_name; old_withpath += old_sound_dir_name;
old_withpath += '/';
if (stat (old_withpath.c_str(), &statbuf) == 0) { if (stat (old_withpath.c_str(), &statbuf) == 0) {
if (with_path) if (with_path)
@ -1812,7 +1813,6 @@ Session::sound_dir (bool with_path) const
res += legalize_for_path (_name); res += legalize_for_path (_name);
res += '/'; res += '/';
res += sound_dir_name; res += sound_dir_name;
res += '/';
return res; return res;
} }
@ -2385,11 +2385,22 @@ Session::find_all_sources_across_snapshots (set<string>& result, bool exclude_th
return 0; 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 int
Session::cleanup_sources (Session::cleanup_report& rep) Session::cleanup_sources (Session::cleanup_report& rep)
{ {
vector<boost::shared_ptr<Source> > dead_sources; typedef map<boost::shared_ptr<Source>, RegionCounter> SourceRegionMap;
vector<Playlist*> playlists_tbd; SourceRegionMap dead_sources;
vector<boost::shared_ptr<Playlist> > playlists_tbd;
PathScanner scanner; PathScanner scanner;
string sound_path; string sound_path;
vector<space_and_path>::iterator i; 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 */ /* now delete any that were marked for deletion */
for (vector<Playlist*>::iterator x = playlists_tbd.begin(); x != playlists_tbd.end(); ++x) { for (vector<boost::shared_ptr<Playlist> >::iterator x = playlists_tbd.begin(); x != playlists_tbd.end(); ++x) {
PlaylistList::iterator foo; (*x)->drop_references ();
if ((foo = unused_playlists.find (*x)) != unused_playlists.end()) {
unused_playlists.erase (foo);
}
delete *x;
} }
playlists_tbd.clear ();
/* step 2: find all un-referenced sources */ /* step 2: find all un-referenced sources */
rep.paths.clear (); rep.paths.clear ();
rep.space = 0; rep.space = 0;
for (AudioSourceList::iterator i = audio_sources.begin(); i != audio_sources.end(); ) { 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.
AudioSourceList::iterator tmp; do not bother with files that are zero size, otherwise we remove the current "nascent"
capture files.
*/
if (i->second.use_count() <= 3 && i->second->length() > 0) {
pair<boost::shared_ptr<Source>, RegionCounter> newpair;
newpair.first = i->second;
newpair.second.iter = i;
dead_sources.insert (newpair);
}
}
/* Search the region list to find out the state of the supposedly unreferenced regions
*/
for (SourceRegionMap::iterator i = dead_sources.begin(); i != dead_sources.end();++i) {
for (AudioRegionList::iterator r = audio_regions.begin(); r != audio_regions.end(); ++r) {
boost::shared_ptr<AudioRegion> ar = r->second;
for (uint32_t n = 0; n < ar->n_channels(); ++n) {
if (ar->source (n) == i->first) {
/* this region uses this source */
i->second.region = ar;
i->second.count++;
if (i->second.count > 1) {
break;
}
}
}
}
}
/* 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 = i;
++tmp; ++tmp;
/* only remove files that are not in use and have some size if (i->second.count == 0) {
to them. otherwise we remove the current "nascent"
capture files.
*/
cerr << "checking out source " << i->second->name() << " use_count = " << i->second.use_count() << endl; /* no regions use this source */
if (i->second.use_count() == 1 && i->second->length() > 0) {
dead_sources.push_back (i->second);
/* remove this source from our own list to avoid us /* remove this source from our own list to avoid us
adding it to the list of all sources below adding it to the list of all sources below
*/ */
audio_sources.erase (i); 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; i = tmp;
} }
/* 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) {
for (AudioRegionList::iterator r = audio_regions.begin(); r != audio_regions.end(); ) {
AudioRegionList::iterator tmp;
boost::shared_ptr<AudioRegion> ar;
tmp = r;
++tmp;
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);
}
}
r = tmp;
}
}
/* build a list of all the possible sound directories for the session */ /* build a list of all the possible sound directories for the session */
for (i = session_dirs.begin(); i != session_dirs.end(); ) { for (i = session_dirs.begin(); i != session_dirs.end(); ) {
@ -2504,7 +2555,7 @@ Session::cleanup_sources (Session::cleanup_report& rep)
++nexti; ++nexti;
sound_path += (*i).path; sound_path += (*i).path;
sound_path += sound_dir_name; sound_path += sound_dir (false);
if (nexti != session_dirs.end()) { if (nexti != session_dirs.end()) {
sound_path += ':'; sound_path += ':';
@ -2512,7 +2563,7 @@ Session::cleanup_sources (Session::cleanup_report& rep)
i = nexti; i = nexti;
} }
/* now do the same thing for the files that ended up in the sounds dir(s) /* 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. 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. on whichever filesystem it was already on.
*/ */
newpath = Glib::path_get_dirname (*x); /* XXX this is a hack ... go up 4 levels */
newpath = Glib::path_get_dirname (newpath);
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 += '/';
newpath += dead_sound_dir_name; newpath += dead_sound_dir_name;
@ -2639,7 +2694,6 @@ Session::cleanup_sources (Session::cleanup_report& rep)
goto out; goto out;
} }
} }
} }
ret = 0; ret = 0;

View File

@ -110,15 +110,22 @@ Source::set_state (const XMLNode& node)
} }
void void
Source::add_playlist (Playlist* pl) Source::add_playlist (boost::shared_ptr<Playlist> pl)
{ {
_playlists.insert (pl); _playlists.insert (pl);
pl->GoingAway.connect (bind (mem_fun (*this, &Source::remove_playlist), boost::weak_ptr<Playlist> (pl)));
} }
void 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()) { if ((x = _playlists.find (pl)) != _playlists.end()) {
_playlists.erase (x); _playlists.erase (x);

View File

@ -83,10 +83,13 @@ boost::shared_ptr<Source>
SourceFactory::create (Session& s, const XMLNode& node) SourceFactory::create (Session& s, const XMLNode& node)
{ {
boost::shared_ptr<Source> ret (new SndFileSource (s, node)); boost::shared_ptr<Source> ret (new SndFileSource (s, node));
if (setup_peakfile (ret)) { if (setup_peakfile (ret)) {
return boost::shared_ptr<Source>(); return boost::shared_ptr<Source>();
} }
SourceCreated (ret); SourceCreated (ret);
return ret; return ret;
} }
@ -141,12 +144,15 @@ boost::shared_ptr<Source>
SourceFactory::createReadable (Session& s, string idstr, AudioFileSource::Flag flags, bool announce) SourceFactory::createReadable (Session& s, string idstr, AudioFileSource::Flag flags, bool announce)
{ {
boost::shared_ptr<Source> ret (new SndFileSource (s, idstr, flags)); boost::shared_ptr<Source> ret (new SndFileSource (s, idstr, flags));
if (setup_peakfile (ret)) { if (setup_peakfile (ret)) {
return boost::shared_ptr<Source>(); return boost::shared_ptr<Source>();
} }
if (announce) { if (announce) {
SourceCreated (ret); SourceCreated (ret);
} }
return ret; return ret;
} }