1 /* 2 * Copyright (C) 2000-2017 Paul Davis <paul@linuxaudiosystems.com> 3 * Copyright (C) 2006-2012 David Robillard <d@drobilla.net> 4 * Copyright (C) 2009-2012 Carl Hetherington <carl@carlh.net> 5 * Copyright (C) 2015-2017 Robin Gareus <robin@gareus.org> 6 * Copyright (C) 2016-2017 Nick Mainsbridge <mainsbridge@gmail.com> 7 * Copyright (C) 2018-2019 Ben Loftis <ben@harrisonconsoles.com> 8 * 9 * This program is free software; you can redistribute it and/or modify 10 * it under the terms of the GNU General Public License as published by 11 * the Free Software Foundation; either version 2 of the License, or 12 * (at your option) any later version. 13 * 14 * This program is distributed in the hope that it will be useful, 15 * but WITHOUT ANY WARRANTY; without even the implied warranty of 16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 * GNU General Public License for more details. 18 * 19 * You should have received a copy of the GNU General Public License along 20 * with this program; if not, write to the Free Software Foundation, Inc., 21 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 22 */ 23 24 #ifndef __ardour_region_factory_h__ 25 #define __ardour_region_factory_h__ 26 27 #include <glibmm/threads.h> 28 #include <map> 29 #include <set> 30 31 #include "pbd/id.h" 32 #include "pbd/property_list.h" 33 #include "pbd/signals.h" 34 35 #include "ardour/libardour_visibility.h" 36 #include "ardour/types.h" 37 38 class XMLNode; 39 class RegionNamingTest; 40 41 namespace ARDOUR { 42 43 class AudioRegion; 44 class Session; 45 class ThawList; 46 47 class LIBARDOUR_API RegionFactory 48 { 49 public: 50 typedef std::map<PBD::ID, boost::shared_ptr<Region> > RegionMap; 51 52 static boost::shared_ptr<Region> wholefile_region_by_name (const std::string& name); 53 static boost::shared_ptr<Region> region_by_id (const PBD::ID&); 54 static boost::shared_ptr<Region> region_by_name (const std::string& name); 55 static void clear_map (); all_regions()56 static const RegionMap all_regions () 57 { 58 return region_map; 59 } 60 61 /** This is emitted only when a new id is assigned. Therefore, 62 * in a pure Region copy, it will not be emitted. 63 * 64 * It must be emitted using a derived instance of Region, not Region 65 * itself, to permit dynamic_cast<> to be used to 66 * infer the type of Region. 67 */ 68 static PBD::Signal1<void, boost::shared_ptr<Region> > CheckNewRegion; 69 70 /** create a "pure copy" of Region \p other */ 71 static boost::shared_ptr<Region> create (boost::shared_ptr<const Region> other, bool announce, bool fork = false, ThawList* tl = 0); 72 73 /** Lua binding to create a "pure copy" of Region \p other */ create(boost::shared_ptr<Region> other,bool announce,bool fork)74 static boost::shared_ptr<Region> create (boost::shared_ptr<Region> other, bool announce, bool fork) 75 { 76 return create (boost::shared_ptr<const Region> (other), announce, fork, 0); 77 } 78 79 /** create a region from a single Source */ 80 static boost::shared_ptr<Region> create (boost::shared_ptr<Source>, const PBD::PropertyList&, bool announce = true, ThawList* tl = 0); 81 /** create a region from a multiple sources */ 82 static boost::shared_ptr<Region> create (const SourceList&, const PBD::PropertyList&, bool announce = true, ThawList* tl = 0); 83 /** create a copy of \p other starting at zero within \p other's sources */ 84 static boost::shared_ptr<Region> create (boost::shared_ptr<Region> other, const PBD::PropertyList&, bool announce = true, ThawList* tl = 0); 85 /** create a copy of \p other starting at \p offset within \p other */ 86 static boost::shared_ptr<Region> create (boost::shared_ptr<Region> other, ARDOUR::MusicSample offset, const PBD::PropertyList&, bool announce = true, ThawList* tl = 0); 87 /** create a "copy" of \p other but using a different set of sources \p srcs */ 88 static boost::shared_ptr<Region> create (boost::shared_ptr<Region> other, const SourceList& srcs, const PBD::PropertyList&, bool announce = true, ThawList* tl = 0); 89 90 /** create a region with no sources, using XML state */ 91 static boost::shared_ptr<Region> create (Session&, XMLNode&, bool); 92 /** create a region with specified sources \p srcs and XML state */ 93 static boost::shared_ptr<Region> create (SourceList& srcs, const XMLNode&); 94 95 static boost::shared_ptr<Region> get_whole_region_for_source (boost::shared_ptr<ARDOUR::Source>); 96 97 static void get_regions_using_source (boost::shared_ptr<Source>, std::set<boost::shared_ptr<Region> >&); 98 static void remove_regions_using_source (boost::shared_ptr<Source>); 99 100 static void map_remove (boost::weak_ptr<Region>); 101 static void delete_all_regions (); 102 regions()103 static const RegionMap& regions () 104 { 105 return region_map; 106 } 107 108 static uint32_t nregions (); 109 foreach_region(boost::function<void (boost::shared_ptr<Region>)> f)110 static void foreach_region (boost::function<void (boost::shared_ptr<Region>)> f) 111 { 112 Glib::Threads::Mutex::Lock ls (region_map_lock); 113 for (RegionMap::const_iterator i = region_map.begin (); i != region_map.end (); ++i) { 114 f ((*i).second); 115 } 116 } 117 118 static int region_name (std::string&, std::string, bool new_level = false); 119 static std::string new_region_name (std::string); 120 static std::string compound_region_name (const std::string& playlist, uint32_t compound_ops, uint32_t depth, bool whole_source); 121 122 /* when we make a compound region, for every region involved there 123 * are two "instances" - the original, which is removed from this 124 * playlist, and a copy, which is added to the playlist used as 125 * the source for the compound. 126 * 127 * when we uncombine, we want to put the originals back into this 128 * playlist after we remove the compound. this map lets us 129 * look them up easily. note that if the compound was trimmed or 130 * split, we may have to trim the originals 131 * and they may not be added back if the compound was trimmed 132 * or split sufficiently. 133 */ 134 135 typedef std::map<boost::shared_ptr<Region>, boost::shared_ptr<Region> > CompoundAssociations; 136 compound_associations()137 static CompoundAssociations& compound_associations () 138 { 139 return _compound_associations; 140 } 141 142 static void add_compound_association (boost::shared_ptr<Region>, boost::shared_ptr<Region>); 143 144 /* exposed because there may be cases where regions are created with 145 * announce=false but they still need to be in the map soon after 146 * creation. 147 */ 148 149 static void map_add (boost::shared_ptr<Region>); 150 151 private: 152 friend class ::RegionNamingTest; 153 154 static void region_changed (PBD::PropertyChange const&, boost::weak_ptr<Region>); 155 static void add_to_region_name_maps (boost::shared_ptr<Region>); 156 static void rename_in_region_name_maps (boost::shared_ptr<Region>); 157 static void update_region_name_number_map (boost::shared_ptr<Region>); 158 static void remove_from_region_name_map (std::string); 159 160 static Glib::Threads::Mutex region_map_lock; 161 static RegionMap region_map; 162 163 static Glib::Threads::Mutex region_name_maps_mutex; 164 /** map of partial region names and suffix numbers */ 165 static std::map<std::string, uint32_t> region_name_number_map; 166 /** map of complete region names with their region ID */ 167 static std::map<std::string, PBD::ID> region_name_map; 168 169 static PBD::ScopedConnectionList* region_list_connections; 170 static CompoundAssociations _compound_associations; 171 }; 172 173 } // namespace ARDOUR 174 175 #endif /* __ardour_region_factory_h__ */ 176