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