diff --git a/gtk2_ardour/editor.cc b/gtk2_ardour/editor.cc index 1b03576ace..4b97ceea2d 100644 --- a/gtk2_ardour/editor.cc +++ b/gtk2_ardour/editor.cc @@ -4971,7 +4971,7 @@ Editor::hide_a_region (boost::shared_ptr r) void Editor::remove_a_region (boost::shared_ptr r) { - _session->remove_region_from_region_list (r); + // _session->remove_region_from_region_list (r); } void diff --git a/gtk2_ardour/editor_regions.cc b/gtk2_ardour/editor_regions.cc index 39e8b84c1b..18b6971fe8 100644 --- a/gtk2_ardour/editor_regions.cc +++ b/gtk2_ardour/editor_regions.cc @@ -28,8 +28,9 @@ #include "ardour/audioregion.h" #include "ardour/audiofilesource.h" +#include "ardour/region_factory.h" +#include "ardour/session.h" #include "ardour/silentfilesource.h" -#include "ardour/session_region.h" #include "ardour/profile.h" #include @@ -139,7 +140,6 @@ EditorRegions::set_session (ARDOUR::Session* s) if (_session) { _session->RegionsAdded.connect (_session_connections, ui_bind (&EditorRegions::handle_new_regions, this, _1), gui_context()); - _session->RegionRemoved.connect (_session_connections, ui_bind (&EditorRegions::handle_region_removed, this, _1), gui_context()); _session->RegionHiddenChange.connect (_session_connections, ui_bind (&EditorRegions::region_hidden, this, _1), gui_context()); } @@ -147,15 +147,7 @@ EditorRegions::set_session (ARDOUR::Session* s) } void -EditorRegions::handle_region_removed (boost::weak_ptr wregion) -{ - ENSURE_GUI_THREAD (*this, &EditorRegions::handle_region_removed, wregion) - - redisplay (); -} - -void -EditorRegions::handle_new_regions (vector >& v) +EditorRegions::handle_new_regions (vector >& v) { ENSURE_GUI_THREAD (*this, &EditorRegions::handle_new_regions, v) add_regions (v); @@ -180,13 +172,10 @@ EditorRegions::region_hidden (boost::shared_ptr r) void -EditorRegions::add_regions (vector >& regions) +EditorRegions::add_regions (vector >& regions) { - for (vector >::iterator x = regions.begin(); x != regions.end(); ++x) { - boost::shared_ptr region ((*x).lock()); - if (region) { - add_region (region); - } + for (vector >::iterator x = regions.begin(); x != regions.end(); ++x) { + add_region (*x); } } @@ -511,7 +500,11 @@ EditorRegions::redisplay () */ tmp_region_list.clear(); - _session->foreach_region (this, &EditorRegions::insert_into_tmp_regionlist); + + const RegionFactory::RegionMap& regions (RegionFactory::regions()); + for (RegionFactory::RegionMap::const_iterator i = regions.begin(); i != regions.end(); ++i) { + insert_into_tmp_regionlist (i->second); + } for (list >::iterator r = tmp_region_list.begin(); r != tmp_region_list.end(); ++r) { add_region (*r); @@ -1000,7 +993,7 @@ EditorRegions::button_release (GdkEventButton *ev) } if (region && Keyboard::is_delete_event (ev)) { - _session->remove_region_from_region_list (region); + // _session->remove_region_from_region_list (region); return true; } diff --git a/gtk2_ardour/editor_regions.h b/gtk2_ardour/editor_regions.h index 33e077261c..c4ec4a1ba2 100644 --- a/gtk2_ardour/editor_regions.h +++ b/gtk2_ardour/editor_regions.h @@ -121,10 +121,9 @@ private: int sorter (Gtk::TreeModel::iterator, Gtk::TreeModel::iterator); void handle_new_region (boost::weak_ptr); - void handle_new_regions (std::vector >& ); - void handle_region_removed (boost::weak_ptr); + void handle_new_regions (std::vector >& ); void add_region (boost::shared_ptr); - void add_regions (std::vector > & ); + void add_regions (std::vector > & ); void region_hidden (boost::shared_ptr); void region_hidden_weak (boost::weak_ptr); void populate_row (boost::shared_ptr, Gtk::TreeModel::Row const &); diff --git a/libs/ardour/ardour/region_factory.h b/libs/ardour/ardour/region_factory.h index a01103603a..2bff4dd104 100644 --- a/libs/ardour/ardour/region_factory.h +++ b/libs/ardour/ardour/region_factory.h @@ -24,6 +24,7 @@ #include #include "pbd/id.h" +#include "pbd/signals.h" #include "ardour/types.h" #include "ardour/region.h" @@ -77,11 +78,17 @@ class RegionFactory { /** create a region with specified sources @param srcs and XML state */ static boost::shared_ptr create (SourceList& srcs, const XMLNode&); + static void map_remove (boost::shared_ptr); + static void delete_all_regions (); + static const RegionMap& regions() { return region_map; } + static uint32_t nregions (); + private: static Glib::StaticMutex region_map_lock; static RegionMap region_map; static void map_add (boost::shared_ptr); - static void map_remove (boost::shared_ptr); + + static PBD::ScopedConnectionList region_list_connections; }; } diff --git a/libs/ardour/ardour/session.h b/libs/ardour/ardour/session.h index cf88f2e6bd..7d94515efa 100644 --- a/libs/ardour/ardour/session.h +++ b/libs/ardour/ardour/session.h @@ -501,14 +501,12 @@ class Session : public PBD::StatefulDestructible, public PBD::ScopedConnectionLi /* region info */ - boost::shared_ptr region_by_id (const PBD::ID&) const; boost::shared_ptr find_whole_file_parent (boost::shared_ptr) const; void add_regions (std::vector >&); - PBD::Signal1 > RegionAdded; - PBD::Signal1 >&> RegionsAdded; - PBD::Signal1 > RegionRemoved; + PBD::Signal1 >&> RegionsAdded; + PBD::Signal1 > RegionRemoved; int region_name (std::string& result, std::string base = std::string(""), bool newlevel = false); std::string new_region_name (std::string); @@ -518,8 +516,6 @@ class Session : public PBD::StatefulDestructible, public PBD::ScopedConnectionLi boost::shared_ptr XMLAudioRegionFactory (const XMLNode&, bool full); boost::shared_ptr XMLMidiRegionFactory (const XMLNode&, bool full); - template void foreach_region (T *obj, void (T::*func)(boost::shared_ptr)); - /* source management */ void import_audiofiles (ImportStatus&); @@ -1259,8 +1255,6 @@ class Session : public PBD::StatefulDestructible, public PBD::ScopedConnectionLi void update_region_name_map (boost::shared_ptr); mutable Glib::Mutex region_lock; - typedef std::map > RegionList; - RegionList regions; void add_region (boost::shared_ptr); void region_changed (const PBD::PropertyChange&, boost::weak_ptr); diff --git a/libs/ardour/ardour/session_region.h b/libs/ardour/ardour/session_region.h deleted file mode 100644 index 136aaa0022..0000000000 --- a/libs/ardour/ardour/session_region.h +++ /dev/null @@ -1,39 +0,0 @@ -/* - Copyright (C) 2000-2007 Paul Davis - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - -*/ - -#ifndef __ardour_session_region_h__ -#define __ardour_session_region_h__ - -#include "ardour/session.h" -#include "ardour/audioregion.h" - -namespace ARDOUR { - -template void -Session::foreach_region (T *obj, void (T::*func)(boost::shared_ptr)) -{ - Glib::Mutex::Lock lm (region_lock); - for (RegionList::iterator i = regions.begin(); i != regions.end(); i++) { - (obj->*func) (i->second); - } -} - -} // namespace ARDOUR - -#endif /* __ardour_session_region_h__ */ diff --git a/libs/ardour/playlist.cc b/libs/ardour/playlist.cc index 0549982217..5cf0627448 100644 --- a/libs/ardour/playlist.cc +++ b/libs/ardour/playlist.cc @@ -112,13 +112,10 @@ RegionListProperty::lookup_id (const ID& id) { boost::shared_ptr ret = _playlist.region_by_id (id); - if (!ret) { - ret = _playlist.session().region_by_id (id); - } - if (!ret) { ret = RegionFactory::region_by_id (id); } + return ret; } @@ -2077,8 +2074,6 @@ Playlist::property_factory (const XMLNode& history_node) const for (XMLNodeList::const_iterator i = children.begin(); i != children.end(); ++i) { - /* XXX property name needs capitalizing */ - if ((*i)->name() == capitalize (regions.property_name())) { RegionListProperty* rlp = new RegionListProperty (*const_cast (this)); diff --git a/libs/ardour/plugin_manager.cc b/libs/ardour/plugin_manager.cc index f4d638e3bc..ebf0ecab3c 100644 --- a/libs/ardour/plugin_manager.cc +++ b/libs/ardour/plugin_manager.cc @@ -145,7 +145,9 @@ PluginManager::PluginManager () PluginManager::~PluginManager() { +#ifdef HAVE_SLV2 delete _lv2_world; +#endif } diff --git a/libs/ardour/region_factory.cc b/libs/ardour/region_factory.cc index 3f4af2462c..8a24bc954c 100644 --- a/libs/ardour/region_factory.cc +++ b/libs/ardour/region_factory.cc @@ -38,6 +38,7 @@ using namespace PBD; PBD::Signal1 > RegionFactory::CheckNewRegion; Glib::StaticMutex RegionFactory::region_map_lock; RegionFactory::RegionMap RegionFactory::region_map; +PBD::ScopedConnectionList RegionFactory::region_list_connections; boost::shared_ptr RegionFactory::create (boost::shared_ptr region) @@ -287,7 +288,6 @@ RegionFactory::create (SourceList& srcs, const XMLNode& node) return ret; } - void RegionFactory::map_add (boost::shared_ptr r) { @@ -298,19 +298,19 @@ RegionFactory::map_add (boost::shared_ptr r) { Glib::Mutex::Lock lm (region_map_lock); region_map.insert (p); - /* we pay no attention to attempts to delete regions */ } + + r->DropReferences.connect_same_thread (region_list_connections, boost::bind (&RegionFactory::map_remove, r)); } void RegionFactory::map_remove (boost::shared_ptr r) { - { - Glib::Mutex::Lock lm (region_map_lock); - RegionMap::iterator i = region_map.find (r->id()); - if (i != region_map.end()) { - region_map.erase (i); - } + Glib::Mutex::Lock lm (region_map_lock); + RegionMap::iterator i = region_map.find (r->id()); + + if (i != region_map.end()) { + region_map.erase (i); } } @@ -330,5 +330,42 @@ RegionFactory::region_by_id (const PBD::ID& id) void RegionFactory::clear_map () { - region_map.clear (); + region_list_connections.drop_connections (); + + { + Glib::Mutex::Lock lm (region_map_lock); + region_map.clear (); + } + +} + +void +RegionFactory::delete_all_regions () +{ + RegionMap copy; + + /* copy region list */ + { + Glib::Mutex::Lock lm (region_map_lock); + copy = region_map; + } + + /* clear existing map */ + clear_map (); + + /* tell everyone to drop references */ + for (RegionMap::iterator i = copy.begin(); i != copy.end(); ++i) { + i->second->drop_references (); + } + + /* the copy should now hold the only references, which will + vanish as we leave this scope, thus calling all destructors. + */ +} + +uint32_t +RegionFactory::nregions () +{ + Glib::Mutex::Lock lm (region_map_lock); + return region_map.size (); } diff --git a/libs/ardour/session.cc b/libs/ardour/session.cc index 53c8ea2350..31fd036890 100644 --- a/libs/ardour/session.cc +++ b/libs/ardour/session.cc @@ -353,10 +353,6 @@ Session::destroy () _engine.remove_session (); - /* clear region map. it doesn't hold references, but lets just be sensible here */ - - RegionFactory::clear_map (); - /* clear history so that no references to objects are held any more */ _history.clear (); @@ -403,11 +399,7 @@ Session::destroy () named_selections.clear (); DEBUG_TRACE (DEBUG::Destruction, "delete regions\n"); - for (RegionList::iterator i = regions.begin(); i != regions.end(); ++i) { - DEBUG_TRACE(DEBUG::Destruction, string_compose ("Dropping for region %1 ; pre-ref = %2\n", i->second->name(), i->second.use_count())); - i->second->drop_references (); - } - regions.clear (); + RegionFactory::delete_all_regions (); DEBUG_TRACE (DEBUG::Destruction, "delete routes\n"); @@ -2559,7 +2551,8 @@ Session::new_region_name (string old) while (number < (UINT_MAX-1)) { - RegionList::const_iterator i; + const RegionFactory::RegionMap& regions (RegionFactory::regions()); + RegionFactory::RegionMap::const_iterator i; string sbuf; number++; @@ -2598,9 +2591,7 @@ Session::region_name (string& result, string base, bool newlevel) if (base == "") { - Glib::Mutex::Lock lm (region_lock); - - snprintf (buf, sizeof (buf), "%d", (int)regions.size() + 1); + snprintf (buf, sizeof (buf), "%d", RegionFactory::nregions() + 1); result = "region."; result += buf; @@ -2652,84 +2643,23 @@ Session::add_region (boost::shared_ptr region) void Session::add_regions (vector >& new_regions) { - bool added = false; - - { - Glib::Mutex::Lock lm (region_lock); - - for (vector >::iterator ii = new_regions.begin(); ii != new_regions.end(); ++ii) { - - boost::shared_ptr region = *ii; - - if (region == 0) { - - error << _("Session::add_region() ignored a null region. Warning: you might have lost a region.") << endmsg; - - } else { - - RegionList::iterator x; - - for (x = regions.begin(); x != regions.end(); ++x) { - - if (region->region_list_equivalent (x->second)) { - break; - } - } - - if (x == regions.end()) { - - pair entry; - - entry.first = region->id(); - entry.second = region; - - pair x = regions.insert (entry); - - if (!x.second) { - return; - } - - added = true; - } - } - } - } - - /* mark dirty because something has changed even if we didn't - add the region to the region list. + /* mark dirty because something has changed */ set_dirty (); - - if (added) { - - vector > v; - boost::shared_ptr first_r; - - for (vector >::iterator ii = new_regions.begin(); ii != new_regions.end(); ++ii) { - - boost::shared_ptr region = *ii; - - if (region == 0) { - - error << _("Session::add_region() ignored a null region. Warning: you might have lost a region.") << endmsg; - - } else { - v.push_back (region); - - if (!first_r) { - first_r = region; - } - } - - region->PropertyChanged.connect_same_thread (*this, boost::bind (&Session::region_changed, this, _1, boost::weak_ptr(region))); - update_region_name_map (region); - } - - if (!v.empty()) { - RegionsAdded (v); /* EMIT SIGNAL */ - } - } + + for (vector >::iterator ii = new_regions.begin(); ii != new_regions.end(); ++ii) { + + boost::shared_ptr region = *ii; + assert (region); + + region->PropertyChanged.connect_same_thread (*this, boost::bind (&Session::region_changed, this, _1, boost::weak_ptr(region))); + update_region_name_map (region); + } + + if (!new_regions.empty()) { + RegionsAdded (new_regions); /* EMIT SIGNAL */ + } } void @@ -2773,39 +2703,23 @@ Session::region_changed (const PropertyChange& what_changed, boost::weak_ptr weak_region) { - RegionList::iterator i; boost::shared_ptr region (weak_region.lock ()); if (!region) { return; } - bool removed = false; - - { - Glib::Mutex::Lock lm (region_lock); - - if ((i = regions.find (region->id())) != regions.end()) { - regions.erase (i); - removed = true; - } - } - - /* mark dirty because something has changed even if we didn't - remove the region from the region list. - */ - + RegionFactory::map_remove (region); set_dirty(); - if (removed) { - RegionRemoved(region); /* EMIT SIGNAL */ - } + RegionRemoved(region); /* EMIT SIGNAL */ } boost::shared_ptr Session::find_whole_file_parent (boost::shared_ptr child) const { - RegionList::const_iterator i; + const RegionFactory::RegionMap& regions (RegionFactory::regions()); + RegionFactory::RegionMap::const_iterator i; boost::shared_ptr region; Glib::Mutex::Lock lm (region_lock); @@ -2825,20 +2739,6 @@ Session::find_whole_file_parent (boost::shared_ptr child) const return boost::shared_ptr (); } -boost::shared_ptr -Session::region_by_id (const PBD::ID& id) const -{ - Glib::Mutex::Lock lm (region_lock); - - RegionList::const_iterator i = regions.find (id); - - if (i != regions.end()) { - return i->second; - } - - return boost::shared_ptr (); -} - int Session::destroy_region (boost::shared_ptr region) { @@ -2858,10 +2758,10 @@ Session::destroy_region (boost::shared_ptr region) for (vector >::iterator i = srcs.begin(); i != srcs.end(); ++i) { - (*i)->mark_for_remove (); - (*i)->drop_references (); - - cerr << "source was not used by any playlist\n"; + (*i)->mark_for_remove (); + (*i)->drop_references (); + + cerr << "source was not used by any playlist\n"; } return 0; @@ -2892,10 +2792,6 @@ Session::remove_last_capture () } } - for (list >::iterator i = r.begin(); i != r.end(); ++i) { - remove_region (*i); - } - destroy_regions (r); save_state (_current_snapshot_name); @@ -2903,13 +2799,6 @@ Session::remove_last_capture () return 0; } -int -Session::remove_region_from_region_list (boost::shared_ptr r) -{ - remove_region (r); - return 0; -} - /* Source Management */ void diff --git a/libs/ardour/session_state.cc b/libs/ardour/session_state.cc index 014200da1c..f960660555 100644 --- a/libs/ardour/session_state.cc +++ b/libs/ardour/session_state.cc @@ -991,16 +991,6 @@ Session::state(bool full_state) if (full_state) { Glib::Mutex::Lock rl (region_lock); -#if 0 - for (RegionList::const_iterator i = regions.begin(); i != regions.end(); ++i) { - - /* only store regions not attached to playlists */ - - if (i->second->playlist() == 0) { - child->add_child_nocopy (i->second->state (true)); - } - } -#else const RegionFactory::RegionMap& region_map (RegionFactory::all_regions()); for (RegionFactory::RegionMap::const_iterator i = region_map.begin(); i != region_map.end(); ++i) { boost::shared_ptr r = i->second; @@ -1009,8 +999,6 @@ Session::state(bool full_state) child->add_child_nocopy (r->state (true)); } } -#endif - } child = node->add_child ("DiskStreams"); diff --git a/libs/ardour/strip_silence.cc b/libs/ardour/strip_silence.cc index ae35eebd8f..21e1ad5450 100644 --- a/libs/ardour/strip_silence.cc +++ b/libs/ardour/strip_silence.cc @@ -17,6 +17,8 @@ */ +#include "pbd/property_list.h" + #include "ardour/strip_silence.h" #include "ardour/audioregion.h" #include "ardour/region_factory.h" @@ -44,7 +46,8 @@ StripSilence::run (boost::shared_ptr r) results.clear (); /* we only operate on AudioRegions, for now, though this could be adapted to MIDI - as well I guess */ + as well I guess + */ boost::shared_ptr region = boost::dynamic_pointer_cast (r); InterThreadInfo itt; @@ -78,59 +81,54 @@ StripSilence::run (boost::shared_ptr r) } std::list >::const_iterator s = silence.begin (); - framepos_t const pos = region->position (); - framepos_t const end = region->start () + region->length() - 1; - framepos_t const start = region->start (); + PBD::PropertyList plist; + framepos_t start = 0; + framepos_t end; + bool in_silence; + boost::shared_ptr copy; - region = boost::dynamic_pointer_cast (RegionFactory::create (region)); - region->set_name (session.new_region_name (region->name ())); - boost::shared_ptr last_region = region; - results.push_back (region); + if (s->first == 0) { + /* initial segment, starting at zero, is silent */ + end = s->second; + in_silence = true; + } else { + /* initial segment, starting at zero, is audible */ + end = s->first; + in_silence = false; + } - if (s->first == 0) { - /* the region starts with some silence */ + while (s != silence.end()) { - /* we must set length to an intermediate value here, otherwise the call - ** to set_start will fail */ - region->set_length (region->length() - s->second + _fade_length, 0); - region->set_start (start + s->second - _fade_length, 0); - region->set_position (pos + s->second - _fade_length, 0); - region->set_fade_in_active (true); - region->set_fade_in (AudioRegion::Linear, _fade_length); - s++; - } + framecnt_t interval_duration; - while (s != silence.end()) { + interval_duration = end - start; - /* trim the end of this region */ - region->trim_end (pos + s->first + _fade_length, 0); - region->set_fade_out_active (true); - region->set_fade_out (AudioRegion::Linear, _fade_length); - /* make a new region and trim its start */ - region = boost::dynamic_pointer_cast (RegionFactory::create (region)); - region->set_name (session.new_region_name (region->name ())); - last_region = region; - assert (region); - results.push_back (region); + if (!in_silence && interval_duration > 0) { - /* set length here for the same reasons as above */ - region->set_length (region->length() - s->second + _fade_length, 0); - region->set_start (start + s->second - _fade_length, 0); - region->set_position (pos + s->second - _fade_length, 0); - region->set_fade_in_active (true); - region->set_fade_in (AudioRegion::Linear, _fade_length); + plist.clear (); + plist.add (Properties::length, interval_duration); + plist.add (Properties::position, region->position() + start); - s++; - } + copy = boost::dynamic_pointer_cast (RegionFactory::create + (region, start, plist)); - if (silence.back().second == end) { - /* the last region we created is zero-sized, so just remove it */ - results.pop_back (); - } else { - /* finish off the last region */ - last_region->trim_end (end, 0); - } + copy->set_name (session.new_region_name (region->name ())); + + std::cerr << "New silent delineated region called " << copy->name() + << " @ " << copy->start() << " length = " << copy->length() << " pos = " << + copy->position() << std::endl; + + copy->set_fade_in_active (true); + copy->set_fade_in (AudioRegion::Linear, _fade_length); + results.push_back (copy); + } + + start = end; + ++s; + end = s->first; + in_silence = !in_silence; + } return 0; }