summaryrefslogtreecommitdiff
path: root/libs/ardour
diff options
context:
space:
mode:
authorDavid Robillard <d@drobilla.net>2006-08-29 21:21:48 +0000
committerDavid Robillard <d@drobilla.net>2006-08-29 21:21:48 +0000
commit82232f06ba3eea4a2b4342ad91fab552f4044402 (patch)
treed517cb47c017f51e2ecd9450624b86eb70d9f97b /libs/ardour
parent25d1670a61d19e795227b939a98be9cf5a050c67 (diff)
Merged with trunk R861
Possible new bugs - not very thoroughly tested, but at least functional at first glance git-svn-id: svn://localhost/ardour2/branches/midi@870 d708f5d6-7413-0410-9779-e7cbd77b26cf
Diffstat (limited to 'libs/ardour')
-rw-r--r--libs/ardour/SConscript2
-rw-r--r--libs/ardour/ardour/audio_diskstream.h14
-rw-r--r--libs/ardour/ardour/audiofilesource.h10
-rw-r--r--libs/ardour/ardour/audiofilter.h8
-rw-r--r--libs/ardour/ardour/audioplaylist.h14
-rw-r--r--libs/ardour/ardour/audioregion.h20
-rw-r--r--libs/ardour/ardour/audiosource.h4
-rw-r--r--libs/ardour/ardour/auditioner.h4
-rw-r--r--libs/ardour/ardour/automation_event.h5
-rw-r--r--libs/ardour/ardour/crossfade.h29
-rw-r--r--libs/ardour/ardour/diskstream.h10
-rw-r--r--libs/ardour/ardour/io.h6
-rw-r--r--libs/ardour/ardour/location.h6
-rw-r--r--libs/ardour/ardour/midi_diskstream.h4
-rw-r--r--libs/ardour/ardour/midi_playlist.h17
-rw-r--r--libs/ardour/ardour/midi_region.h20
-rw-r--r--libs/ardour/ardour/playlist.h75
-rw-r--r--libs/ardour/ardour/playlist_templates.h4
-rw-r--r--libs/ardour/ardour/plugin.h6
-rw-r--r--libs/ardour/ardour/redirect.h1
-rw-r--r--libs/ardour/ardour/region.h59
-rw-r--r--libs/ardour/ardour/region_factory.h30
-rw-r--r--libs/ardour/ardour/reverse.h2
-rw-r--r--libs/ardour/ardour/route.h2
-rw-r--r--libs/ardour/ardour/session.h134
-rw-r--r--libs/ardour/ardour/session_region.h4
-rw-r--r--libs/ardour/ardour/source.h20
-rw-r--r--libs/ardour/ardour/source_factory.h28
-rw-r--r--libs/ardour/ardour/tempo.h6
-rw-r--r--libs/ardour/ardour/types.h4
-rw-r--r--libs/ardour/audio_diskstream.cc95
-rw-r--r--libs/ardour/audio_playlist.cc151
-rw-r--r--libs/ardour/audio_track.cc18
-rw-r--r--libs/ardour/audioengine.cc24
-rw-r--r--libs/ardour/audiofilesource.cc83
-rw-r--r--libs/ardour/audiofilter.cc32
-rw-r--r--libs/ardour/audioregion.cc96
-rw-r--r--libs/ardour/audiosource.cc14
-rw-r--r--libs/ardour/auditioner.cc25
-rw-r--r--libs/ardour/automation_event.cc2
-rw-r--r--libs/ardour/control_protocol_manager.cc2
-rw-r--r--libs/ardour/coreaudiosource.cc2
-rw-r--r--libs/ardour/crossfade.cc38
-rw-r--r--libs/ardour/destructive_filesource.cc2
-rw-r--r--libs/ardour/diskstream.cc6
-rw-r--r--libs/ardour/import.cc40
-rw-r--r--libs/ardour/insert.cc4
-rw-r--r--libs/ardour/io.cc19
-rw-r--r--libs/ardour/ladspa_plugin.cc2
-rw-r--r--libs/ardour/location.cc34
-rw-r--r--libs/ardour/midi_diskstream.cc39
-rw-r--r--libs/ardour/midi_playlist.cc174
-rw-r--r--libs/ardour/midi_region.cc47
-rw-r--r--libs/ardour/osc.cc2
-rw-r--r--libs/ardour/playlist.cc222
-rw-r--r--libs/ardour/playlist_factory.cc46
-rw-r--r--libs/ardour/region.cc180
-rw-r--r--libs/ardour/region_factory.cc182
-rw-r--r--libs/ardour/reverse.cc25
-rw-r--r--libs/ardour/send.cc2
-rw-r--r--libs/ardour/session.cc312
-rw-r--r--libs/ardour/session_butler.cc2
-rw-r--r--libs/ardour/session_command.cc7
-rw-r--r--libs/ardour/session_events.cc2
-rw-r--r--libs/ardour/session_state.cc172
-rw-r--r--libs/ardour/session_timefx.cc38
-rw-r--r--libs/ardour/smf_source.cc4
-rw-r--r--libs/ardour/sndfilesource.cc21
-rw-r--r--libs/ardour/source.cc15
-rw-r--r--libs/ardour/source_factory.cc219
-rw-r--r--libs/ardour/vst_plugin.cc2
71 files changed, 1519 insertions, 1431 deletions
diff --git a/libs/ardour/SConscript b/libs/ardour/SConscript
index 1128ecfde9..254f5a0560 100644
--- a/libs/ardour/SConscript
+++ b/libs/ardour/SConscript
@@ -84,6 +84,7 @@ plugin_manager.cc
recent_sessions.cc
redirect.cc
region.cc
+region_factory.cc
reverse.cc
route.cc
route_group.cc
@@ -103,6 +104,7 @@ session_transport.cc
sndfile_helpers.cc
sndfilesource.cc
source.cc
+source_factory.cc
state_manager.cc
tempo.cc
utils.cc
diff --git a/libs/ardour/ardour/audio_diskstream.h b/libs/ardour/ardour/audio_diskstream.h
index 18f8328cfd..8588c9660d 100644
--- a/libs/ardour/ardour/audio_diskstream.h
+++ b/libs/ardour/ardour/audio_diskstream.h
@@ -108,10 +108,10 @@ class AudioDiskstream : public Diskstream
return 0;
}
- AudioFileSource *write_source (uint32_t n=0) {
+ boost::shared_ptr<AudioFileSource> write_source (uint32_t n=0) {
if (n < channels.size())
return channels[n].write_source;
- return 0;
+ return boost::shared_ptr<AudioFileSource>();
}
int add_channel ();
@@ -141,8 +141,6 @@ class AudioDiskstream : public Diskstream
}
}
- std::list<Region*>& last_capture_regions () { return _last_capture_regions; }
-
XMLNode* deprecated_io_node;
protected:
@@ -181,9 +179,9 @@ class AudioDiskstream : public Diskstream
Sample *speed_buffer;
float peak_power;
-
- AudioFileSource *fades_source;
- AudioFileSource *write_source;
+
+ boost::shared_ptr<AudioFileSource> fades_source;
+ boost::shared_ptr<AudioFileSource> write_source;
Port *source;
Sample *current_capture_buffer;
@@ -251,7 +249,7 @@ class AudioDiskstream : public Diskstream
int _do_refill (Sample *mixdown_buffer, float *gain_buffer);
- std::vector<AudioFileSource*> capturing_sources;
+ std::vector<boost::shared_ptr<AudioFileSource> > capturing_sources;
typedef vector<ChannelInfo> ChannelList;
ChannelList channels;
diff --git a/libs/ardour/ardour/audiofilesource.h b/libs/ardour/ardour/audiofilesource.h
index 3e0d4c45ae..b1ffab0944 100644
--- a/libs/ardour/ardour/audiofilesource.h
+++ b/libs/ardour/ardour/audiofilesource.h
@@ -56,16 +56,6 @@ class AudioFileSource : public AudioSource {
static void set_peak_dir (string dir) { peak_dir = dir; }
- /* factory for an existing but not-used-in-session audio file. this exists
- because there maybe multiple back-end derivations of AudioFileSource,
- some of which can handle formats that cannot be handled by others.
- For example, CoreAudioFileSource can handle MP3 files, which SndFileSource
- cannot.
- */
-
- static AudioFileSource* create (const string& path_plus_channel, Flag flags = Flag (0));
- static AudioFileSource* create (const XMLNode&);
-
static bool get_soundfile_info (string path, SoundFileInfo& _info, string& error);
void set_allow_remove_if_empty (bool yn);
diff --git a/libs/ardour/ardour/audiofilter.h b/libs/ardour/ardour/audiofilter.h
index 02e5e6f061..c8762dbf69 100644
--- a/libs/ardour/ardour/audiofilter.h
+++ b/libs/ardour/ardour/audiofilter.h
@@ -36,14 +36,14 @@ class AudioFilter {
: session (s){}
virtual ~AudioFilter() {}
- virtual int run (ARDOUR::AudioRegion&) = 0;
- std::vector<ARDOUR::AudioRegion*> results;
+ virtual int run (boost::shared_ptr<ARDOUR::AudioRegion>) = 0;
+ std::vector<boost::shared_ptr<ARDOUR::AudioRegion> > results;
protected:
ARDOUR::Session& session;
- int make_new_sources (ARDOUR::AudioRegion&, ARDOUR::AudioRegion::SourceList&);
- int finish (ARDOUR::AudioRegion&, ARDOUR::AudioRegion::SourceList&);
+ int make_new_sources (boost::shared_ptr<ARDOUR::AudioRegion>, ARDOUR::SourceList&);
+ int finish (boost::shared_ptr<ARDOUR::AudioRegion>, ARDOUR::SourceList&);
};
} /* namespace */
diff --git a/libs/ardour/ardour/audioplaylist.h b/libs/ardour/ardour/audioplaylist.h
index bd76c30289..0426208ba1 100644
--- a/libs/ardour/ardour/audioplaylist.h
+++ b/libs/ardour/ardour/audioplaylist.h
@@ -58,7 +58,7 @@ class AudioPlaylist : public ARDOUR::Playlist
AudioPlaylist (const AudioPlaylist&, string name, bool hidden = false);
AudioPlaylist (const AudioPlaylist&, jack_nframes_t start, jack_nframes_t cnt, string name, bool hidden = false);
- void clear (bool with_delete = false, bool with_save = true);
+ void clear (bool with_save = true);
jack_nframes_t read (Sample *dst, Sample *mixdown, float *gain_buffer, jack_nframes_t start, jack_nframes_t cnt, uint32_t chan_n=0);
@@ -75,7 +75,7 @@ class AudioPlaylist : public ARDOUR::Playlist
(obj.*method) (states, _current_state_id);
}
- bool destroy_region (Region*);
+ bool destroy_region (boost::shared_ptr<Region>);
void drop_all_states ();
@@ -91,11 +91,11 @@ class AudioPlaylist : public ARDOUR::Playlist
void notify_crossfade_added (Crossfade *);
void flush_notifications ();
- void finalize_split_region (Region *orig, Region *left, Region *right);
+ void finalize_split_region (boost::shared_ptr<Region> orig, boost::shared_ptr<Region> left, boost::shared_ptr<Region> right);
- void refresh_dependents (Region& region);
- void check_dependents (Region& region, bool norefresh);
- void remove_dependents (Region& region);
+ void refresh_dependents (boost::shared_ptr<Region> region);
+ void check_dependents (boost::shared_ptr<Region> region, bool norefresh);
+ void remove_dependents (boost::shared_ptr<Region> region);
protected:
~AudioPlaylist (); /* public should use unref() */
@@ -108,7 +108,7 @@ class AudioPlaylist : public ARDOUR::Playlist
XMLNode& state (bool full_state);
void dump () const;
- bool region_changed (Change, Region*);
+ bool region_changed (Change, boost::shared_ptr<Region>);
void crossfade_changed (Change);
void add_crossfade (Crossfade&);
};
diff --git a/libs/ardour/ardour/audioregion.h b/libs/ardour/ardour/audioregion.h
index fd2cc8d2f1..9b97a88bc0 100644
--- a/libs/ardour/ardour/audioregion.h
+++ b/libs/ardour/ardour/audioregion.h
@@ -65,18 +65,11 @@ class AudioRegion : public Region
static Change ScaleAmplitudeChanged;
static Change EnvelopeChanged;
- AudioRegion (AudioSource&, jack_nframes_t start, jack_nframes_t length, bool announce = true);
- AudioRegion (AudioSource&, jack_nframes_t start, jack_nframes_t length, const string& name, layer_t = 0, Region::Flag flags = Region::DefaultFlags, bool announce = true);
- AudioRegion (SourceList &, jack_nframes_t start, jack_nframes_t length, const string& name, layer_t = 0, Region::Flag flags = Region::DefaultFlags, bool announce = true);
- AudioRegion (const AudioRegion&, jack_nframes_t start, jack_nframes_t length, const string& name, layer_t = 0, Region::Flag flags = Region::DefaultFlags, bool announce = true);
- AudioRegion (const AudioRegion&);
- AudioRegion (AudioSource&, const XMLNode&);
- AudioRegion (SourceList &, const XMLNode&);
~AudioRegion();
bool speed_mismatch (float) const;
- AudioSource& audio_source (uint32_t n=0) const;
+ boost::shared_ptr<AudioSource> audio_source (uint32_t n=0) const;
void set_scale_amplitude (gain_t);
gain_t scale_amplitude() const { return _scale_amplitude; }
@@ -149,7 +142,15 @@ class AudioRegion : public Region
void resume_fade_out ();
private:
- friend class Playlist;
+ friend class RegionFactory;
+
+ AudioRegion (boost::shared_ptr<AudioSource>, jack_nframes_t start, jack_nframes_t length);
+ AudioRegion (boost::shared_ptr<AudioSource>, jack_nframes_t start, jack_nframes_t length, const string& name, layer_t = 0, Region::Flag flags = Region::DefaultFlags);
+ AudioRegion (SourceList &, jack_nframes_t start, jack_nframes_t length, const string& name, layer_t = 0, Region::Flag flags = Region::DefaultFlags);
+ AudioRegion (boost::shared_ptr<const AudioRegion>, jack_nframes_t start, jack_nframes_t length, const string& name, layer_t = 0, Region::Flag flags = Region::DefaultFlags);
+ AudioRegion (boost::shared_ptr<const AudioRegion>);
+ AudioRegion (boost::shared_ptr<AudioSource>, const XMLNode&);
+ AudioRegion (SourceList &, const XMLNode&);
private:
void set_default_fades ();
@@ -174,7 +175,6 @@ class AudioRegion : public Region
void envelope_changed (Change);
-
mutable Curve _fade_in;
FadeShape _fade_in_shape;
mutable Curve _fade_out;
diff --git a/libs/ardour/ardour/audiosource.h b/libs/ardour/ardour/audiosource.h
index c3c2f9bb9a..751213ee8e 100644
--- a/libs/ardour/ardour/audiosource.h
+++ b/libs/ardour/ardour/audiosource.h
@@ -70,7 +70,7 @@ class AudioSource : public Source
int read_peaks (PeakData *peaks, jack_nframes_t npeaks, jack_nframes_t start, jack_nframes_t cnt, double samples_per_unit) const;
int build_peaks ();
bool peaks_ready (sigc::slot<void>, sigc::connection&) const;
-
+
mutable sigc::signal<void> PeaksReady;
mutable sigc::signal<void,jack_nframes_t,jack_nframes_t> PeakRangeReady;
@@ -129,7 +129,7 @@ class AudioSource : public Source
static vector<AudioSource*> pending_peak_sources;
static Glib::Mutex* pending_peak_sources_lock;
- static void queue_for_peaks (AudioSource&);
+ static void queue_for_peaks (AudioSource*);
static void clear_queue_for_peaks ();
struct PeakBuildRecord {
diff --git a/libs/ardour/ardour/auditioner.h b/libs/ardour/ardour/auditioner.h
index 434ec32f97..424ede0009 100644
--- a/libs/ardour/ardour/auditioner.h
+++ b/libs/ardour/ardour/auditioner.h
@@ -40,7 +40,7 @@ class Auditioner : public AudioTrack
Auditioner (Session&);
~Auditioner ();
- void audition_region (AudioRegion&);
+ void audition_region (boost::shared_ptr<Region>);
ARDOUR::AudioPlaylist& prepare_playlist ();
void audition_current_playlist ();
@@ -54,7 +54,7 @@ class Auditioner : public AudioTrack
bool active() const { return g_atomic_int_get (&_active); }
private:
- AudioRegion *the_region;
+ boost::shared_ptr<AudioRegion> the_region;
jack_nframes_t current_frame;
mutable gint _active;
Glib::Mutex lock;
diff --git a/libs/ardour/ardour/automation_event.h b/libs/ardour/ardour/automation_event.h
index dad94161d0..a3b84289c1 100644
--- a/libs/ardour/ardour/automation_event.h
+++ b/libs/ardour/ardour/automation_event.h
@@ -27,8 +27,11 @@
#include <sigc++/signal.h>
#include <glibmm/thread.h>
+
#include <pbd/undo.h>
#include <pbd/xml++.h>
+#include <pbd/statefuldestructible.h>
+
#include <ardour/ardour.h>
#include <ardour/state_manager.h>
@@ -51,7 +54,7 @@ struct ControlEvent {
};
-class AutomationList : public StateManager, public Stateful
+ class AutomationList : public StateManager, public PBD::StatefulDestructible
{
public:
typedef std::list<ControlEvent*> AutomationEventList;
diff --git a/libs/ardour/ardour/crossfade.h b/libs/ardour/ardour/crossfade.h
index aea7b31852..ded41bbfda 100644
--- a/libs/ardour/ardour/crossfade.h
+++ b/libs/ardour/ardour/crossfade.h
@@ -23,10 +23,12 @@
#include <vector>
#include <algorithm>
+#include <boost/shared_ptr.hpp>
#include <sigc++/signal.h>
#include <pbd/undo.h>
+#include <pbd/statefuldestructible.h>
#include <ardour/ardour.h>
#include <ardour/curve.h>
@@ -51,7 +53,7 @@ struct CrossfadeState : public StateManager::State {
bool active;
};
-class Crossfade : public Stateful, public StateManager
+class Crossfade : public PBD::StatefulDestructible, public StateManager
{
public:
@@ -62,7 +64,7 @@ class Crossfade : public Stateful, public StateManager
/* constructor for "fixed" xfades at each end of an internal overlap */
- Crossfade (ARDOUR::AudioRegion& in, ARDOUR::AudioRegion& out,
+ Crossfade (boost::shared_ptr<ARDOUR::AudioRegion> in, boost::shared_ptr<ARDOUR::AudioRegion> out,
jack_nframes_t position,
jack_nframes_t initial_length,
AnchorPoint);
@@ -71,12 +73,12 @@ class Crossfade : public Stateful, public StateManager
except the "internal" case.
*/
- Crossfade (ARDOUR::AudioRegion& in, ARDOUR::AudioRegion& out, CrossfadeModel, bool active);
+ Crossfade (boost::shared_ptr<ARDOUR::AudioRegion> in, boost::shared_ptr<ARDOUR::AudioRegion> out, CrossfadeModel, bool active);
/* copy constructor to copy a crossfade with new regions. used (for example)
when a playlist copy is made */
- Crossfade (const Crossfade &, ARDOUR::AudioRegion *, ARDOUR::AudioRegion *);
+ Crossfade (const Crossfade &, boost::shared_ptr<ARDOUR::AudioRegion>, boost::shared_ptr<ARDOUR::AudioRegion>);
/* the usual XML constructor */
@@ -88,8 +90,8 @@ class Crossfade : public Stateful, public StateManager
XMLNode& get_state (void);
int set_state (const XMLNode&);
- ARDOUR::AudioRegion& in() const { return *_in; }
- ARDOUR::AudioRegion& out() const { return *_out; }
+ boost::shared_ptr<ARDOUR::AudioRegion> in() const { return _in; }
+ boost::shared_ptr<ARDOUR::AudioRegion> out() const { return _out; }
jack_nframes_t read_at (Sample *buf, Sample *mixdown_buffer,
float *gain_buffer, jack_nframes_t position, jack_nframes_t cnt,
@@ -107,12 +109,12 @@ class Crossfade : public Stateful, public StateManager
return std::min (_in->layer(), _out->layer());
}
- bool involves (ARDOUR::AudioRegion& region) const {
- return _in == &region || _out == &region;
+ bool involves (boost::shared_ptr<ARDOUR::AudioRegion> region) const {
+ return _in == region || _out == region;
}
- bool involves (ARDOUR::AudioRegion& a, ARDOUR::AudioRegion& b) const {
- return (_in == &a && _out == &b) || (_in == &b && _out == &a);
+ bool involves (boost::shared_ptr<ARDOUR::AudioRegion> a, boost::shared_ptr<ARDOUR::AudioRegion> b) const {
+ return (_in == a && _out == b) || (_in == b && _out == a);
}
jack_nframes_t length() const { return _length; }
@@ -120,7 +122,6 @@ class Crossfade : public Stateful, public StateManager
jack_nframes_t position() const { return _position; }
sigc::signal<void,Crossfade*> Invalidated;
- sigc::signal<void> GoingAway;
bool covers (jack_nframes_t frame) const {
return _position <= frame && frame < _position + _length;
@@ -155,8 +156,8 @@ class Crossfade : public Stateful, public StateManager
static jack_nframes_t _short_xfade_length;
- ARDOUR::AudioRegion* _in;
- ARDOUR::AudioRegion* _out;
+ boost::shared_ptr<ARDOUR::AudioRegion> _in;
+ boost::shared_ptr<ARDOUR::AudioRegion> _out;
bool _active;
bool _in_update;
OverlapType overlap_type;
@@ -172,7 +173,7 @@ class Crossfade : public Stateful, public StateManager
static Sample* crossfade_buffer_in;
void initialize (bool savestate=true);
- int compute (ARDOUR::AudioRegion&, ARDOUR::AudioRegion&, CrossfadeModel);
+ int compute (boost::shared_ptr<ARDOUR::AudioRegion>, boost::shared_ptr<ARDOUR::AudioRegion>, CrossfadeModel);
bool update (bool force);
StateManager::State* state_factory (std::string why) const;
diff --git a/libs/ardour/ardour/diskstream.h b/libs/ardour/ardour/diskstream.h
index 858ed1af6f..2bce6a424f 100644
--- a/libs/ardour/ardour/diskstream.h
+++ b/libs/ardour/ardour/diskstream.h
@@ -34,7 +34,7 @@
#include <pbd/fastlog.h>
#include <pbd/ringbufferNPT.h>
#include <pbd/stateful.h>
-#include <pbd/destructible.h>
+#include <pbd/statefuldestructible.h>
#include <ardour/ardour.h>
#include <ardour/configuration.h>
@@ -54,7 +54,7 @@ class Session;
class Playlist;
class IO;
- class Diskstream : public Stateful, public sigc::trackable, public PBD::Destructible
+ class Diskstream : public sigc::trackable, public PBD::StatefulDestructible
{
public:
enum Flag {
@@ -134,7 +134,7 @@ class IO;
int set_loop (Location *loc);
- std::list<Region*>& last_capture_regions () { return _last_capture_regions; }
+ std::list<boost::shared_ptr<Region> >& last_capture_regions () { return _last_capture_regions; }
void handle_input_change (IOChange, void *src);
@@ -147,7 +147,7 @@ class IO;
static sigc::signal<void> DiskOverrun;
static sigc::signal<void> DiskUnderrun;
- static sigc::signal<void,list<Source*>*> DeleteSources;
+ static sigc::signal<void,std::list<boost::shared_ptr<Source> >*> DeleteSources;
protected:
friend class Session;
@@ -224,7 +224,7 @@ class IO;
virtual bool realtime_set_speed (double, bool global_change);
- std::list<Region*> _last_capture_regions;
+ std::list<boost::shared_ptr<Region> > _last_capture_regions;
virtual int use_pending_capture_data (XMLNode& node) = 0;
virtual void get_input_sources () = 0;
diff --git a/libs/ardour/ardour/io.h b/libs/ardour/ardour/io.h
index 7b5e72742d..ec29c6f843 100644
--- a/libs/ardour/ardour/io.h
+++ b/libs/ardour/ardour/io.h
@@ -31,7 +31,7 @@
#include <pbd/fastlog.h>
#include <pbd/undo.h>
-#include <pbd/stateful.h>
+#include <pbd/statefuldestructible.h>
#include <pbd/controllable.h>
#include <ardour/ardour.h>
@@ -65,7 +65,7 @@ class BufferSet;
* An IO can contain ports of varying types, making routes/inserts/etc with
* varied combinations of types (eg MIDI and audio) possible.
*/
-class IO : public Stateful, public ARDOUR::StateManager
+class IO : public PBD::StatefulDestructible, public ARDOUR::StateManager
{
public:
@@ -76,7 +76,7 @@ class IO : public Stateful, public ARDOUR::StateManager
int output_min = -1, int output_max = -1,
DataType default_type = DataType::AUDIO);
- virtual ~IO();
+virtual ~IO();
ChanCount input_minimum() const { return _input_minimum; }
ChanCount input_maximum() const { return _input_maximum; }
diff --git a/libs/ardour/ardour/location.h b/libs/ardour/ardour/location.h
index beae4a6e07..1052b74bd4 100644
--- a/libs/ardour/ardour/location.h
+++ b/libs/ardour/ardour/location.h
@@ -33,6 +33,7 @@
#include <pbd/undo.h>
#include <pbd/stateful.h>
+#include <pbd/statefuldestructible.h>
#include <ardour/ardour.h>
#include <ardour/state_manager.h>
@@ -41,7 +42,7 @@ using std::string;
namespace ARDOUR {
-class Location : public Stateful, public sigc::trackable
+class Location : public sigc::trackable, public PBD::StatefulDestructible
{
public:
enum Flags {
@@ -72,6 +73,7 @@ class Location : public Stateful, public sigc::trackable
}
Location (const Location& other);
+ Location (const XMLNode&);
Location* operator= (const Location& other);
jack_nframes_t start() { return _start; }
@@ -132,7 +134,7 @@ class Location : public Stateful, public sigc::trackable
bool set_flag_internal (bool yn, Flags flag);
};
-class Locations : public Stateful, public StateManager
+class Locations : public StateManager, public PBD::StatefulDestructible
{
public:
typedef std::list<Location *> LocationList;
diff --git a/libs/ardour/ardour/midi_diskstream.h b/libs/ardour/ardour/midi_diskstream.h
index bf64cedd08..e62121672f 100644
--- a/libs/ardour/ardour/midi_diskstream.h
+++ b/libs/ardour/ardour/midi_diskstream.h
@@ -85,7 +85,7 @@ class MidiDiskstream : public Diskstream
void monitor_input (bool);
- MidiSource* write_source() { return (MidiSource*)_write_source; }
+ boost::shared_ptr<SMFSource> write_source () { return _write_source; }
void set_destructive (bool yn); // doom!
@@ -153,7 +153,7 @@ class MidiDiskstream : public Diskstream
//RawMidi* _playback_wrap_buffer;
//RawMidi* _capture_wrap_buffer;
MidiPort* _source_port;
- SMFSource* _write_source; ///< aka capturing source
+ boost::shared_ptr<SMFSource> _write_source;
RingBufferNPT<CaptureTransition>* _capture_transition_buf;
//RingBufferNPT<RawMidi>::rw_vector _playback_vector;
//RingBufferNPT<RawMidi>::rw_vector _capture_vector;
diff --git a/libs/ardour/ardour/midi_playlist.h b/libs/ardour/ardour/midi_playlist.h
index 11627b5a07..36793b70ea 100644
--- a/libs/ardour/ardour/midi_playlist.h
+++ b/libs/ardour/ardour/midi_playlist.h
@@ -69,10 +69,7 @@ public:
(obj.*method) (states, _current_state_id);
}
- bool destroy_region (Region*);
-
- void get_equivalent_regions (const MidiRegion&, std::vector<MidiRegion*>&);
- void get_region_list_equivalent_regions (const MidiRegion&, std::vector<MidiRegion*>&);
+ bool destroy_region (boost::shared_ptr<Region>);
void drop_all_states ();
@@ -87,11 +84,11 @@ protected:
/* playlist "callbacks" */
void flush_notifications ();
- void finalize_split_region (Region *orig, Region *left, Region *right);
-
- void refresh_dependents (Region& region);
- void check_dependents (Region& region, bool norefresh);
- void remove_dependents (Region& region);
+ void finalize_split_region (boost::shared_ptr<Region> original, boost::shared_ptr<Region> left, boost::shared_ptr<Region> right);
+
+ void check_dependents (boost::shared_ptr<Region> region, bool norefresh);
+ void refresh_dependents (boost::shared_ptr<Region> region);
+ void remove_dependents (boost::shared_ptr<Region> region);
protected:
~MidiPlaylist (); /* public should use unref() */
@@ -100,7 +97,7 @@ private:
XMLNode& state (bool full_state);
void dump () const;
- bool region_changed (Change, Region*);
+ bool region_changed (Change, boost::shared_ptr<Region>);
};
} /* namespace ARDOUR */
diff --git a/libs/ardour/ardour/midi_region.h b/libs/ardour/ardour/midi_region.h
index 745d3fa4a8..a5c578b7cd 100644
--- a/libs/ardour/ardour/midi_region.h
+++ b/libs/ardour/ardour/midi_region.h
@@ -46,16 +46,9 @@ class MidiRingBuffer;
class MidiRegion : public Region
{
public:
- MidiRegion (MidiSource&, jack_nframes_t start, jack_nframes_t length, bool announce = true);
- MidiRegion (MidiSource&, jack_nframes_t start, jack_nframes_t length, const string& name, layer_t = 0, Region::Flag flags = Region::DefaultFlags, bool announce = true);
- MidiRegion (SourceList &, jack_nframes_t start, jack_nframes_t length, const string& name, layer_t = 0, Region::Flag flags = Region::DefaultFlags, bool announce = true);
- MidiRegion (const MidiRegion&, jack_nframes_t start, jack_nframes_t length, const string& name, layer_t = 0, Region::Flag flags = Region::DefaultFlags, bool announce = true);
- MidiRegion (const MidiRegion&);
- MidiRegion (MidiSource&, const XMLNode&);
- MidiRegion (SourceList &, const XMLNode&);
~MidiRegion();
- MidiSource& midi_source (uint32_t n=0) const;
+ boost::shared_ptr<MidiSource> midi_source (uint32_t n=0) const;
jack_nframes_t read_at (MidiRingBuffer& dst,
jack_nframes_t position,
@@ -77,6 +70,17 @@ class MidiRegion : public Region
UndoAction get_memento() const;
private:
+ friend class RegionFactory;
+
+ MidiRegion (boost::shared_ptr<MidiSource>, jack_nframes_t start, jack_nframes_t length);
+ MidiRegion (boost::shared_ptr<MidiSource>, jack_nframes_t start, jack_nframes_t length, const string& name, layer_t = 0, Region::Flag flags = Region::DefaultFlags);
+ MidiRegion (SourceList &, jack_nframes_t start, jack_nframes_t length, const string& name, layer_t = 0, Region::Flag flags = Region::DefaultFlags);
+ MidiRegion (boost::shared_ptr<const MidiRegion>, jack_nframes_t start, jack_nframes_t length, const string& name, layer_t = 0, Region::Flag flags = Region::DefaultFlags);
+ MidiRegion (boost::shared_ptr<const MidiRegion>);
+ MidiRegion (boost::shared_ptr<MidiSource>, const XMLNode&);
+ MidiRegion (SourceList &, const XMLNode&);
+
+ private:
friend class Playlist;
private:
diff --git a/libs/ardour/ardour/playlist.h b/libs/ardour/ardour/playlist.h
index 59fd0f8bc5..c04b59286f 100644
--- a/libs/ardour/ardour/playlist.h
+++ b/libs/ardour/ardour/playlist.h
@@ -25,6 +25,7 @@
#include <set>
#include <map>
#include <list>
+#include <boost/shared_ptr.hpp>
#include <sys/stat.h>
@@ -34,6 +35,7 @@
#include <pbd/undo.h>
#include <pbd/stateful.h>
+#include <pbd/statefuldestructible.h>
#include <ardour/ardour.h>
#include <ardour/crossfade_compare.h>
@@ -46,16 +48,16 @@ namespace ARDOUR {
class Session;
class Region;
-class Playlist : public Stateful, public StateManager {
+class Playlist : public StateManager, public PBD::StatefulDestructible {
public:
- typedef list<Region*> RegionList;
+ typedef list<boost::shared_ptr<Region> > RegionList;
Playlist (Session&, const XMLNode&, DataType type, bool hidden = false);
Playlist (Session&, string name, DataType type, bool hidden = false);
Playlist (const Playlist&, string name, bool hidden = false);
Playlist (const Playlist&, jack_nframes_t start, jack_nframes_t cnt, string name, bool hidden = false);
- virtual void clear (bool with_delete = false, bool with_save = true);
+ virtual void clear (bool with_save = true);
virtual void dump () const;
virtual UndoAction get_memento() const = 0;
@@ -82,17 +84,17 @@ class Playlist : public Stateful, public StateManager {
PBD::ID id() { return _id; }
/* Editing operations */
- void add_region (const Region&, jack_nframes_t position, float times = 1, bool with_save = true);
- void remove_region (Region *);
- void get_equivalent_regions (const Region&, std::vector<Region*>&);
- void get_region_list_equivalent_regions (const Region&, std::vector<Region*>&);
- void replace_region (Region& old, Region& newr, jack_nframes_t pos);
- void split_region (Region&, jack_nframes_t position);
+ void add_region (boost::shared_ptr<Region>, jack_nframes_t position, float times = 1, bool with_save = true);
+ void remove_region (boost::shared_ptr<Region>);
+ void get_equivalent_regions (boost::shared_ptr<Region>, std::vector<boost::shared_ptr<Region> >&);
+ void get_region_list_equivalent_regions (boost::shared_ptr<Region>, std::vector<boost::shared_ptr<Region> >&);
+ void replace_region (boost::shared_ptr<Region> old, boost::shared_ptr<Region> newr, jack_nframes_t pos);
+ void split_region (boost::shared_ptr<Region>, jack_nframes_t position);
void partition (jack_nframes_t start, jack_nframes_t end, bool just_top_level);
- void duplicate (Region&, jack_nframes_t position, float times);
+ void duplicate (boost::shared_ptr<Region>, jack_nframes_t position, float times);
void nudge_after (jack_nframes_t start, jack_nframes_t distance, bool forwards);
- Region* find_region (const PBD::ID&) const;
+ boost::shared_ptr<Region> find_region (const PBD::ID&) const;
Playlist* cut (list<AudioRange>&, bool result_is_hidden = true);
Playlist* copy (list<AudioRange>&, bool result_is_hidden = true);
@@ -102,25 +104,24 @@ class Playlist : public Stateful, public StateManager {
RegionList* regions_at (jack_nframes_t frame);
RegionList* regions_touched (jack_nframes_t start, jack_nframes_t end);
- Region* top_region_at (jack_nframes_t frame);
+ boost::shared_ptr<Region> top_region_at (jack_nframes_t frame);
- Region* find_next_region (jack_nframes_t frame, RegionPoint point, int dir);
+ boost::shared_ptr<Region> find_next_region (jack_nframes_t frame, RegionPoint point, int dir);
- template<class T> void foreach_region (T *t, void (T::*func)(Region *, void *), void *arg);
- template<class T> void foreach_region (T *t, void (T::*func)(Region *));
+ template<class T> void foreach_region (T *t, void (T::*func)(boost::shared_ptr<Region>, void *), void *arg);
+ template<class T> void foreach_region (T *t, void (T::*func)(boost::shared_ptr<Region>));
XMLNode& get_state ();
int set_state (const XMLNode&);
XMLNode& get_template ();
- sigc::signal<void,Region *> RegionAdded;
- sigc::signal<void,Region *> RegionRemoved;
+ sigc::signal<void,boost::shared_ptr<Region> > RegionAdded;
+ sigc::signal<void,boost::shared_ptr<Region> > RegionRemoved;
sigc::signal<void,Playlist*,bool> InUse;
sigc::signal<void> Modified;
sigc::signal<void> NameChanged;
sigc::signal<void> LengthChanged;
sigc::signal<void> LayeringChanged;
- sigc::signal<void,Playlist *> GoingAway;
sigc::signal<void> StatePushed;
static sigc::signal<void,Playlist*> PlaylistCreated;
@@ -131,10 +132,10 @@ class Playlist : public Stateful, public StateManager {
void freeze ();
void thaw ();
- void raise_region (Region&);
- void lower_region (Region&);
- void raise_region_to_top (Region&);
- void lower_region_to_bottom (Region&);
+ void raise_region (boost::shared_ptr<Region>);
+ void lower_region (boost::shared_ptr<Region>);
+ void raise_region_to_top (boost::shared_ptr<Region>);
+ void lower_region_to_bottom (boost::shared_ptr<Region>);
uint32_t read_data_count() const { return _read_data_count; }
@@ -145,7 +146,7 @@ class Playlist : public Stateful, public StateManager {
/* destructive editing */
- virtual bool destroy_region (Region *) = 0;
+ virtual bool destroy_region (boost::shared_ptr<Region>) = 0;
protected:
friend class Session;
@@ -216,8 +217,8 @@ class Playlist : public Stateful, public StateManager {
void release_notifications ();
virtual void flush_notifications ();
- void notify_region_removed (Region *);
- void notify_region_added (Region *);
+ void notify_region_removed (boost::shared_ptr<Region>);
+ void notify_region_added (boost::shared_ptr<Region>);
void notify_length_changed ();
void notify_layering_changed ();
void notify_modified ();
@@ -225,11 +226,11 @@ class Playlist : public Stateful, public StateManager {
void mark_session_dirty();
- void region_changed_proxy (Change, Region*);
- virtual bool region_changed (Change, Region*);
+ void region_changed_proxy (Change, boost::shared_ptr<Region>);
+ virtual bool region_changed (Change, boost::shared_ptr<Region>);
- void region_bounds_changed (Change, Region *);
- void region_deleted (Region *);
+ void region_bounds_changed (Change, boost::shared_ptr<Region>);
+ void region_deleted (boost::shared_ptr<Region>);
void sort_regions ();
@@ -240,11 +241,11 @@ class Playlist : public Stateful, public StateManager {
void splice_unlocked ();
- virtual void finalize_split_region (Region *original, Region *left, Region *right) {}
+ virtual void finalize_split_region (boost::shared_ptr<Region> original, boost::shared_ptr<Region> left, boost::shared_ptr<Region> right) {}
- virtual void check_dependents (Region& region, bool norefresh) {}
- virtual void refresh_dependents (Region& region) {}
- virtual void remove_dependents (Region& region) {}
+ virtual void check_dependents (boost::shared_ptr<Region> region, bool norefresh) {}
+ virtual void refresh_dependents (boost::shared_ptr<Region> region) {}
+ virtual void remove_dependents (boost::shared_ptr<Region> region) {}
virtual XMLNode& state (bool);
@@ -253,9 +254,9 @@ class Playlist : public Stateful, public StateManager {
void save_state (std::string why);
void maybe_save_state (std::string why);
- void add_region_internal (Region *, jack_nframes_t position, bool delay_sort = false);
+ void add_region_internal (boost::shared_ptr<Region>, jack_nframes_t position, bool delay_sort = false);
- int remove_region_internal (Region *, bool delay_sort = false);
+ int remove_region_internal (boost::shared_ptr<Region>, bool delay_sort = false);
RegionList *find_regions_at (jack_nframes_t frame);
void copy_regions (RegionList&) const;
void partition_internal (jack_nframes_t start, jack_nframes_t end, bool cutting, RegionList& thawlist);
@@ -268,7 +269,7 @@ class Playlist : public Stateful, public StateManager {
Playlist *copy (jack_nframes_t start, jack_nframes_t cnt, bool result_is_hidden);
- int move_region_to_layer (layer_t, Region& r, int dir);
+ int move_region_to_layer (layer_t, boost::shared_ptr<Region> r, int dir);
void relayer ();
static Playlist* copyPlaylist (const Playlist&, jack_nframes_t start, jack_nframes_t length,
@@ -277,7 +278,7 @@ class Playlist : public Stateful, public StateManager {
void unset_freeze_parent (Playlist*);
void unset_freeze_child (Playlist*);
- void timestamp_layer_op (Region&);
+ void timestamp_layer_op (boost::shared_ptr<Region>);
PBD::ID _id;
};
diff --git a/libs/ardour/ardour/playlist_templates.h b/libs/ardour/ardour/playlist_templates.h
index d3d682b8c5..7ce6c1818c 100644
--- a/libs/ardour/ardour/playlist_templates.h
+++ b/libs/ardour/ardour/playlist_templates.h
@@ -30,14 +30,14 @@ template<class T> void AudioPlaylist::foreach_crossfade (T *t, void (T::*func)(C
}
}
-template<class T> void Playlist::foreach_region (T *t, void (T::*func)(Region *, void *), void *arg) {
+template<class T> void Playlist::foreach_region (T *t, void (T::*func)(boost::shared_ptr<Region>, void *), void *arg) {
RegionLock rlock (this, false);
for (RegionList::iterator i = regions.begin(); i != regions.end(); i++) {
(t->*func) ((*i), arg);
}
}
-template<class T> void Playlist::foreach_region (T *t, void (T::*func)(Region *)) {
+template<class T> void Playlist::foreach_region (T *t, void (T::*func)(boost::shared_ptr<Region>)) {
RegionLock rlock (this, false);
for (RegionList::const_iterator i = regions.begin(); i != regions.end(); i++) {
(t->*func) (*i);
diff --git a/libs/ardour/ardour/plugin.h b/libs/ardour/ardour/plugin.h
index a199e99933..2117a9d58a 100644
--- a/libs/ardour/ardour/plugin.h
+++ b/libs/ardour/ardour/plugin.h
@@ -24,7 +24,7 @@
#include <boost/shared_ptr.hpp>
#include <sigc++/signal.h>
-#include <pbd/stateful.h>
+#include <pbd/statefuldestructible.h>
#include <pbd/controllable.h>
#include <jack/types.h>
@@ -78,8 +78,7 @@ class PluginInfo {
typedef boost::shared_ptr<PluginInfo> PluginInfoPtr;
typedef std::list<PluginInfoPtr> PluginInfoList;
-class Plugin : public Stateful, public sigc::trackable
-
+class Plugin : public PBD::StatefulDestructible, public sigc::trackable
{
public:
Plugin (ARDOUR::AudioEngine&, ARDOUR::Session&);
@@ -141,7 +140,6 @@ class Plugin : public Stateful, public sigc::trackable
virtual bool has_editor() const = 0;
sigc::signal<void,uint32_t,float> ParameterChanged;
- sigc::signal<void,Plugin *> GoingAway;
PBD::Controllable *get_nth_control (uint32_t);
diff --git a/libs/ardour/ardour/redirect.h b/libs/ardour/ardour/redirect.h
index b9e91e1cfd..4015c708de 100644
--- a/libs/ardour/ardour/redirect.h
+++ b/libs/ardour/ardour/redirect.h
@@ -92,7 +92,6 @@ class Redirect : public IO
sigc::signal<void,Redirect*,void*> placement_changed;
sigc::signal<void,Redirect*,bool> AutomationPlaybackChanged;
sigc::signal<void,Redirect*,uint32_t> AutomationChanged;
- sigc::signal<void,Redirect*> GoingAway;
static sigc::signal<void,Redirect*> RedirectCreated;
diff --git a/libs/ardour/ardour/region.h b/libs/ardour/ardour/region.h
index 80504ce044..1abba574f1 100644
--- a/libs/ardour/ardour/region.h
+++ b/libs/ardour/ardour/region.h
@@ -22,8 +22,10 @@
#define __ardour_region_h__
#include <vector>
+#include <boost/shared_ptr.hpp>
#include <pbd/undo.h>
+#include <pbd/statefuldestructible.h>
#include <ardour/ardour.h>
#include <ardour/state_manager.h>
@@ -56,10 +58,10 @@ struct RegionState : public StateManager::State
mutable RegionEditState _first_edit;
};
-class Region : public Stateful, public StateManager
+class Region : public PBD::StatefulDestructible, public StateManager
{
public:
- typedef std::vector<Source *> SourceList;
+ typedef std::vector<boost::shared_ptr<Source> > SourceList;
enum Flag {
Muted = 0x1,
@@ -94,15 +96,6 @@ class Region : public Stateful, public StateManager
static Change LayerChanged;
static Change HiddenChanged;
- Region (Source& src, jack_nframes_t start, jack_nframes_t length,
- const string& name, DataType type, layer_t = 0, Flag flags = DefaultFlags);
- Region (SourceList& srcs, jack_nframes_t start, jack_nframes_t length,
- const string& name, DataType type, layer_t = 0, Flag flags = DefaultFlags);
- Region (const Region&, jack_nframes_t start, jack_nframes_t length,
- const string& name, layer_t = 0, Flag flags = DefaultFlags);
- Region (const Region&);
- Region (SourceList& srcs, const XMLNode&);
- Region (Source& src, const XMLNode&);
virtual ~Region();
const PBD::ID& id() const { return _id; }
@@ -151,11 +144,11 @@ class Region : public Stateful, public StateManager
return ARDOUR::coverage (_position, _position + _length - 1, start, end);
}
- bool equivalent (const Region&) const;
- bool size_equivalent (const Region&) const;
- bool overlap_equivalent (const Region&) const;
- bool region_list_equivalent (const Region&) const;
- bool source_equivalent (const Region&) const;
+ bool equivalent (boost::shared_ptr<const Region>) const;
+ bool size_equivalent (boost::shared_ptr<const Region>) const;
+ bool overlap_equivalent (boost::shared_ptr<const Region>) const;
+ bool region_list_equivalent (boost::shared_ptr<const Region>) const;
+ bool source_equivalent (boost::shared_ptr<const Region>) const;
/* EDITING OPERATIONS */
@@ -194,12 +187,10 @@ class Region : public Stateful, public StateManager
void set_playlist (ARDOUR::Playlist*);
- void lock_sources ();
- void unlock_sources ();
- void source_deleted (Source*);
+ void source_deleted (boost::shared_ptr<Source>);
- Source& source (uint32_t n=0) const { return *_sources[ (n < _sources.size()) ? n : 0 ]; }
- uint32_t n_channels() const { return _sources.size(); }
+ boost::shared_ptr<Source> source (uint32_t n=0) const { return _sources[ (n < _sources.size()) ? n : 0 ]; }
+ uint32_t n_channels() const { return _sources.size(); }
std::vector<string> master_source_names();
@@ -210,24 +201,24 @@ class Region : public Stateful, public StateManager
virtual XMLNode& state (bool);
virtual int set_state (const XMLNode&);
- sigc::signal<void,Region*> GoingAway;
-
- /* This is emitted only when a new id is assigned. Therefore,
- in a pure Region copy, it will not be emitted.
-
- It must be emitted by derived classes, not Region
- itself, to permit dynamic_cast<> to be used to
- infer the type of Region.
- */
-
- static sigc::signal<void,Region*> CheckNewRegion;
-
- Region* get_parent();
+ boost::shared_ptr<Region> get_parent();
uint64_t last_layer_op() const { return _last_layer_op; }
void set_last_layer_op (uint64_t when);
protected:
+ friend class RegionFactory;
+
+ Region (boost::shared_ptr<Source> src, jack_nframes_t start, jack_nframes_t length,
+ const string& name, DataType type, layer_t = 0, Flag flags = DefaultFlags);
+ Region (SourceList& srcs, jack_nframes_t start, jack_nframes_t length,
+ const string& name, DataType type, layer_t = 0, Flag flags = DefaultFlags);
+ Region (boost::shared_ptr<const Region>, jack_nframes_t start, jack_nframes_t length, const string& name, layer_t = 0, Flag flags = DefaultFlags);
+ Region (boost::shared_ptr<const Region>);
+ Region (boost::shared_ptr<Source> src, const XMLNode&);
+ Region (SourceList& srcs, const XMLNode&);
+
+ protected:
XMLNode& get_short_state (); /* used only by Session */
/* state management */
diff --git a/libs/ardour/ardour/region_factory.h b/libs/ardour/ardour/region_factory.h
index f72c0a52d8..bd5089f512 100644
--- a/libs/ardour/ardour/region_factory.h
+++ b/libs/ardour/ardour/region_factory.h
@@ -10,12 +10,30 @@ namespace ARDOUR {
class Session;
-Region* createRegion (const Region&, jack_nframes_t start,
- jack_nframes_t length, std::string name,
- layer_t = 0, Region::Flag flags = Region::DefaultFlags);
-// Region* createRegion (const Region&, std::string name);
-Region* createRegion (const Region&);
-Region* createRegion (Session&, XMLNode&, bool);
+class RegionFactory {
+
+ public:
+ /** This is emitted only when a new id is assigned. Therefore,
+ in a pure Region copy, it will not be emitted.
+
+ It must be emitted by derived classes, not Region
+ itself, to permit dynamic_cast<> to be used to
+ infer the type of Region.
+ */
+ static sigc::signal<void,boost::shared_ptr<Region> > CheckNewRegion;
+
+ static boost::shared_ptr<Region> create (boost::shared_ptr<Region>, jack_nframes_t start,
+ jack_nframes_t length, std::string name,
+ layer_t = 0, Region::Flag flags = Region::DefaultFlags, bool announce = true);
+ static boost::shared_ptr<Region> create (boost::shared_ptr<AudioRegion>, jack_nframes_t start,
+ jack_nframes_t length, std::string name,
+ layer_t = 0, Region::Flag flags = Region::DefaultFlags, bool announce = true);
+ static boost::shared_ptr<Region> create (boost::shared_ptr<Source>, jack_nframes_t start, jack_nframes_t length, const string& name, layer_t = 0, Region::Flag flags = Region::DefaultFlags, bool announce = true);
+ static boost::shared_ptr<Region> create (SourceList &, jack_nframes_t start, jack_nframes_t length, const string& name, layer_t = 0, Region::Flag flags = Region::DefaultFlags, bool announce = true);
+ static boost::shared_ptr<Region> create (boost::shared_ptr<Region>);
+ static boost::shared_ptr<Region> create (Session&, XMLNode&, bool);
+ static boost::shared_ptr<Region> create (SourceList &, const XMLNode&);
+};
}
diff --git a/libs/ardour/ardour/reverse.h b/libs/ardour/ardour/reverse.h
index 05ea8a1353..c60df990f2 100644
--- a/libs/ardour/ardour/reverse.h
+++ b/libs/ardour/ardour/reverse.h
@@ -30,7 +30,7 @@ class Reverse : public AudioFilter {
Reverse (ARDOUR::Session&);
~Reverse ();
- int run (ARDOUR::AudioRegion&);
+ int run (boost::shared_ptr<ARDOUR::AudioRegion>);
};
} /* namespace */
diff --git a/libs/ardour/ardour/route.h b/libs/ardour/ardour/route.h
index 5b9c92dc71..7abc69f059 100644
--- a/libs/ardour/ardour/route.h
+++ b/libs/ardour/ardour/route.h
@@ -56,7 +56,7 @@ enum mute_type {
MAIN_OUTS = 0x8
};
- class Route : public IO, public PBD::Destructible
+class Route : public IO
{
protected:
diff --git a/libs/ardour/ardour/session.h b/libs/ardour/ardour/session.h
index eeb905a301..ee87848dcb 100644
--- a/libs/ardour/ardour/session.h
+++ b/libs/ardour/ardour/session.h
@@ -1,22 +1,22 @@
-/*
- Copyright (C) 2000 Paul Davis
+ /*
+ Copyright (C) 2000 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 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.
+ 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.
+ 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.
- $Id$
-*/
+ $Id$
+ */
#ifndef __ardour_session_h__
#define __ardour_session_h__
@@ -27,6 +27,9 @@
#include <vector>
#include <set>
#include <stack>
+
+#include <boost/weak_ptr.hpp>
+
#include <stdint.h>
#include <sndfile.h>
@@ -37,11 +40,13 @@
#include <pbd/undo.h>
#include <pbd/pool.h>
#include <pbd/rcu.h>
+#include <pbd/statefuldestructible.h>
#include <midi++/types.h>
#include <midi++/mmc.h>
#include <pbd/stateful.h>
+#include <pbd/destructible.h>
#include <ardour/ardour.h>
#include <ardour/configuration.h>
@@ -108,12 +113,10 @@ struct RouteGroup;
using std::vector;
using std::string;
-using std::list;
using std::map;
using std::set;
-class Session : public sigc::trackable, public Stateful
-
+class Session : public sigc::trackable, public PBD::StatefulDestructible
{
private:
typedef std::pair<boost::shared_ptr<Route>,bool> RouteBooleanState;
@@ -133,7 +136,7 @@ class Session : public sigc::trackable, public Stateful
MTC,
JACK
};
-
+
enum AutoConnectOption {
AutoConnectPhysical = 0x1,
AutoConnectMaster = 0x2
@@ -185,6 +188,8 @@ class Session : public sigc::trackable, public Stateful
Route* route;
};
+ boost::shared_ptr<Region> region;
+
list<AudioRange> audio_range;
list<MusicRange> music_range;
@@ -339,11 +344,9 @@ class Session : public sigc::trackable, public Stateful
void disable_record (bool rt_context, bool force = false);
void step_back_from_record ();
- sigc::signal<void> going_away;
-
/* Proxy signal for region hidden changes */
- sigc::signal<void,Region*> RegionHiddenChange;
+ sigc::signal<void,boost::shared_ptr<Region> > RegionHiddenChange;
/* Emitted when all i/o connections are complete */
@@ -382,7 +385,7 @@ class Session : public sigc::trackable, public Stateful
int wipe ();
//int wipe_diskstream (AudioDiskstream *);
- int remove_region_from_region_list (Region&);
+ int remove_region_from_region_list (boost::shared_ptr<Region>);
jack_nframes_t get_maximum_extent () const;
jack_nframes_t current_end_frame() const { return end_location->start(); }
@@ -633,21 +636,21 @@ class Session : public sigc::trackable, public Stateful
/* region info */
- sigc::signal<void,Region *> RegionAdded;
- sigc::signal<void,Region *> RegionRemoved;
+ sigc::signal<void,boost::shared_ptr<Region> > RegionAdded;
+ sigc::signal<void,boost::shared_ptr<Region> > RegionRemoved;
int region_name (string& result, string base = string(""), bool newlevel = false) const;
string new_region_name (string);
string path_from_region_name (string name, string identifier);
- Region* find_whole_file_parent (Region& child);
- void find_equivalent_playlist_regions (Region&, std::vector<Region*>& result);
+ boost::shared_ptr<Region> find_whole_file_parent (Region&);
+ void find_equivalent_playlist_regions (boost::shared_ptr<Region>, std::vector<boost::shared_ptr<Region> >& result);
- Region* XMLRegionFactory (const XMLNode&, bool full);
- AudioRegion* XMLAudioRegionFactory (const XMLNode&, bool full);
- MidiRegion* XMLMidiRegionFactory (const XMLNode&, bool full);
+ boost::shared_ptr<Region> XMLRegionFactory (const XMLNode&, bool full);
+ boost::shared_ptr<AudioRegion> XMLAudioRegionFactory (const XMLNode&, bool full);
+ boost::shared_ptr<MidiRegion> XMLMidiRegionFactory (const XMLNode&, bool full);
- template<class T> void foreach_region (T *obj, void (T::*func)(Region *));
+ template<class T> void foreach_region (T *obj, void (T::*func)(boost::shared_ptr<Region>));
/* source management */
@@ -661,8 +664,7 @@ class Session : public sigc::trackable, public Stateful
string pathname;
/* result */
- std::vector<Region*> new_regions;
-
+ std::vector<boost::shared_ptr<Region> > new_regions;
};
int import_audiofile (import_status&);
@@ -675,9 +677,9 @@ class Session : public sigc::trackable, public Stateful
int start_audio_export (ARDOUR::AudioExportSpecification&);
int stop_audio_export (ARDOUR::AudioExportSpecification&);
- void add_source (Source *);
- void remove_source (Source *);
- int cleanup_audio_file_source (AudioFileSource&);
+ void add_source (boost::shared_ptr<Source>);
+ void remove_source (boost::weak_ptr<Source>);
+ int cleanup_audio_file_source (boost::shared_ptr<AudioFileSource>);
struct cleanup_report {
vector<string> paths;
@@ -687,8 +689,8 @@ class Session : public sigc::trackable, public Stateful
int cleanup_sources (cleanup_report&);
int cleanup_trash_sources (cleanup_report&);
- int destroy_region (Region*);
- int destroy_regions (list<Region*>);
+ int destroy_region (boost::shared_ptr<Region>);
+ int destroy_regions (std::list<boost::shared_ptr<Region> >);
int remove_last_capture ();
@@ -706,14 +708,14 @@ class Session : public sigc::trackable, public Stateful
static sigc::signal<int> AskAboutPendingState;
- sigc::signal<void,Source *> SourceAdded;
- sigc::signal<void,Source *> SourceRemoved;
+ sigc::signal<void,boost::shared_ptr<Source> > SourceAdded;
+ sigc::signal<void,boost::shared_ptr<Source> > SourceRemoved;
- AudioFileSource *create_audio_source_for_session (ARDOUR::AudioDiskstream&, uint32_t which_channel, bool destructive);
+ boost::shared_ptr<AudioFileSource> create_audio_source_for_session (ARDOUR::AudioDiskstream&, uint32_t which_channel, bool destructive);
- MidiSource *create_midi_source_for_session (ARDOUR::MidiDiskstream&);
+ boost::shared_ptr<MidiSource> create_midi_source_for_session (ARDOUR::MidiDiskstream&);
- Source *source_by_id (const PBD::ID&);
+ boost::shared_ptr<Source> source_by_id (const PBD::ID&);
/* playlist management */
@@ -750,7 +752,7 @@ class Session : public sigc::trackable, public Stateful
boost::shared_ptr<Auditioner> the_auditioner() { return auditioner; }
void audition_playlist ();
- void audition_region (Region&);
+ void audition_region (boost::shared_ptr<Region>);
void cancel_audition ();
bool is_auditioning () const;
@@ -758,7 +760,8 @@ class Session : public sigc::trackable, public Stateful
/* flattening stuff */
- int write_one_audio_track (AudioTrack&, jack_nframes_t start, jack_nframes_t cnt, bool overwrite, vector<Source*>&, InterThreadInfo& wot);
+ int write_one_audio_track (AudioTrack&, jack_nframes_t start, jack_nframes_t cnt, bool overwrite, vector<boost::shared_ptr<Source> >&,
+ InterThreadInfo& wot);
int freeze (InterThreadInfo&);
/* session-wide solo/mute/rec-enable */
@@ -861,12 +864,15 @@ class Session : public sigc::trackable, public Stateful
void commit_reversible_command (Command* cmd = 0);
void add_command (Command *const cmd) {
- current_trans.add_command (cmd);
+ current_trans->add_command (cmd);
}
+ std::map<PBD::ID, PBD::StatefulDestructible*> registry;
+
// these commands are implemented in libs/ardour/session_command.cc
Command *memento_command_factory(XMLNode *n);
- void register_with_memento_command_factory(PBD::ID, Stateful *);
+ void register_with_memento_command_factory(PBD::ID, PBD::StatefulDestructible *);
+
class GlobalSoloStateCommand : public Command
{
GlobalRouteBooleanState before, after;
@@ -936,17 +942,17 @@ class Session : public sigc::trackable, public Stateful
/* tempo FX */
struct TimeStretchRequest {
- ARDOUR::AudioRegion* region;
+ boost::shared_ptr<ARDOUR::AudioRegion> region;
float fraction; /* session: read ; GUI: write */
float progress; /* session: write ; GUI: read */
bool running; /* read/write */
bool quick_seek; /* GUI: write */
bool antialias; /* GUI: write */
- TimeStretchRequest () : region (0) {}
+ TimeStretchRequest () {}
};
- AudioRegion* tempoize_region (TimeStretchRequest&);
+ boost::shared_ptr<AudioRegion> tempoize_region (TimeStretchRequest&);
string raid_path() const;
void set_raid_path(string);
@@ -1558,27 +1564,27 @@ class Session : public sigc::trackable, public Stateful
/* REGION MANAGEMENT */
mutable Glib::Mutex region_lock;
- typedef map<PBD::ID,Region *> RegionList;
+ typedef map<PBD::ID,boost::shared_ptr<Region> > RegionList;
RegionList regions;
- void region_renamed (Region *);
- void region_changed (Change, Region *);
- void add_region (Region *);
- void remove_region (Region *);
+ void region_renamed (boost::shared_ptr<Region>);
+ void region_changed (Change, boost::shared_ptr<Region>);
+ void add_region (boost::shared_ptr<Region>);
+ void remove_region (boost::shared_ptr<Region>);
int load_regions (const XMLNode& node);
/* SOURCES */
mutable Glib::Mutex source_lock;
- typedef std::map<PBD::ID,Source *> SourceList;
+ typedef std::map<PBD::ID,boost::shared_ptr<Source> > SourceMap;
- SourceList sources;
+ SourceMap sources;
int load_sources (const XMLNode& node);
XMLNode& get_sources_as_xml ();
- Source *XMLSourceFactory (const XMLNode&);
+ boost::shared_ptr<Source> XMLSourceFactory (const XMLNode&);
/* PLAYLISTS */
@@ -1609,9 +1615,9 @@ class Session : public sigc::trackable, public Stateful
NamedSelection *named_selection_factory (string name);
NamedSelection *XMLNamedSelectionFactory (const XMLNode&);
- /* CURVES and AUTOMATION LISTS */
- std::map<PBD::ID, Curve*> curves;
- std::map<PBD::ID, AutomationList*> automation_lists;
+ /* CURVES and AUTOMATION LISTS */
+ std::map<PBD::ID, Curve*> curves;
+ std::map<PBD::ID, AutomationList*> automation_lists;
/* DEFAULT FADE CURVES */
@@ -1621,9 +1627,9 @@ class Session : public sigc::trackable, public Stateful
/* AUDITIONING */
boost::shared_ptr<Auditioner> auditioner;
- void set_audition (AudioRegion*);
+ void set_audition (boost::shared_ptr<Region>);
void non_realtime_set_audition ();
- AudioRegion *pending_audition_region;
+ boost::shared_ptr<Region> pending_audition_region;
/* EXPORT */
@@ -1692,7 +1698,7 @@ class Session : public sigc::trackable, public Stateful
void reverse_diskstream_buffers ();
UndoHistory history;
- UndoTransaction current_trans;
+ UndoTransaction* current_trans;
GlobalRouteBooleanState get_global_route_boolean (bool (Route::*method)(void) const);
GlobalRouteMeterState get_global_route_metering ();
diff --git a/libs/ardour/ardour/session_region.h b/libs/ardour/ardour/session_region.h
index fae950baa6..bce025adbe 100644
--- a/libs/ardour/ardour/session_region.h
+++ b/libs/ardour/ardour/session_region.h
@@ -6,7 +6,7 @@
namespace ARDOUR {
-template<class T> void Session::foreach_region (T *obj, void (T::*func)(Region *))
+template<class T> void Session::foreach_region (T *obj, void (T::*func)(boost::shared_ptr<Region>))
{
Glib::Mutex::Lock lm (region_lock);
for (RegionList::iterator i = regions.begin(); i != regions.end(); i++) {
@@ -14,6 +14,6 @@ template<class T> void Session::foreach_region (T *obj, void (T::*func)(Region *
}
}
-}
+} // namespace ARDOUR
#endif /* __ardour_session_region_h__ */
diff --git a/libs/ardour/ardour/source.h b/libs/ardour/ardour/source.h
index a8d0fed20b..1728cdb477 100644
--- a/libs/ardour/ardour/source.h
+++ b/libs/ardour/ardour/source.h
@@ -24,15 +24,16 @@
#include <string>
#include <sigc++/signal.h>
+#include <boost/enable_shared_from_this.hpp>
-#include <pbd/stateful.h>
+#include <pbd/statefuldestructible.h>
#include <ardour/ardour.h>
#include <ardour/data_type.h>
namespace ARDOUR {
-class Source : public Stateful, public sigc::trackable
+class Source : public PBD::StatefulDestructible, public sigc::trackable, public boost::enable_shared_from_this<Source>
{
public:
Source (std::string name, DataType type);
@@ -42,13 +43,9 @@ class Source : public Stateful, public sigc::trackable
std::string name() const { return _name; }
int set_name (std::string str, bool destructive);
- const PBD::ID& id() const { return _id; }
+ DataType type() { return _type; }
- uint32_t use_cnt() const { return _use_cnt; }
- void use ();
- void release ();
-
- virtual void mark_for_remove() = 0;
+ const PBD::ID& id() const { return _id; }
time_t timestamp() const { return _timestamp; }
void stamp (time_t when) { _timestamp = when; }
@@ -58,18 +55,19 @@ class Source : public Stateful, public sigc::trackable
virtual jack_nframes_t natural_position() const { return 0; }
+ virtual void mark_for_remove() = 0;
+ virtual void mark_streaming_write_completed () = 0;
+
XMLNode& get_state ();
int set_state (const XMLNode&);
-
+
static sigc::signal<void,Source*> SourceCreated;
- sigc::signal<void,Source *> GoingAway;
protected:
void update_length (jack_nframes_t pos, jack_nframes_t cnt);
string _name;
DataType _type;
- uint32_t _use_cnt;
time_t _timestamp;
jack_nframes_t _length;
diff --git a/libs/ardour/ardour/source_factory.h b/libs/ardour/ardour/source_factory.h
new file mode 100644
index 0000000000..2b25752a0d
--- /dev/null
+++ b/libs/ardour/ardour/source_factory.h
@@ -0,0 +1,28 @@
+#ifndef __ardour_source_factory_h__
+#define __ardour_source_factory_h__
+
+#include <string>
+#include <stdint.h>
+#include <sigc++/sigc++.h>
+#include <boost/shared_ptr.hpp>
+
+#include <ardour/source.h>
+#include <ardour/audiofilesource.h>
+
+class XMLNode;
+
+namespace ARDOUR {
+
+class SourceFactory {
+ public:
+ static sigc::signal<void,boost::shared_ptr<Source> > SourceCreated;
+
+ static boost::shared_ptr<Source> create (const XMLNode& node);
+
+ static boost::shared_ptr<Source> createReadable (DataType type, std::string idstr, AudioFileSource::Flag flags, bool announce = true);
+ static boost::shared_ptr<Source> createWritable (DataType type, std::string name, bool destructive, jack_nframes_t rate, bool announce = true);
+};
+
+}
+
+#endif /* __ardour_source_factory_h__ */
diff --git a/libs/ardour/ardour/tempo.h b/libs/ardour/ardour/tempo.h
index bfd3e429c3..a365717417 100644
--- a/libs/ardour/ardour/tempo.h
+++ b/libs/ardour/ardour/tempo.h
@@ -26,8 +26,11 @@
#include <vector>
#include <cmath>
#include <glibmm/thread.h>
+
#include <pbd/undo.h>
#include <pbd/stateful.h>
+#include <pbd/statefuldestructible.h>
+
#include <sigc++/signal.h>
#include <ardour/ardour.h>
@@ -169,7 +172,8 @@ class TempoMapState : public StateManager::State {
Metrics *metrics;
};
-class TempoMap : public Stateful, public StateManager {
+class TempoMap : public StateManager, public PBD::StatefulDestructible
+{
public:
TempoMap (jack_nframes_t frame_rate);
diff --git a/libs/ardour/ardour/types.h b/libs/ardour/ardour/types.h
index d5bfded460..c0975be922 100644
--- a/libs/ardour/ardour/types.h
+++ b/libs/ardour/ardour/types.h
@@ -26,6 +26,8 @@
#endif
#include <istream>
+#include <vector>
+#include <boost/shared_ptr.hpp>
#include <inttypes.h>
#include <jack/types.h>
@@ -43,6 +45,7 @@ typedef int intptr_t;
namespace ARDOUR {
class Source;
+ class AudioSource;
typedef jack_default_audio_sample_t Sample;
typedef float pan_t;
@@ -254,6 +257,7 @@ namespace ARDOUR {
VST
};
+ typedef std::vector<boost::shared_ptr<Source> > SourceList;
} // namespace ARDOUR
std::istream& operator>>(std::istream& o, ARDOUR::SampleFormat& sf);
diff --git a/libs/ardour/audio_diskstream.cc b/libs/ardour/audio_diskstream.cc
index dceaea3f7e..5daaae5d51 100644
--- a/libs/ardour/audio_diskstream.cc
+++ b/libs/ardour/audio_diskstream.cc
@@ -44,10 +44,12 @@
#include <ardour/audiofilesource.h>
#include <ardour/destructive_filesource.h>
#include <ardour/send.h>
+#include <ardour/region_factory.h>
#include <ardour/audioplaylist.h>
#include <ardour/cycle_timer.h>
#include <ardour/audioregion.h>
#include <ardour/audio_port.h>
+#include <ardour/source_factory.h>
#include "i18n.h"
#include <locale.h>
@@ -100,7 +102,6 @@ AudioDiskstream::init_channel (ChannelInfo &chan)
chan.capture_wrap_buffer = 0;
chan.speed_buffer = 0;
chan.peak_power = 0.0f;
- chan.write_source = 0;
chan.source = 0;
chan.current_capture_buffer = 0;
chan.current_playback_buffer = 0;
@@ -143,8 +144,7 @@ void
AudioDiskstream::destroy_channel (ChannelInfo &chan)
{
if (chan.write_source) {
- chan.write_source->release ();
- chan.write_source = 0;
+ chan.write_source.reset ();
}
if (chan.speed_buffer) {
@@ -189,8 +189,8 @@ AudioDiskstream::allocate_working_buffers()
void
AudioDiskstream::free_working_buffers()
{
- delete _mixdown_buffer;
- delete _gain_buffer;
+ delete [] _mixdown_buffer;
+ delete [] _gain_buffer;
_working_buffers_size = 0;
_mixdown_buffer = 0;
_gain_buffer = 0;
@@ -369,7 +369,7 @@ AudioDiskstream::use_copy_playlist ()
void
AudioDiskstream::setup_destructive_playlist ()
{
- AudioRegion::SourceList srcs;
+ SourceList srcs;
for (ChannelList::iterator chan = channels.begin(); chan != channels.end(); ++chan) {
srcs.push_back ((*chan).write_source);
@@ -379,8 +379,8 @@ AudioDiskstream::setup_destructive_playlist ()
cerr << "setup DS using " << srcs.front()->natural_position () << endl;
- AudioRegion* region = new AudioRegion (srcs, 0, max_frames, _name);
- _playlist->add_region (*region, srcs.front()->natural_position());
+ boost::shared_ptr<Region> region (RegionFactory::create (srcs, 0, max_frames, _name));
+ _playlist->add_region (region, srcs.front()->natural_position());
}
void
@@ -395,7 +395,7 @@ AudioDiskstream::use_destructive_playlist ()
return;
}
- AudioRegion* region = dynamic_cast<AudioRegion*> (rl->front());
+ boost::shared_ptr<AudioRegion> region = boost::dynamic_pointer_cast<AudioRegion> (rl->front());
if (region == 0) {
throw failed_constructor();
@@ -407,7 +407,7 @@ AudioDiskstream::use_destructive_playlist ()
ChannelList::iterator chan;
for (n = 0, chan = channels.begin(); chan != channels.end(); ++chan, ++n) {
- (*chan).write_source = dynamic_cast<AudioFileSource*>(&region->source (n));
+ (*chan).write_source = boost::dynamic_pointer_cast<AudioFileSource>(region->source (n));
assert((*chan).write_source);
(*chan).write_source->set_allow_remove_if_empty (false);
}
@@ -1458,10 +1458,10 @@ AudioDiskstream::transport_stopped (struct tm& when, time_t twhen, bool abort_ca
uint32_t buffer_position;
bool more_work = true;
int err = 0;
- AudioRegion* region = 0;
+ boost::shared_ptr<AudioRegion> region;
jack_nframes_t total_capture;
- AudioRegion::SourceList srcs;
- AudioRegion::SourceList::iterator src;
+ SourceList srcs;
+ SourceList::iterator src;
ChannelList::iterator chan;
vector<CaptureInfo*>::iterator ci;
uint32_t n = 0;
@@ -1497,18 +1497,17 @@ AudioDiskstream::transport_stopped (struct tm& when, time_t twhen, bool abort_ca
ChannelList::iterator chan;
- list<Source*>* deletion_list = new list<Source*>;
+ list<boost::shared_ptr<Source> >* deletion_list = new list<boost::shared_ptr<Source> >;
for ( chan = channels.begin(); chan != channels.end(); ++chan) {
if ((*chan).write_source) {
(*chan).write_source->mark_for_remove ();
- (*chan).write_source->release ();
deletion_list->push_back ((*chan).write_source);
- (*chan).write_source = 0;
+ (*chan).write_source.reset ();
}
/* new source set up in "out" below */
@@ -1531,19 +1530,11 @@ AudioDiskstream::transport_stopped (struct tm& when, time_t twhen, bool abort_ca
for (n = 0, chan = channels.begin(); chan != channels.end(); ++chan, ++n) {
- AudioFileSource* s = (*chan).write_source;
+ boost::shared_ptr<AudioFileSource> s = (*chan).write_source;
if (s) {
-
- AudioFileSource* fsrc;
-
srcs.push_back (s);
-
- if ((fsrc = dynamic_cast<AudioFileSource *>(s)) != 0) {
- cerr << "updating source after capture\n";
- fsrc->update_header (capture_info.front()->start, when, twhen);
- }
-
+ s->update_header (capture_info.front()->start, when, twhen);
s->set_captured_for (_name);
}
@@ -1570,10 +1561,11 @@ AudioDiskstream::transport_stopped (struct tm& when, time_t twhen, bool abort_ca
*/
try {
- region = new AudioRegion (srcs, channels[0].write_source->last_capture_start_frame(), total_capture,
- region_name_from_path (channels[0].write_source->name()),
- 0, AudioRegion::Flag (AudioRegion::DefaultFlags|AudioRegion::Automatic|AudioRegion::WholeFile));
-
+ boost::shared_ptr<Region> rx (RegionFactory::create (srcs, channels[0].write_source->last_capture_start_frame(), total_capture,
+ region_name_from_path (channels[0].write_source->name()),
+ 0, AudioRegion::Flag (AudioRegion::DefaultFlags|AudioRegion::Automatic|AudioRegion::WholeFile)));
+
+ region = boost::dynamic_pointer_cast<AudioRegion> (rx);
region->special_set_position (capture_info.front()->start);
}
@@ -1595,10 +1587,11 @@ AudioDiskstream::transport_stopped (struct tm& when, time_t twhen, bool abort_ca
string region_name;
_session.region_name (region_name, channels[0].write_source->name(), false);
- // cerr << _name << ": based on ci of " << (*ci)->start << " for " << (*ci)->frames << " add a region\n";
+ cerr << _name << ": based on ci of " << (*ci)->start << " for " << (*ci)->frames << " add region " << region_name << endl;
try {
- region = new AudioRegion (srcs, buffer_position, (*ci)->frames, region_name);
+ boost::shared_ptr<Region> rx (RegionFactory::create (srcs, buffer_position, (*ci)->frames, region_name));
+ region = boost::dynamic_pointer_cast<AudioRegion> (rx);
}
catch (failed_constructor& err) {
@@ -1611,7 +1604,7 @@ AudioDiskstream::transport_stopped (struct tm& when, time_t twhen, bool abort_ca
// cerr << "add new region, buffer position = " << buffer_position << " @ " << (*ci)->start << endl;
i_am_the_modifier++;
- _playlist->add_region (*region, (*ci)->start);
+ _playlist->add_region (region, (*ci)->start);
i_am_the_modifier--;
buffer_position += (*ci)->frames;
@@ -1785,7 +1778,7 @@ AudioDiskstream::get_state ()
XMLNode* cs_child = new XMLNode (X_("CapturingSources"));
XMLNode* cs_grandchild;
- for (vector<AudioFileSource*>::iterator i = capturing_sources.begin(); i != capturing_sources.end(); ++i) {
+ for (vector<boost::shared_ptr<AudioFileSource> >::iterator i = capturing_sources.begin(); i != capturing_sources.end(); ++i) {
cs_grandchild = new XMLNode (X_("file"));
cs_grandchild->add_property (X_("path"), (*i)->path());
cs_child->add_child_nocopy (*cs_grandchild);
@@ -1954,11 +1947,9 @@ AudioDiskstream::use_new_write_source (uint32_t n)
if (AudioFileSource::is_empty (chan.write_source->path())) {
chan.write_source->mark_for_remove ();
- chan.write_source->release();
- delete chan.write_source;
+ chan.write_source.reset ();
} else {
- chan.write_source->release();
- chan.write_source = 0;
+ chan.write_source.reset ();
}
}
@@ -1970,12 +1961,10 @@ AudioDiskstream::use_new_write_source (uint32_t n)
catch (failed_constructor &err) {
error << string_compose (_("%1:%2 new capture file not initialized correctly"), _name, n) << endmsg;
- chan.write_source = 0;
+ chan.write_source.reset ();
return -1;
}
- chan.write_source->use ();
-
/* do not remove destructive files even if they are empty */
chan.write_source->set_allow_remove_if_empty (!destructive());
@@ -2172,9 +2161,9 @@ AudioDiskstream::use_pending_capture_data (XMLNode& node)
const XMLProperty* prop;
XMLNodeList nlist = node.children();
XMLNodeIterator niter;
- AudioFileSource* fs;
- AudioFileSource* first_fs = 0;
- AudioRegion::SourceList pending_sources;
+ boost::shared_ptr<AudioFileSource> fs;
+ boost::shared_ptr<AudioFileSource> first_fs;
+ SourceList pending_sources;
jack_nframes_t position;
if ((prop = node.property (X_("at"))) == 0) {
@@ -2193,10 +2182,7 @@ AudioDiskstream::use_pending_capture_data (XMLNode& node)
}
try {
- fs = new SndFileSource (prop->value(),
- Config->get_native_file_data_format(),
- Config->get_native_file_header_format(),
- _session.frame_rate());
+ fs = boost::dynamic_pointer_cast<AudioFileSource> (SourceFactory::createWritable (DataType::AUDIO, prop->value(), false, _session.frame_rate()));
}
catch (failed_constructor& err) {
@@ -2227,13 +2213,12 @@ AudioDiskstream::use_pending_capture_data (XMLNode& node)
return -1;
}
- AudioRegion* region;
+ boost::shared_ptr<AudioRegion> region;
try {
- region = new AudioRegion (pending_sources, 0, first_fs->length(),
- region_name_from_path (first_fs->name()),
- 0, AudioRegion::Flag (AudioRegion::DefaultFlags|AudioRegion::Automatic|AudioRegion::WholeFile));
-
+ region = boost::dynamic_pointer_cast<AudioRegion> (RegionFactory::create (pending_sources, 0, first_fs->length(),
+ region_name_from_path (first_fs->name()),
+ 0, AudioRegion::Flag (AudioRegion::DefaultFlags|AudioRegion::Automatic|AudioRegion::WholeFile)));
region->special_set_position (0);
}
@@ -2246,7 +2231,7 @@ AudioDiskstream::use_pending_capture_data (XMLNode& node)
}
try {
- region = new AudioRegion (pending_sources, 0, first_fs->length(), region_name_from_path (first_fs->name()));
+ region = boost::dynamic_pointer_cast<AudioRegion> (RegionFactory::create (pending_sources, 0, first_fs->length(), region_name_from_path (first_fs->name())));
}
catch (failed_constructor& err) {
@@ -2257,7 +2242,7 @@ AudioDiskstream::use_pending_capture_data (XMLNode& node)
return -1;
}
- _playlist->add_region (*region, position);
+ _playlist->add_region (region, position);
return 0;
}
diff --git a/libs/ardour/audio_playlist.cc b/libs/ardour/audio_playlist.cc
index b621e587e9..7fc29f84b8 100644
--- a/libs/ardour/audio_playlist.cc
+++ b/libs/ardour/audio_playlist.cc
@@ -76,28 +76,28 @@ AudioPlaylist::AudioPlaylist (const AudioPlaylist& other, string name, bool hidd
{
save_state (_("initial state"));
- list<Region*>::const_iterator in_o = other.regions.begin();
- list<Region*>::iterator in_n = regions.begin();
+ RegionList::const_iterator in_o = other.regions.begin();
+ RegionList::iterator in_n = regions.begin();
while (in_o != other.regions.end()) {
- AudioRegion *ar = dynamic_cast<AudioRegion *>( (*in_o) );
+ boost::shared_ptr<AudioRegion> ar = boost::dynamic_pointer_cast<AudioRegion>(*in_o);
// We look only for crossfades which begin with the current region, so we don't get doubles
for (list<Crossfade *>::const_iterator xfades = other._crossfades.begin(); xfades != other._crossfades.end(); ++xfades) {
- if ( &(*xfades)->in() == ar) {
+ if ((*xfades)->in() == ar) {
// We found one! Now copy it!
- list<Region*>::const_iterator out_o = other.regions.begin();
- list<Region*>::const_iterator out_n = regions.begin();
+ RegionList::const_iterator out_o = other.regions.begin();
+ RegionList::const_iterator out_n = regions.begin();
while (out_o != other.regions.end()) {
- AudioRegion *ar2 = dynamic_cast<AudioRegion *>( (*out_o) );
+ boost::shared_ptr<AudioRegion>ar2 = boost::dynamic_pointer_cast<AudioRegion>(*out_o);
- if ( &(*xfades)->out() == ar2) {
- AudioRegion *in = dynamic_cast<AudioRegion*>( (*in_n) );
- AudioRegion *out = dynamic_cast<AudioRegion*>( (*out_n) );
- Crossfade *new_fade = new Crossfade( *(*xfades), in, out);
+ if ((*xfades)->out() == ar2) {
+ boost::shared_ptr<AudioRegion>in = boost::dynamic_pointer_cast<AudioRegion>(*in_n);
+ boost::shared_ptr<AudioRegion>out = boost::dynamic_pointer_cast<AudioRegion>(*out_n);
+ Crossfade *new_fade = new Crossfade (*(*xfades), in, out);
add_crossfade(*new_fade);
break;
}
@@ -129,29 +129,21 @@ AudioPlaylist::AudioPlaylist (const AudioPlaylist& other, jack_nframes_t start,
AudioPlaylist::~AudioPlaylist ()
{
set<Crossfade*> all_xfades;
- set<Region*> all_regions;
- GoingAway (this);
+ GoingAway (); /* EMIT SIGNAL */
- /* find every region we've ever used, and add it to the set of
- all regions. same for xfades;
- */
+ /* drop connections to signals */
- for (RegionList::iterator x = regions.begin(); x != regions.end(); ++x) {
- all_regions.insert (*x);
- }
+ notify_callbacks ();
for (Crossfades::iterator x = _crossfades.begin(); x != _crossfades.end(); ++x) {
all_xfades.insert (*x);
}
for (StateMap::iterator i = states.begin(); i != states.end(); ++i) {
-
+
AudioPlaylist::State* apstate = dynamic_cast<AudioPlaylist::State*> (*i);
- for (RegionList::iterator r = apstate->regions.begin(); r != apstate->regions.end(); ++r) {
- all_regions.insert (*r);
- }
for (Crossfades::iterator xf = apstate->crossfades.begin(); xf != apstate->crossfades.end(); ++xf) {
all_xfades.insert (*xf);
}
@@ -159,13 +151,6 @@ AudioPlaylist::~AudioPlaylist ()
delete apstate;
}
- /* delete every region */
-
- for (set<Region *>::iterator ar = all_regions.begin(); ar != all_regions.end(); ++ar) {
- (*ar)->unlock_sources ();
- delete *ar;
- }
-
/* delete every crossfade */
for (set<Crossfade *>::iterator axf = all_xfades.begin(); axf != all_xfades.end(); ++axf) {
@@ -174,7 +159,7 @@ AudioPlaylist::~AudioPlaylist ()
}
struct RegionSortByLayer {
- bool operator() (Region *a, Region *b) {
+ bool operator() (boost::shared_ptr<Region> a, boost::shared_ptr<Region> b) {
return a->layer() < b->layer();
}
};
@@ -215,7 +200,7 @@ AudioPlaylist::read (Sample *buf, Sample *mixdown_buffer, float *gain_buffer, ja
skip_frames = 0;
_read_data_count = 0;
- map<uint32_t,vector<Region*> > relevant_regions;
+ map<uint32_t,vector<boost::shared_ptr<Region> > > relevant_regions;
map<uint32_t,vector<Crossfade*> > relevant_xfades;
vector<uint32_t> relevant_layers;
@@ -246,12 +231,11 @@ AudioPlaylist::read (Sample *buf, Sample *mixdown_buffer, float *gain_buffer, ja
for (vector<uint32_t>::iterator l = relevant_layers.begin(); l != relevant_layers.end(); ++l) {
- // FIXME: Should be vector<AudioRegion*>
- vector<Region*>& r (relevant_regions[*l]);
+ vector<boost::shared_ptr<Region> > r (relevant_regions[*l]);
vector<Crossfade*>& x (relevant_xfades[*l]);
- for (vector<Region*>::iterator i = r.begin(); i != r.end(); ++i) {
- AudioRegion* const ar = dynamic_cast<AudioRegion*>(*i);
+ for (vector<boost::shared_ptr<Region> >::iterator i = r.begin(); i != r.end(); ++i) {
+ boost::shared_ptr<AudioRegion> ar = boost::dynamic_pointer_cast<AudioRegion>(*i);
assert(ar);
ar->read_at (buf, mixdown_buffer, gain_buffer, start, cnt, chan_n, read_frames, skip_frames);
_read_data_count += ar->read_data_count();
@@ -271,10 +255,10 @@ AudioPlaylist::read (Sample *buf, Sample *mixdown_buffer, float *gain_buffer, ja
void
-AudioPlaylist::remove_dependents (Region& region)
+AudioPlaylist::remove_dependents (boost::shared_ptr<Region> region)
{
Crossfades::iterator i, tmp;
- AudioRegion* r = dynamic_cast<AudioRegion*> (&region);
+ boost::shared_ptr<AudioRegion> r = boost::dynamic_pointer_cast<AudioRegion> (region);
if (r == 0) {
fatal << _("programming error: non-audio Region passed to remove_overlap in audio playlist")
@@ -286,7 +270,7 @@ AudioPlaylist::remove_dependents (Region& region)
tmp = i;
tmp++;
- if ((*i)->involves (*r)) {
+ if ((*i)->involves (r)) {
/* do not delete crossfades */
_crossfades.erase (i);
}
@@ -318,9 +302,9 @@ AudioPlaylist::flush_notifications ()
}
void
-AudioPlaylist::refresh_dependents (Region& r)
+AudioPlaylist::refresh_dependents (boost::shared_ptr<Region> r)
{
- AudioRegion* ar = dynamic_cast<AudioRegion*>(&r);
+ boost::shared_ptr<AudioRegion> ar = boost::dynamic_pointer_cast<AudioRegion>(r);
set<Crossfade*> updated;
if (ar == 0) {
@@ -336,7 +320,7 @@ AudioPlaylist::refresh_dependents (Region& r)
/* only update them once */
- if ((*x)->involves (*ar)) {
+ if ((*x)->involves (ar)) {
if (find (updated.begin(), updated.end(), *x) == updated.end()) {
if ((*x)->refresh ()) {
@@ -351,11 +335,11 @@ AudioPlaylist::refresh_dependents (Region& r)
}
void
-AudioPlaylist::finalize_split_region (Region *o, Region *l, Region *r)
+AudioPlaylist::finalize_split_region (boost::shared_ptr<Region> o, boost::shared_ptr<Region> l, boost::shared_ptr<Region> r)
{
- AudioRegion *orig = dynamic_cast<AudioRegion*>(o);
- AudioRegion *left = dynamic_cast<AudioRegion*>(l);
- AudioRegion *right = dynamic_cast<AudioRegion*>(r);
+ boost::shared_ptr<AudioRegion> orig = boost::dynamic_pointer_cast<AudioRegion>(o);
+ boost::shared_ptr<AudioRegion> left = boost::dynamic_pointer_cast<AudioRegion>(l);
+ boost::shared_ptr<AudioRegion> right = boost::dynamic_pointer_cast<AudioRegion>(r);
for (Crossfades::iterator x = _crossfades.begin(); x != _crossfades.end();) {
Crossfades::iterator tmp;
@@ -366,24 +350,24 @@ AudioPlaylist::finalize_split_region (Region *o, Region *l, Region *r)
if ((*x)->_in == orig) {
if (! (*x)->covers(right->position())) {
- fade = new Crossfade( *(*x), left, (*x)->_out);
+ fade = new Crossfade (**x, left, (*x)->_out);
} else {
// Overlap, the crossfade is copied on the left side of the right region instead
- fade = new Crossfade( *(*x), right, (*x)->_out);
+ fade = new Crossfade (**x, right, (*x)->_out);
}
}
if ((*x)->_out == orig) {
if (! (*x)->covers(right->position())) {
- fade = new Crossfade( *(*x), (*x)->_in, right);
+ fade = new Crossfade (**x, (*x)->_in, right);
} else {
// Overlap, the crossfade is copied on the right side of the left region instead
- fade = new Crossfade( *(*x), (*x)->_in, left);
+ fade = new Crossfade (**x, (*x)->_in, left);
}
}
if (fade) {
- _crossfades.remove( (*x) );
+ _crossfades.remove (*x);
add_crossfade (*fade);
}
x = tmp;
@@ -391,19 +375,19 @@ AudioPlaylist::finalize_split_region (Region *o, Region *l, Region *r)
}
void
-AudioPlaylist::check_dependents (Region& r, bool norefresh)
+AudioPlaylist::check_dependents (boost::shared_ptr<Region> r, bool norefresh)
{
- AudioRegion* other;
- AudioRegion* region;
- AudioRegion* top;
- AudioRegion* bottom;
+ boost::shared_ptr<AudioRegion> other;
+ boost::shared_ptr<AudioRegion> region;
+ boost::shared_ptr<AudioRegion> top;
+ boost::shared_ptr<AudioRegion> bottom;
Crossfade* xfade;
if (in_set_state || in_partition) {
return;
}
- if ((region = dynamic_cast<AudioRegion*> (&r)) == 0) {
+ if ((region = boost::dynamic_pointer_cast<AudioRegion> (r)) == 0) {
fatal << _("programming error: non-audio Region tested for overlap in audio playlist")
<< endmsg;
return;
@@ -419,7 +403,7 @@ AudioPlaylist::check_dependents (Region& r, bool norefresh)
for (RegionList::iterator i = regions.begin(); i != regions.end(); ++i) {
- other = dynamic_cast<AudioRegion*> (*i);
+ other = boost::dynamic_pointer_cast<AudioRegion> (*i);
if (other == region) {
continue;
@@ -461,14 +445,14 @@ AudioPlaylist::check_dependents (Region& r, bool norefresh)
jack_nframes_t xfade_length = min ((jack_nframes_t) 720, top->length());
/* in, out */
- xfade = new Crossfade (*top, *bottom, xfade_length, top->first_frame(), StartOfIn);
+ xfade = new Crossfade (top, bottom, xfade_length, top->first_frame(), StartOfIn);
add_crossfade (*xfade);
- xfade = new Crossfade (*bottom, *top, xfade_length, top->last_frame() - xfade_length, EndOfOut);
+ xfade = new Crossfade (bottom, top, xfade_length, top->last_frame() - xfade_length, EndOfOut);
add_crossfade (*xfade);
} else {
- xfade = new Crossfade (*other, *region, _session.get_xfade_model(), _session.get_crossfades_active());
+ xfade = new Crossfade (other, region, _session.get_xfade_model(), _session.get_crossfades_active());
add_crossfade (*xfade);
}
}
@@ -522,8 +506,8 @@ AudioPlaylist::crossfade_invalidated (Crossfade* xfade)
{
Crossfades::iterator i;
- xfade->in().resume_fade_in ();
- xfade->out().resume_fade_out ();
+ xfade->in()->resume_fade_in ();
+ xfade->out()->resume_fade_out ();
if ((i = find (_crossfades.begin(), _crossfades.end(), xfade)) != _crossfades.end()) {
_crossfades.erase (i);
@@ -589,7 +573,7 @@ void
AudioPlaylist::drop_all_states ()
{
set<Crossfade*> all_xfades;
- set<Region*> all_regions;
+ set<boost::shared_ptr<Region> > all_regions;
/* find every region we've ever used, and add it to the set of
all regions. same for xfades;
@@ -602,6 +586,7 @@ AudioPlaylist::drop_all_states ()
for (RegionList::iterator r = apstate->regions.begin(); r != apstate->regions.end(); ++r) {
all_regions.insert (*r);
}
+
for (Crossfades::iterator xf = apstate->crossfades.begin(); xf != apstate->crossfades.end(); ++xf) {
all_xfades.insert (*xf);
}
@@ -609,8 +594,8 @@ AudioPlaylist::drop_all_states ()
/* now remove from the "all" lists every region that is in the current list. */
- for (list<Region*>::iterator i = regions.begin(); i != regions.end(); ++i) {
- set<Region*>::iterator x = all_regions.find (*i);
+ for (RegionList::iterator i = regions.begin(); i != regions.end(); ++i) {
+ set<boost::shared_ptr<Region> >::iterator x = all_regions.find (*i);
if (x != all_regions.end()) {
all_regions.erase (x);
}
@@ -625,13 +610,6 @@ AudioPlaylist::drop_all_states ()
}
}
- /* delete every region that is left - these are all things that are part of our "history" */
-
- for (set<Region *>::iterator ar = all_regions.begin(); ar != all_regions.end(); ++ar) {
- (*ar)->unlock_sources ();
- delete *ar;
- }
-
/* delete every crossfade that is left (ditto as per regions) */
for (set<Crossfade *>::iterator axf = all_xfades.begin(); axf != all_xfades.end(); ++axf) {
@@ -697,17 +675,11 @@ AudioPlaylist::get_memento () const
}
void
-AudioPlaylist::clear (bool with_delete, bool with_save)
+AudioPlaylist::clear (bool with_save)
{
- if (with_delete) {
- for (Crossfades::iterator i = _crossfades.begin(); i != _crossfades.end(); ++i) {
- delete *i;
- }
- }
-
_crossfades.clear ();
- Playlist::clear (with_delete, with_save);
+ Playlist::clear (with_save);
}
XMLNode&
@@ -727,7 +699,7 @@ AudioPlaylist::state (bool full_state)
void
AudioPlaylist::dump () const
{
- Region *r;
+ boost::shared_ptr<Region>r;
Crossfade *x;
cerr << "Playlist \"" << _name << "\" " << endl
@@ -749,9 +721,9 @@ AudioPlaylist::dump () const
for (Crossfades::const_iterator i = _crossfades.begin(); i != _crossfades.end(); ++i) {
x = *i;
cerr << " xfade ["
- << x->out().name()
+ << x->out()->name()
<< ','
- << x->in().name()
+ << x->in()->name()
<< " @ "
<< x->position()
<< " length = "
@@ -763,9 +735,9 @@ AudioPlaylist::dump () const
}
bool
-AudioPlaylist::destroy_region (Region* region)
+AudioPlaylist::destroy_region (boost::shared_ptr<Region> region)
{
- AudioRegion* r = dynamic_cast<AudioRegion*> (region);
+ boost::shared_ptr<AudioRegion> r = boost::dynamic_pointer_cast<AudioRegion> (region);
bool changed = false;
Crossfades::iterator c, ctmp;
set<Crossfade*> unique_xfades;
@@ -788,7 +760,6 @@ AudioPlaylist::destroy_region (Region* region)
++tmp;
if ((*i) == region) {
- (*i)->unlock_sources ();
regions.erase (i);
changed = true;
}
@@ -801,7 +772,7 @@ AudioPlaylist::destroy_region (Region* region)
ctmp = c;
++ctmp;
- if ((*c)->involves (*r)) {
+ if ((*c)->involves (r)) {
unique_xfades.insert (*c);
_crossfades.erase (c);
}
@@ -822,7 +793,7 @@ AudioPlaylist::destroy_region (Region* region)
ctmp = c;
++ctmp;
- if ((*c)->involves (*r)) {
+ if ((*c)->involves (r)) {
unique_xfades.insert (*c);
_crossfades.erase (c);
}
@@ -886,7 +857,7 @@ AudioPlaylist::crossfade_changed (Change ignored)
}
bool
-AudioPlaylist::region_changed (Change what_changed, Region* region)
+AudioPlaylist::region_changed (Change what_changed, boost::shared_ptr<Region> region)
{
if (in_flush || in_set_state) {
return false;
diff --git a/libs/ardour/audio_track.cc b/libs/ardour/audio_track.cc
index 7a44be9b54..2762418f19 100644
--- a/libs/ardour/audio_track.cc
+++ b/libs/ardour/audio_track.cc
@@ -28,6 +28,7 @@
#include <ardour/redirect.h>
#include <ardour/audioregion.h>
#include <ardour/audiosource.h>
+#include <ardour/region_factory.h>
#include <ardour/route_group_specialized.h>
#include <ardour/insert.h>
#include <ardour/audioplaylist.h>
@@ -719,7 +720,7 @@ AudioTrack::export_stuff (BufferSet& buffers, jack_nframes_t start, jack_nframes
void
AudioTrack::bounce (InterThreadInfo& itt)
{
- vector<Source*> srcs;
+ vector<boost::shared_ptr<Source> > srcs;
_session.write_one_audio_track (*this, 0, _session.current_end_frame(), false, srcs, itt);
}
@@ -727,18 +728,17 @@ AudioTrack::bounce (InterThreadInfo& itt)
void
AudioTrack::bounce_range (jack_nframes_t start, jack_nframes_t end, InterThreadInfo& itt)
{
- vector<Source*> srcs;
+ vector<boost::shared_ptr<Source> > srcs;
_session.write_one_audio_track (*this, start, end, false, srcs, itt);
}
void
AudioTrack::freeze (InterThreadInfo& itt)
{
- vector<Source*> srcs;
+ vector<boost::shared_ptr<Source> > srcs;
string new_playlist_name;
Playlist* new_playlist;
string dir;
- AudioRegion* region;
string region_name;
boost::shared_ptr<AudioDiskstream> diskstream = audio_diskstream();
@@ -805,13 +805,13 @@ AudioTrack::freeze (InterThreadInfo& itt)
/* create a new region from all filesources, keep it private */
- region = new AudioRegion (srcs, 0, srcs[0]->length(),
- region_name, 0,
- (AudioRegion::Flag) (AudioRegion::WholeFile|AudioRegion::DefaultFlags),
- false);
+ boost::shared_ptr<Region> region (RegionFactory::create (srcs, 0, srcs[0]->length(),
+ region_name, 0,
+ (Region::Flag) (Region::WholeFile|Region::DefaultFlags),
+ false));
new_playlist->set_orig_diskstream_id (diskstream->id());
- new_playlist->add_region (*region, 0);
+ new_playlist->add_region (region, 0);
new_playlist->set_frozen (true);
region->set_locked (true);
diff --git a/libs/ardour/audioengine.cc b/libs/ardour/audioengine.cc
index 15ad6e442c..fe29037cb7 100644
--- a/libs/ardour/audioengine.cc
+++ b/libs/ardour/audioengine.cc
@@ -63,16 +63,16 @@ AudioEngine::AudioEngine (string client_name)
_buffer_size = 0;
_freewheeling = false;
_freewheel_thread_registered = false;
-
- m_meter_thread = 0;
- m_meter_exit = false;
- start_metering_thread();
-
+ m_meter_thread = 0;
+ m_meter_exit = false;
+
if (connect_to_jack (client_name)) {
throw NoBackendAvailable ();
}
+ start_metering_thread();
+
}
AudioEngine::~AudioEngine ()
@@ -81,9 +81,9 @@ AudioEngine::~AudioEngine ()
jack_client_close (_jack);
}
- if(m_meter_thread) {
- g_atomic_int_inc(&m_meter_exit);
- }
+ if(m_meter_thread) {
+ g_atomic_int_inc(&m_meter_exit);
+ }
}
void
@@ -207,7 +207,7 @@ AudioEngine::_xrun_callback (void *arg)
int
AudioEngine::_graph_order_callback (void *arg)
{
- static_cast<AudioEngine *>(arg)->GraphReordered (); /* EMIT SIGNAL */
+ static_cast<AudioEngine *>(arg)->GraphReordered (); /* EMIT SIGNAL */
return 0;
}
@@ -359,9 +359,9 @@ AudioEngine::jack_bufsize_callback (jack_nframes_t nframes)
void
AudioEngine::start_metering_thread ()
{
- if(m_meter_thread == 0) {
- m_meter_thread = Glib::Thread::create (sigc::mem_fun(this, &AudioEngine::meter_thread), false);
- }
+ if(m_meter_thread == 0) {
+ m_meter_thread = Glib::Thread::create (sigc::mem_fun(this, &AudioEngine::meter_thread), false);
+ }
}
void
diff --git a/libs/ardour/audiofilesource.cc b/libs/ardour/audiofilesource.cc
index 46079ef9a5..963a2274df 100644
--- a/libs/ardour/audiofilesource.cc
+++ b/libs/ardour/audiofilesource.cc
@@ -38,6 +38,7 @@
#include <ardour/sndfilesource.h>
#include <ardour/destructive_filesource.h>
#include <ardour/session.h>
+#include <ardour/source_factory.h>
// if these headers come before sigc++ is included
// the parser throws ObjC++ errors. (nil is a keyword)
@@ -108,8 +109,7 @@ AudioFileSource::~AudioFileSource ()
bool
AudioFileSource::removable () const
{
- return (_flags & Removable) && ((_flags & RemoveAtDestroy) ||
- ((_flags & RemovableIfEmpty) && is_empty (_path)));
+ return (_flags & Removable) && ((_flags & RemoveAtDestroy) || ((_flags & RemovableIfEmpty) && is_empty (_path)));
}
int
@@ -164,80 +164,6 @@ AudioFileSource::old_peak_path (string audio_path)
return res;
}
-#ifdef HAVE_COREAUDIO
-
-AudioFileSource*
-AudioFileSource::create (const XMLNode& node)
-{
- AudioFileSource* es = 0;
-
- if (node.property (X_("destructive")) != 0) {
-
- es = new DestructiveFileSource (node);
-
- } else {
-
- try {
- es = new CoreAudioSource (node);
- }
-
-
- catch (failed_constructor& err) {
- es = new SndFileSource (node);
- }
- }
-
- return es;
-}
-
-#else
-
-AudioFileSource*
-AudioFileSource::create (const XMLNode& node)
-{
- if (node.property (X_("destructive")) != 0) {
-
- return new DestructiveFileSource (node);
-
- } else {
-
- return new SndFileSource (node);
- }
-}
-
-#endif // HAVE_COREAUDIO
-
-#ifdef HAVE_COREAUDIO
-AudioFileSource*
-AudioFileSource::create (const string& idstr, Flag flags)
-{
- AudioFileSource* es = 0;
-
- if (flags & Destructive) {
- return new DestructiveFileSource (idstr, flags);
- }
-
- try {
- es = new CoreAudioSource (idstr, flags);
- }
-
- catch (failed_constructor& err) {
- es = new SndFileSource (idstr, flags);
- }
-
- return es;
-}
-
-#else
-
-AudioFileSource*
-AudioFileSource::create (const string& idstr, Flag flags)
-{
- return new SndFileSource (idstr, flags);
-}
-
-#endif // HAVE_COREAUDIO
-
bool
AudioFileSource::get_soundfile_info (string path, SoundFileInfo& _info, string& error_msg)
{
@@ -579,7 +505,6 @@ void
AudioFileSource::set_header_position_offset (jack_nframes_t offset)
{
header_position_offset = offset;
- cerr << "hpo set to " << offset << endl;
HeaderPositionOffsetChanged ();
}
@@ -639,11 +564,11 @@ bool
AudioFileSource::is_empty (string path)
{
bool ret = false;
- AudioFileSource* afs = create (path, NoPeakFile);
+ boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource> (
+ SourceFactory::createReadable (DataType::AUDIO, path, NoPeakFile, false));
if (afs) {
ret = (afs->length() == 0);
- delete afs;
}
return ret;
diff --git a/libs/ardour/audiofilter.cc b/libs/ardour/audiofilter.cc
index a26d9674bd..0a630f1e25 100644
--- a/libs/ardour/audiofilter.cc
+++ b/libs/ardour/audiofilter.cc
@@ -26,6 +26,8 @@
#include <ardour/session.h>
#include <ardour/audioregion.h>
#include <ardour/audiofilter.h>
+#include <ardour/region_factory.h>
+#include <ardour/source_factory.h>
#include "i18n.h"
@@ -33,25 +35,23 @@ using namespace ARDOUR;
using namespace PBD;
int
-AudioFilter::make_new_sources (AudioRegion& region, AudioRegion::SourceList& nsrcs)
+AudioFilter::make_new_sources (boost::shared_ptr<AudioRegion> region, SourceList& nsrcs)
{
- vector<string> names = region.master_source_names();
+ vector<string> names = region->master_source_names();
- for (uint32_t i = 0; i < region.n_channels(); ++i) {
+ for (uint32_t i = 0; i < region->n_channels(); ++i) {
string path = session.path_from_region_name (PBD::basename_nosuffix (names[i]), string (""));
if (path.length() == 0) {
- error << string_compose (_("audiofilter: error creating name for new audio file based on %1"), region.name())
+ error << string_compose (_("audiofilter: error creating name for new audio file based on %1"), region->name())
<< endmsg;
return -1;
}
try {
- nsrcs.push_back (new SndFileSource (path,
- Config->get_native_file_data_format(),
- Config->get_native_file_header_format(),
- session.frame_rate()));
+ nsrcs.push_back (boost::dynamic_pointer_cast<AudioSource> (
+ SourceFactory::createWritable (DataType::AUDIO, path, false, session.frame_rate())));
}
catch (failed_constructor& err) {
@@ -64,7 +64,7 @@ AudioFilter::make_new_sources (AudioRegion& region, AudioRegion::SourceList& nsr
}
int
-AudioFilter::finish (AudioRegion& region, AudioRegion::SourceList& nsrcs)
+AudioFilter::finish (boost::shared_ptr<AudioRegion> region, SourceList& nsrcs)
{
string region_name;
@@ -76,19 +76,19 @@ AudioFilter::finish (AudioRegion& region, AudioRegion::SourceList& nsrcs)
time (&xnow);
now = localtime (&xnow);
- for (AudioRegion::SourceList::iterator si = nsrcs.begin(); si != nsrcs.end(); ++si) {
- AudioFileSource* afs = dynamic_cast<AudioFileSource*>(*si);
+ for (SourceList::iterator si = nsrcs.begin(); si != nsrcs.end(); ++si) {
+ boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*si);
if (afs) {
- afs->update_header (region.position(), *now, xnow);
+ afs->update_header (region->position(), *now, xnow);
}
}
/* create a new region */
- region_name = session.new_region_name (region.name());
+ region_name = session.new_region_name (region->name());
results.clear ();
- results.push_back (new AudioRegion (nsrcs, 0, region.length(), region_name, 0,
- Region::Flag (Region::WholeFile|Region::DefaultFlags)));
-
+ results.push_back (boost::dynamic_pointer_cast<AudioRegion> (RegionFactory::create (nsrcs, 0, region->length(), region_name, 0,
+ Region::Flag (Region::WholeFile|Region::DefaultFlags))));
+
return 0;
}
diff --git a/libs/ardour/audioregion.cc b/libs/ardour/audioregion.cc
index 052049cda7..07127b78c1 100644
--- a/libs/ardour/audioregion.cc
+++ b/libs/ardour/audioregion.cc
@@ -65,11 +65,11 @@ AudioRegionState::AudioRegionState (string why)
}
/** Basic AudioRegion constructor (one channel) */
-AudioRegion::AudioRegion (AudioSource& src, jack_nframes_t start, jack_nframes_t length, bool announce)
- : Region (src, start, length, PBD::basename_nosuffix(src.name()), DataType::AUDIO, 0, Region::Flag(Region::DefaultFlags|Region::External))
- , _fade_in (0.0, 2.0, 1.0, false)
- , _fade_out (0.0, 2.0, 1.0, false)
- , _envelope (0.0, 2.0, 1.0, false)
+AudioRegion::AudioRegion (boost::shared_ptr<AudioSource> src, jack_nframes_t start, jack_nframes_t length)
+ : Region (src, start, length, PBD::basename_nosuffix(src->name()), DataType::AUDIO, 0, Region::Flag(Region::DefaultFlags|Region::External)),
+ _fade_in (0.0, 2.0, 1.0, false),
+ _fade_out (0.0, 2.0, 1.0, false),
+ _envelope (0.0, 2.0, 1.0, false)
{
_scale_amplitude = 1.0;
@@ -79,14 +79,10 @@ AudioRegion::AudioRegion (AudioSource& src, jack_nframes_t start, jack_nframes_t
save_state ("initial state");
_envelope.StateChanged.connect (mem_fun (*this, &AudioRegion::envelope_changed));
-
- if (announce) {
- CheckNewRegion (this); /* EMIT SIGNAL */
- }
}
/* Basic AudioRegion constructor (one channel) */
-AudioRegion::AudioRegion (AudioSource& src, jack_nframes_t start, jack_nframes_t length, const string& name, layer_t layer, Flag flags, bool announce)
+AudioRegion::AudioRegion (boost::shared_ptr<AudioSource> src, jack_nframes_t start, jack_nframes_t length, const string& name, layer_t layer, Flag flags)
: Region (src, start, length, name, DataType::AUDIO, layer, flags)
, _fade_in (0.0, 2.0, 1.0, false)
, _fade_out (0.0, 2.0, 1.0, false)
@@ -99,14 +95,10 @@ AudioRegion::AudioRegion (AudioSource& src, jack_nframes_t start, jack_nframes_t
save_state ("initial state");
_envelope.StateChanged.connect (mem_fun (*this, &AudioRegion::envelope_changed));
-
- if (announce) {
- CheckNewRegion (this); /* EMIT SIGNAL */
- }
}
/* Basic AudioRegion constructor (many channels) */
-AudioRegion::AudioRegion (SourceList& srcs, jack_nframes_t start, jack_nframes_t length, const string& name, layer_t layer, Flag flags, bool announce)
+AudioRegion::AudioRegion (SourceList& srcs, jack_nframes_t start, jack_nframes_t length, const string& name, layer_t layer, Flag flags)
: Region (srcs, start, length, name, DataType::AUDIO, layer, flags)
, _fade_in (0.0, 2.0, 1.0, false)
, _fade_out (0.0, 2.0, 1.0, false)
@@ -119,19 +111,15 @@ AudioRegion::AudioRegion (SourceList& srcs, jack_nframes_t start, jack_nframes_t
save_state ("initial state");
_envelope.StateChanged.connect (mem_fun (*this, &AudioRegion::envelope_changed));
-
- if (announce) {
- CheckNewRegion (this); /* EMIT SIGNAL */
- }
}
/** Create a new AudioRegion, that is part of an existing one */
-AudioRegion::AudioRegion (const AudioRegion& other, jack_nframes_t offset, jack_nframes_t length, const string& name, layer_t layer, Flag flags, bool announce)
- : Region (other, offset, length, name, layer, flags)
- , _fade_in (other._fade_in)
- , _fade_out (other._fade_out)
- , _envelope (other._envelope, (double) offset, (double) offset + length)
+AudioRegion::AudioRegion (boost::shared_ptr<const AudioRegion> other, jack_nframes_t offset, jack_nframes_t length, const string& name, layer_t layer, Flag flags)
+ : Region (other, offset, length, name, layer, flags),
+ _fade_in (other->_fade_in),
+ _fade_out (other->_fade_out),
+ _envelope (other->_envelope, (double) offset, (double) offset + length)
{
/* return to default fades if the existing ones are too long */
_fade_in_disabled = 0;
@@ -142,7 +130,7 @@ AudioRegion::AudioRegion (const AudioRegion& other, jack_nframes_t offset, jack_
if (_fade_in.back()->when >= _length) {
set_default_fade_in ();
} else {
- _fade_in_disabled = other._fade_in_disabled;
+ _fade_in_disabled = other->_fade_in_disabled;
}
set_default_fade_out ();
_flags = Flag (_flags & ~Region::LeftOfSplit);
@@ -152,31 +140,29 @@ AudioRegion::AudioRegion (const AudioRegion& other, jack_nframes_t offset, jack_
if (_fade_out.back()->when >= _length) {
set_default_fade_out ();
} else {
- _fade_out_disabled = other._fade_out_disabled;
+ _fade_out_disabled = other->_fade_out_disabled;
}
set_default_fade_in ();
_flags = Flag (_flags & ~Region::RightOfSplit);
}
- _scale_amplitude = other._scale_amplitude;
+ _scale_amplitude = other->_scale_amplitude;
save_state ("initial state");
_envelope.StateChanged.connect (mem_fun (*this, &AudioRegion::envelope_changed));
-
- if (announce) {
- CheckNewRegion (this); /* EMIT SIGNAL */
- }
+
+ assert(_type == DataType::AUDIO);
}
-AudioRegion::AudioRegion (const AudioRegion &other)
- : Region (other)
- , _fade_in (other._fade_in)
- , _fade_out (other._fade_out)
- , _envelope (other._envelope)
+AudioRegion::AudioRegion (boost::shared_ptr<const AudioRegion> other)
+ : Region (other),
+ _fade_in (other->_fade_in),
+ _fade_out (other->_fade_out),
+ _envelope (other->_envelope)
{
- _scale_amplitude = other._scale_amplitude;
- _envelope = other._envelope;
+ _scale_amplitude = other->_scale_amplitude;
+ _envelope = other->_envelope;
_fade_in_disabled = 0;
_fade_out_disabled = 0;
@@ -185,10 +171,10 @@ AudioRegion::AudioRegion (const AudioRegion &other)
_envelope.StateChanged.connect (mem_fun (*this, &AudioRegion::envelope_changed));
- /* NOTE: no CheckNewRegion signal emitted here. This is the copy constructor */
+ assert(_type == DataType::AUDIO);
}
-AudioRegion::AudioRegion (AudioSource& src, const XMLNode& node)
+AudioRegion::AudioRegion (boost::shared_ptr<AudioSource> src, const XMLNode& node)
: Region (src, node)
, _fade_in (0.0, 2.0, 1.0, false)
, _fade_out (0.0, 2.0, 1.0, false)
@@ -205,8 +191,6 @@ AudioRegion::AudioRegion (AudioSource& src, const XMLNode& node)
_envelope.StateChanged.connect (mem_fun (*this, &AudioRegion::envelope_changed));
assert(_type == DataType::AUDIO);
-
- CheckNewRegion (this); /* EMIT SIGNAL */
}
AudioRegion::AudioRegion (SourceList& srcs, const XMLNode& node)
@@ -227,13 +211,11 @@ AudioRegion::AudioRegion (SourceList& srcs, const XMLNode& node)
_envelope.StateChanged.connect (mem_fun (*this, &AudioRegion::envelope_changed));
assert(_type == DataType::AUDIO);
-
- CheckNewRegion (this); /* EMIT SIGNAL */
}
AudioRegion::~AudioRegion ()
{
- GoingAway (this);
+ GoingAway (); /* EMIT SIGNAL */
}
StateManager::State*
@@ -345,7 +327,7 @@ AudioRegion::read_peaks (PeakData *buf, jack_nframes_t npeaks, jack_nframes_t of
return 0;
}
- if (audio_source(chan_n).read_peaks (buf, npeaks, offset, cnt, samples_per_unit)) {
+ if (audio_source(chan_n)->read_peaks (buf, npeaks, offset, cnt, samples_per_unit)) {
return 0;
} else {
if (_scale_amplitude != 1.0) {
@@ -419,12 +401,12 @@ AudioRegion::_read_at (const SourceList& srcs, Sample *buf, Sample *mixdown_buff
_read_data_count = 0;
- AudioSource& src = audio_source(chan_n);
- if (src.read (mixdown_buffer, _start + internal_offset, to_read) != to_read) {
+ boost::shared_ptr<AudioSource> src = audio_source(chan_n);
+ if (src->read (mixdown_buffer, _start + internal_offset, to_read) != to_read) {
return 0; /* "read nothing" */
}
- _read_data_count += src.read_data_count();
+ _read_data_count += src->read_data_count();
/* fade in */
@@ -974,7 +956,7 @@ AudioRegion::separate_by_channel (Session& session, vector<AudioRegion*>& v) con
int
AudioRegion::apply (AudioFilter& filter)
{
- return filter.run (*this);
+ return filter.run (boost::shared_ptr<AudioRegion> (this));
}
int
@@ -1002,7 +984,7 @@ AudioRegion::exportme (Session& session, AudioExportSpecification& spec)
if (spec.channels == 1) {
- if (audio_source().read (spec.dataF, _start + spec.pos, to_read) != to_read) {
+ if (audio_source()->read (spec.dataF, _start + spec.pos, to_read) != to_read) {
goto out;
}
@@ -1012,7 +994,7 @@ AudioRegion::exportme (Session& session, AudioExportSpecification& spec)
for (uint32_t chan = 0; chan < spec.channels; ++chan) {
- if (audio_source(chan).read (buf, _start + spec.pos, to_read) != to_read) {
+ if (audio_source(chan)->read (buf, _start + spec.pos, to_read) != to_read) {
goto out;
}
@@ -1090,7 +1072,7 @@ AudioRegion::normalize_to (float target_dB)
/* read it in */
- if (audio_source (n).read (buf, fpos, to_read) != to_read) {
+ if (audio_source (n)->read (buf, fpos, to_read) != to_read) {
return;
}
@@ -1178,16 +1160,16 @@ AudioRegion::speed_mismatch (float sr) const
return false;
}
- float fsr = audio_source().sample_rate();
+ float fsr = audio_source()->sample_rate();
return fsr != sr;
}
-AudioSource&
+boost::shared_ptr<AudioSource>
AudioRegion::audio_source (uint32_t n) const
{
// Guaranteed to succeed (use a static cast?)
- return dynamic_cast<AudioSource&>(source(n));
+ return boost::dynamic_pointer_cast<AudioSource>(source(n));
}
extern "C" {
@@ -1205,7 +1187,7 @@ uint32_t region_length_from_c (void *arg)
uint32_t sourcefile_length_from_c (void *arg, double zoom_factor)
{
- return ( (AudioRegion *) arg)->audio_source().available_peaks (zoom_factor) ;
+ return ( (AudioRegion *) arg)->audio_source()->available_peaks (zoom_factor) ;
}
} /* extern "C" */
diff --git a/libs/ardour/audiosource.cc b/libs/ardour/audiosource.cc
index 9620565ae2..b9d21223e3 100644
--- a/libs/ardour/audiosource.cc
+++ b/libs/ardour/audiosource.cc
@@ -28,6 +28,7 @@
#include <cmath>
#include <iomanip>
#include <algorithm>
+#include <vector>
#include <pbd/xml++.h>
#include <pbd/pthread_utils.h>
@@ -65,6 +66,7 @@ AudioSource::AudioSource (string name)
AudioSource::AudioSource (const XMLNode& node)
: Source (node)
{
+ cerr << "audiosource from XML\n";
if (pending_peak_sources_lock == 0) {
pending_peak_sources_lock = new Glib::Mutex;
}
@@ -249,18 +251,18 @@ AudioSource::stop_peak_thread ()
}
void
-AudioSource::queue_for_peaks (AudioSource& source)
+AudioSource::queue_for_peaks (AudioSource* source)
{
if (have_peak_thread) {
-
+
Glib::Mutex::Lock lm (*pending_peak_sources_lock);
- source.next_peak_clear_should_notify = true;
+ source->next_peak_clear_should_notify = true;
if (find (pending_peak_sources.begin(),
pending_peak_sources.end(),
- &source) == pending_peak_sources.end()) {
- pending_peak_sources.push_back (&source);
+ source) == pending_peak_sources.end()) {
+ pending_peak_sources.push_back (source);
}
char c = (char) PeakRequest::Build;
@@ -829,7 +831,7 @@ AudioSource::build_peaks_from_scratch ()
next_peak_clear_should_notify = true;
pending_peak_builds.push_back (new PeakBuildRecord (0, _length));
- queue_for_peaks (*this);
+ queue_for_peaks (this);
}
bool
diff --git a/libs/ardour/auditioner.cc b/libs/ardour/auditioner.cc
index 3109323acd..29ae3b4d2b 100644
--- a/libs/ardour/auditioner.cc
+++ b/libs/ardour/auditioner.cc
@@ -20,6 +20,8 @@
#include <glibmm/thread.h>
+#include <pbd/error.h>
+
#include <ardour/audio_diskstream.h>
#include <ardour/audioregion.h>
#include <ardour/route.h>
@@ -28,9 +30,13 @@
#include <ardour/audioplaylist.h>
#include <ardour/panner.h>
#include <ardour/data_type.h>
+#include <ardour/region_factory.h>
using namespace std;
using namespace ARDOUR;
+using namespace PBD;
+
+#include "i18n.h"
Auditioner::Auditioner (Session& s)
: AudioTrack (s, "auditioner", Route::Hidden)
@@ -59,7 +65,7 @@ Auditioner::Auditioner (Session& s)
IO::output_changed.connect (mem_fun (*this, &Auditioner::output_changed));
- the_region = 0;
+ the_region.reset ((AudioRegion*) 0);
g_atomic_int_set (&_active, 0);
}
@@ -74,7 +80,7 @@ Auditioner::prepare_playlist ()
AudioPlaylist* const apl = dynamic_cast<AudioPlaylist*>(_diskstream->playlist());
assert(apl);
- apl->clear (false, false);
+ apl->clear (false);
return *apl;
}
@@ -101,7 +107,7 @@ Auditioner::audition_current_playlist ()
}
void
-Auditioner::audition_region (AudioRegion& region)
+Auditioner::audition_region (boost::shared_ptr<Region> region)
{
if (g_atomic_int_get (&_active)) {
/* don't go via session for this, because we are going
@@ -110,13 +116,20 @@ Auditioner::audition_region (AudioRegion& region)
cancel_audition ();
}
+ if (boost::dynamic_pointer_cast<AudioRegion>(region) == 0) {
+ error << _("Auditioning of non-audio regions not yet supported") << endmsg;
+ return;
+ }
+
Glib::Mutex::Lock lm (lock);
- the_region = new AudioRegion (region);
+ /* copy it */
+
+ boost::shared_ptr<AudioRegion> the_region (boost::dynamic_pointer_cast<AudioRegion> (RegionFactory::create (region)));
the_region->set_position (0, this);
- _diskstream->playlist()->clear (true, false);
- _diskstream->playlist()->add_region (*the_region, 0, 1, false);
+ _diskstream->playlist()->clear (false);
+ _diskstream->playlist()->add_region (the_region, 0, 1, false);
while (_diskstream->n_channels().get(DataType::AUDIO) < the_region->n_channels()) {
audio_diskstream()->add_channel ();
diff --git a/libs/ardour/automation_event.cc b/libs/ardour/automation_event.cc
index ccfcef28f4..afdeecbbfe 100644
--- a/libs/ardour/automation_event.cc
+++ b/libs/ardour/automation_event.cc
@@ -136,6 +136,8 @@ AutomationList::~AutomationList()
std::set<ControlEvent*> all_events;
AutomationList::State* asp;
+ GoingAway ();
+
for (AutomationEventList::iterator x = events.begin(); x != events.end(); ++x) {
all_events.insert (*x);
}
diff --git a/libs/ardour/control_protocol_manager.cc b/libs/ardour/control_protocol_manager.cc
index 0370886a35..5c02936ba0 100644
--- a/libs/ardour/control_protocol_manager.cc
+++ b/libs/ardour/control_protocol_manager.cc
@@ -43,7 +43,7 @@ void
ControlProtocolManager::set_session (Session& s)
{
_session = &s;
- _session->going_away.connect (mem_fun (*this, &ControlProtocolManager::drop_session));
+ _session->GoingAway.connect (mem_fun (*this, &ControlProtocolManager::drop_session));
for (list<ControlProtocolInfo*>::iterator i = control_protocol_info.begin(); i != control_protocol_info.end(); ++i) {
if ((*i)->requested || (*i)->mandatory) {
diff --git a/libs/ardour/coreaudiosource.cc b/libs/ardour/coreaudiosource.cc
index d2a9a8c8e6..652ca1e4f2 100644
--- a/libs/ardour/coreaudiosource.cc
+++ b/libs/ardour/coreaudiosource.cc
@@ -141,7 +141,7 @@ CoreAudioSource::init (const string& idstr)
CoreAudioSource::~CoreAudioSource ()
{
- GoingAway (this); /* EMIT SIGNAL */
+ GoingAway (); /* EMIT SIGNAL */
if (af) {
ExtAudioFileDispose (af);
diff --git a/libs/ardour/crossfade.cc b/libs/ardour/crossfade.cc
index 379c9333b0..fcd2158fd8 100644
--- a/libs/ardour/crossfade.cc
+++ b/libs/ardour/crossfade.cc
@@ -1,5 +1,5 @@
/*
- Copyright (C) 2003 Paul Davis
+ Copyright (C) 2003-2006 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
@@ -36,7 +36,7 @@ using namespace ARDOUR;
using namespace PBD;
jack_nframes_t Crossfade::_short_xfade_length = 0;
-Change Crossfade::ActiveChanged = ARDOUR::new_change();
+Change Crossfade::ActiveChanged = new_change();
/* XXX if and when we ever implement parallel processing of the process()
callback, these will need to be handled on a per-thread basis.
@@ -70,15 +70,15 @@ Crossfade::operator== (const Crossfade& other)
return (_in == other._in) && (_out == other._out);
}
-Crossfade::Crossfade (ARDOUR::AudioRegion& in, ARDOUR::AudioRegion& out,
+Crossfade::Crossfade (boost::shared_ptr<AudioRegion> in, boost::shared_ptr<AudioRegion> out,
jack_nframes_t length,
jack_nframes_t position,
AnchorPoint ap)
: _fade_in (0.0, 2.0, 1.0), // linear (gain coefficient) => -inf..+6dB
_fade_out (0.0, 2.0, 1.0) // linear (gain coefficient) => -inf..+6dB
{
- _in = &in;
- _out = &out;
+ _in = in;
+ _out = out;
_length = length;
_position = position;
_anchor_point = ap;
@@ -89,7 +89,7 @@ Crossfade::Crossfade (ARDOUR::AudioRegion& in, ARDOUR::AudioRegion& out,
initialize ();
}
-Crossfade::Crossfade (ARDOUR::AudioRegion& a, ARDOUR::AudioRegion& b, CrossfadeModel model, bool act)
+Crossfade::Crossfade (boost::shared_ptr<AudioRegion> a, boost::shared_ptr<AudioRegion> b, CrossfadeModel model, bool act)
: _fade_in (0.0, 2.0, 1.0), // linear (gain coefficient) => -inf..+6dB
_fade_out (0.0, 2.0, 1.0) // linear (gain coefficient) => -inf..+6dB
{
@@ -110,7 +110,7 @@ Crossfade::Crossfade (const Playlist& playlist, XMLNode& node)
: _fade_in (0.0, 2.0, 1.0), // linear (gain coefficient) => -inf..+6dB
_fade_out (0.0, 2.0, 1.0) // linear (gain coefficient) => -inf..+6dB
{
- Region* r;
+ boost::shared_ptr<Region> r;
XMLProperty* prop;
LocaleGuard lg (X_("POSIX"));
@@ -129,7 +129,7 @@ Crossfade::Crossfade (const Playlist& playlist, XMLNode& node)
throw failed_constructor();
}
- if ((_in = dynamic_cast<AudioRegion*> (r)) == 0) {
+ if ((_in = boost::dynamic_pointer_cast<AudioRegion> (r)) == 0) {
throw failed_constructor();
}
@@ -146,7 +146,7 @@ Crossfade::Crossfade (const Playlist& playlist, XMLNode& node)
throw failed_constructor();
}
- if ((_out = dynamic_cast<AudioRegion*> (r)) == 0) {
+ if ((_out = boost::dynamic_pointer_cast<AudioRegion> (r)) == 0) {
throw failed_constructor();
}
@@ -160,7 +160,7 @@ Crossfade::Crossfade (const Playlist& playlist, XMLNode& node)
save_state ("initial");
}
-Crossfade::Crossfade (const Crossfade &orig, ARDOUR::AudioRegion *newin, ARDOUR::AudioRegion *newout)
+Crossfade::Crossfade (const Crossfade &orig, boost::shared_ptr<AudioRegion> newin, boost::shared_ptr<AudioRegion> newout)
: _fade_in(orig._fade_in),
_fade_out(orig._fade_out)
{
@@ -236,20 +236,20 @@ Crossfade::initialize (bool savestate)
}
int
-Crossfade::compute (AudioRegion& a, AudioRegion& b, CrossfadeModel model)
+Crossfade::compute (boost::shared_ptr<AudioRegion> a, boost::shared_ptr<AudioRegion> b, CrossfadeModel model)
{
- AudioRegion* top;
- AudioRegion* bottom;
+ boost::shared_ptr<AudioRegion> top;
+ boost::shared_ptr<AudioRegion> bottom;
jack_nframes_t short_xfade_length;
short_xfade_length = _short_xfade_length;
- if (a.layer() < b.layer()) {
- top = &b;
- bottom = &a;
+ if (a->layer() < b->layer()) {
+ top = b;
+ bottom = a;
} else {
- top = &a;
- bottom = &b;
+ top = a;
+ bottom = b;
}
/* first check for matching ends */
@@ -605,7 +605,7 @@ Crossfade::member_changed (Change what_changed)
{
Change what_we_care_about = Change (Region::MuteChanged|
Region::LayerChanged|
- ARDOUR::BoundsChanged);
+ BoundsChanged);
if (what_changed & what_we_care_about) {
refresh ();
diff --git a/libs/ardour/destructive_filesource.cc b/libs/ardour/destructive_filesource.cc
index 65ca8dae67..7bf47e84a0 100644
--- a/libs/ardour/destructive_filesource.cc
+++ b/libs/ardour/destructive_filesource.cc
@@ -376,7 +376,7 @@ DestructiveFileSource::write_unlocked (Sample* data, jack_nframes_t cnt)
}
if (_build_peakfiles) {
- queue_for_peaks (*this);
+ queue_for_peaks (this);
}
return cnt;
diff --git a/libs/ardour/diskstream.cc b/libs/ardour/diskstream.cc
index 9a80f3e70f..a5c4d769b1 100644
--- a/libs/ardour/diskstream.cc
+++ b/libs/ardour/diskstream.cc
@@ -32,6 +32,8 @@
#include <sys/stat.h>
#include <sys/mman.h>
+#include <sigc++/bind.h>
+
#include <pbd/error.h>
#include <pbd/basename.h>
#include <glibmm/thread.h>
@@ -63,7 +65,7 @@ using namespace PBD;
*/
jack_nframes_t Diskstream::disk_io_chunk_frames = 1024 * 256;
-sigc::signal<void,list<Source*>*> Diskstream::DeleteSources;
+sigc::signal<void,list<boost::shared_ptr<Source> >*> Diskstream::DeleteSources;
sigc::signal<void> Diskstream::DiskOverrun;
sigc::signal<void> Diskstream::DiskUnderrun;
@@ -330,7 +332,7 @@ Diskstream::use_playlist (Playlist* playlist)
plstate_connection = _playlist->StateChanged.connect (mem_fun (*this, &Diskstream::playlist_changed));
plmod_connection = _playlist->Modified.connect (mem_fun (*this, &Diskstream::playlist_modified));
- plgone_connection = _playlist->GoingAway.connect (mem_fun (*this, &Diskstream::playlist_deleted));
+ plgone_connection = _playlist->GoingAway.connect (bind (mem_fun (*this, &Diskstream::playlist_deleted), _playlist));
}
if (!overwrite_queued) {
diff --git a/libs/ardour/import.cc b/libs/ardour/import.cc
index 6d98388941..14f67245fd 100644
--- a/libs/ardour/import.cc
+++ b/libs/ardour/import.cc
@@ -35,11 +35,15 @@
#include <pbd/basename.h>
#include <ardour/ardour.h>
+#include <ardour/types.h>
#include <ardour/session.h>
#include <ardour/audio_diskstream.h>
#include <ardour/sndfilesource.h>
#include <ardour/sndfile_helpers.h>
#include <ardour/audioregion.h>
+#include <ardour/region_factory.h>
+#include <ardour/source_factory.h>
+
#include "i18n.h"
@@ -52,8 +56,8 @@ int
Session::import_audiofile (import_status& status)
{
SNDFILE *in;
- AudioFileSource **newfiles = 0;
- AudioRegion::SourceList sources;
+ vector<boost::shared_ptr<AudioFileSource> > newfiles;
+ SourceList sources;
SF_INFO info;
float *data = 0;
Sample **channel_data = 0;
@@ -94,11 +98,10 @@ Session::import_audiofile (import_status& status)
}
}
- newfiles = new AudioFileSource *[info.channels];
for (n = 0; n < info.channels; ++n) {
- newfiles[n] = 0;
+ newfiles.push_back (boost::shared_ptr<AudioFileSource>());
}
-
+
sounds_dir = discover_best_sound_dir ();
basepath = PBD::basename_nosuffix (status.pathname);
@@ -135,12 +138,9 @@ Session::import_audiofile (import_status& status)
} while ( !goodfile);
-
try {
- newfiles[n] = new SndFileSource (buf,
- Config->get_native_file_data_format(),
- Config->get_native_file_header_format(),
- frame_rate ());
+ newfiles[n] = boost::dynamic_pointer_cast<AudioFileSource> (
+ SourceFactory::createWritable (DataType::AUDIO, buf, false, frame_rate()));
}
catch (failed_constructor& err) {
@@ -217,8 +217,8 @@ Session::import_audiofile (import_status& status)
sources.push_back(newfiles[n]);
}
- AudioRegion *r = new AudioRegion (sources, 0, newfiles[0]->length(), region_name_from_path (Glib::path_get_basename (basepath)),
- 0, AudioRegion::Flag (AudioRegion::DefaultFlags | AudioRegion::WholeFile));
+ boost::shared_ptr<AudioRegion> r (boost::dynamic_pointer_cast<AudioRegion> (RegionFactory::create (sources, 0, newfiles[0]->length(), region_name_from_path (Glib::path_get_basename (basepath)),
+ 0, AudioRegion::Flag (AudioRegion::DefaultFlags | AudioRegion::WholeFile))));
status.new_regions.push_back (r);
@@ -233,10 +233,10 @@ Session::import_audiofile (import_status& status)
did not bother to create whole-file AudioRegions for them. Do it now.
*/
- AudioRegion *r = new AudioRegion (*newfiles[n], 0, newfiles[n]->length(), region_name_from_path (Glib::path_get_basename (newfiles[n]->name())),
- 0, AudioRegion::Flag (AudioRegion::DefaultFlags | AudioRegion::WholeFile | AudioRegion::Import));
-
- status.new_regions.push_back (r);
+ status.new_regions.push_back (boost::dynamic_pointer_cast<AudioRegion>
+ (RegionFactory::create (boost::static_pointer_cast<Source> (newfiles[n]), 0, newfiles[n]->length(),
+ region_name_from_path (Glib::path_get_basename (newfiles[n]->name())),
+ 0, AudioRegion::Flag (AudioRegion::DefaultFlags | AudioRegion::WholeFile | AudioRegion::Import))));
}
}
@@ -262,19 +262,13 @@ Session::import_audiofile (import_status& status)
}
if (status.cancel) {
- for (vector<Region *>::iterator i = status.new_regions.begin(); i != status.new_regions.end(); ++i) {
- delete *i;
- }
+ status.new_regions.clear ();
for (vector<string>::iterator i = new_paths.begin(); i != new_paths.end(); ++i) {
unlink ((*i).c_str());
}
}
- if (newfiles) {
- delete [] newfiles;
- }
-
if (tmp_convert_file.length()) {
unlink(tmp_convert_file.c_str());
}
diff --git a/libs/ardour/insert.cc b/libs/ardour/insert.cc
index f4263099eb..2fe40424fd 100644
--- a/libs/ardour/insert.cc
+++ b/libs/ardour/insert.cc
@@ -176,7 +176,7 @@ PluginInsert::init ()
PluginInsert::~PluginInsert ()
{
- GoingAway (this); /* EMIT SIGNAL */
+ GoingAway (); /* EMIT SIGNAL */
}
void
@@ -907,7 +907,7 @@ PortInsert::PortInsert (Session& s, const XMLNode& node)
PortInsert::~PortInsert ()
{
- GoingAway (this);
+ GoingAway ();
}
void
diff --git a/libs/ardour/io.cc b/libs/ardour/io.cc
index 430801310d..0abc10648e 100644
--- a/libs/ardour/io.cc
+++ b/libs/ardour/io.cc
@@ -129,13 +129,13 @@ IO::IO (Session& s, string name,
_gain_automation_state = Off;
_gain_automation_style = Absolute;
-
- {
- // IO::Meter is emitted from another thread so the
- // Meter signal must be protected.
- Glib::Mutex::Lock guard (m_meter_signal_lock);
- m_meter_connection = Meter.connect (mem_fun (*this, &IO::meter));
- }
+
+ {
+ // IO::Meter is emitted from another thread so the
+ // Meter signal must be protected.
+ Glib::Mutex::Lock guard (m_meter_signal_lock);
+ m_meter_connection = Meter.connect (mem_fun (*this, &IO::meter));
+ }
// Connect to our own MoreChannels signal to connect output buffers
IO::MoreChannels.connect (mem_fun (*this, &IO::attach_buffers));
@@ -143,7 +143,8 @@ IO::IO (Session& s, string name,
IO::~IO ()
{
- Glib::Mutex::Lock guard (m_meter_signal_lock);
+ Glib::Mutex::Lock guard (m_meter_signal_lock);
+
Glib::Mutex::Lock lm (io_lock);
for (PortSet::iterator i = _inputs.begin(); i != _inputs.end(); ++i) {
@@ -154,7 +155,7 @@ IO::~IO ()
_session.engine().unregister_port (*i);
}
- m_meter_connection.disconnect();
+ m_meter_connection.disconnect();
delete _meter;
delete _panner;
diff --git a/libs/ardour/ladspa_plugin.cc b/libs/ardour/ladspa_plugin.cc
index 803cbd74a0..82cc4e6202 100644
--- a/libs/ardour/ladspa_plugin.cc
+++ b/libs/ardour/ladspa_plugin.cc
@@ -144,7 +144,7 @@ LadspaPlugin::~LadspaPlugin ()
deactivate ();
cleanup ();
- GoingAway (this); /* EMIT SIGNAL */
+ GoingAway (); /* EMIT SIGNAL */
/* XXX who should close a plugin? */
diff --git a/libs/ardour/location.cc b/libs/ardour/location.cc
index ca88a2851b..58ef812d2e 100644
--- a/libs/ardour/location.cc
+++ b/libs/ardour/location.cc
@@ -51,6 +51,13 @@ Location::Location (const Location& other)
_flags = Flags (_flags & ~IsEnd);
}
+Location::Location (const XMLNode& node)
+{
+ if (set_state (node)) {
+ throw failed_constructor ();
+ }
+}
+
Location*
Location::operator= (const Location& other)
{
@@ -241,13 +248,16 @@ XMLNode&
Location::get_state (void)
{
XMLNode *node = new XMLNode ("Location");
- char buf[32];
+ char buf[64];
typedef map<string, string>::const_iterator CI;
+
for(CI m = cd_info.begin(); m != cd_info.end(); ++m){
node->add_child_nocopy(cd_info_node(m->first, m->second));
}
+ id().print (buf);
+ node->add_property("id", buf);
node->add_property ("name", name());
snprintf (buf, sizeof (buf), "%u", start());
node->add_property ("start", buf);
@@ -262,7 +272,6 @@ Location::get_state (void)
int
Location::set_state (const XMLNode& node)
{
- XMLPropertyList plist;
const XMLProperty *prop;
XMLNodeList cd_list = node.children();
@@ -272,14 +281,17 @@ Location::set_state (const XMLNode& node)
string cd_name;
string cd_value;
-
if (node.name() != "Location") {
error << _("incorrect XML node passed to Location::set_state") << endmsg;
return -1;
}
- plist = node.properties();
-
+ if ((prop = node.property ("id")) == 0) {
+ warning << _("XML node for Location has no ID information") << endmsg;
+ } else {
+ _id = prop->value ();
+ }
+
if ((prop = node.property ("name")) == 0) {
error << _("XML node for Location has no name information") << endmsg;
return -1;
@@ -582,16 +594,20 @@ Locations::set_state (const XMLNode& node)
Glib::Mutex::Lock lm (lock);
for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
- Location *loc = new Location;
- if (loc->set_state (**niter)) {
- delete loc;
- } else {
+ try {
+
+ Location *loc = new Location (**niter);
locations.push_back (loc);
}
+
+ catch (failed_constructor& err) {
+ error << _("could not load location from session file - ignored") << endmsg;
+ }
}
if (locations.size()) {
+
current_location = locations.front();
} else {
current_location = 0;
diff --git a/libs/ardour/midi_diskstream.cc b/libs/ardour/midi_diskstream.cc
index e42e455df0..6435655689 100644
--- a/libs/ardour/midi_diskstream.cc
+++ b/libs/ardour/midi_diskstream.cc
@@ -45,6 +45,7 @@
#include <ardour/smf_source.h>
#include <ardour/destructive_filesource.h>
#include <ardour/send.h>
+#include <ardour/region_factory.h>
#include <ardour/midi_playlist.h>
#include <ardour/cycle_timer.h>
#include <ardour/midi_region.h>
@@ -66,7 +67,6 @@ MidiDiskstream::MidiDiskstream (Session &sess, const string &name, Diskstream::F
//, _playback_wrap_buffer(0)
//, _capture_wrap_buffer(0)
, _source_port(0)
- , _write_source(0)
, _capture_transition_buf(0)
, _last_flush_frame(0)
{
@@ -91,7 +91,6 @@ MidiDiskstream::MidiDiskstream (Session& sess, const XMLNode& node)
//, _playback_wrap_buffer(0)
//, _capture_wrap_buffer(0)
, _source_port(0)
- , _write_source(0)
, _capture_transition_buf(0)
, _last_flush_frame(0)
{
@@ -972,7 +971,7 @@ MidiDiskstream::transport_stopped (struct tm& when, time_t twhen, bool abort_cap
uint32_t buffer_position;
bool more_work = true;
int err = 0;
- MidiRegion* region = 0;
+ boost::shared_ptr<MidiRegion> region;
jack_nframes_t total_capture;
MidiRegion::SourceList srcs;
MidiRegion::SourceList::iterator src;
@@ -1007,15 +1006,15 @@ MidiDiskstream::transport_stopped (struct tm& when, time_t twhen, bool abort_cap
if (abort_capture) {
- list<Source*>* deletion_list = new list<Source*>;
+ list<boost::shared_ptr<Source> >* deletion_list = new list<boost::shared_ptr<Source> >;
if (_write_source) {
+
_write_source->mark_for_remove ();
- _write_source->release ();
deletion_list->push_back (_write_source);
- _write_source = 0;
+ _write_source.reset();
}
/* new source set up in "out" below */
@@ -1036,7 +1035,7 @@ MidiDiskstream::transport_stopped (struct tm& when, time_t twhen, bool abort_cap
/* figure out the name for this take */
- SMFSource* s = _write_source;
+ boost::shared_ptr<SMFSource> s = _write_source;
if (s) {
@@ -1056,10 +1055,12 @@ MidiDiskstream::transport_stopped (struct tm& when, time_t twhen, bool abort_cap
*/
try {
assert(_write_source);
- region = new MidiRegion (srcs, _write_source->last_capture_start_frame(), total_capture,
- region_name_from_path (_write_source->name()),
- 0, Region::Flag (Region::DefaultFlags|Region::Automatic|Region::WholeFile));
+
+ boost::shared_ptr<Region> rx (RegionFactory::create (srcs, _write_source->last_capture_start_frame(), total_capture,
+ region_name_from_path (_write_source->name()),
+ 0, Region::Flag (Region::DefaultFlags|Region::Automatic|Region::WholeFile)));
+ region = boost::dynamic_pointer_cast<MidiRegion> (rx);
region->special_set_position (capture_info.front()->start);
}
@@ -1084,11 +1085,12 @@ MidiDiskstream::transport_stopped (struct tm& when, time_t twhen, bool abort_cap
// cerr << _name << ": based on ci of " << (*ci)->start << " for " << (*ci)->frames << " add a region\n";
try {
- region = new MidiRegion (srcs, buffer_position, (*ci)->frames, region_name);
+ boost::shared_ptr<Region> rx (RegionFactory::create (srcs, buffer_position, (*ci)->frames, region_name));
+ region = boost::dynamic_pointer_cast<MidiRegion> (rx);
}
catch (failed_constructor& err) {
- error << _("MidiDiskstream: could not create region for captured audio!") << endmsg;
+ error << _("MidiDiskstream: could not create region for captured midi!") << endmsg;
continue; /* XXX is this OK? */
}
@@ -1097,7 +1099,7 @@ MidiDiskstream::transport_stopped (struct tm& when, time_t twhen, bool abort_cap
// cerr << "add new region, buffer position = " << buffer_position << " @ " << (*ci)->start << endl;
i_am_the_modifier++;
- _playlist->add_region (*region, (*ci)->start);
+ _playlist->add_region (region, (*ci)->start);
i_am_the_modifier--;
buffer_position += (*ci)->frames;
@@ -1361,16 +1363,14 @@ MidiDiskstream::use_new_write_source (uint32_t n)
if (SMFSource::is_empty (_write_source->path())) {
_write_source->mark_for_remove ();
- _write_source->release();
- delete _write_source;
+ _write_source.reset();
} else {
- _write_source->release();
- _write_source = 0;
+ _write_source.reset();
}
}
try {
- _write_source = dynamic_cast<SMFSource*>(_session.create_midi_source_for_session (*this));
+ _write_source = boost::dynamic_pointer_cast<SMFSource>(_session.create_midi_source_for_session (*this));
if (!_write_source) {
throw failed_constructor();
}
@@ -1378,11 +1378,10 @@ MidiDiskstream::use_new_write_source (uint32_t n)
catch (failed_constructor &err) {
error << string_compose (_("%1:%2 new capture file not initialized correctly"), _name, n) << endmsg;
- _write_source = 0;
+ _write_source.reset();
return -1;
}
- _write_source->use ();
_write_source->set_allow_remove_if_empty (true);
return 0;
diff --git a/libs/ardour/midi_playlist.cc b/libs/ardour/midi_playlist.cc
index 051203e55e..7f2781d707 100644
--- a/libs/ardour/midi_playlist.cc
+++ b/libs/ardour/midi_playlist.cc
@@ -129,44 +129,19 @@ MidiPlaylist::MidiPlaylist (const MidiPlaylist& other, jack_nframes_t start, jac
MidiPlaylist::~MidiPlaylist ()
{
- set <Region*> all_regions;
-
- GoingAway (this);
-
- /* find every region we've ever used, and add it to the set of
- all regions.
- */
-
- for (RegionList::iterator x = regions.begin(); x != regions.end(); ++x) {
- all_regions.insert (*x);
- }
+ GoingAway (); /* EMIT SIGNAL */
for (StateMap::iterator i = states.begin(); i != states.end(); ++i) {
MidiPlaylist::State* apstate = dynamic_cast<MidiPlaylist::State*> (*i);
-
- for (RegionList::iterator r = apstate->regions.begin(); r != apstate->regions.end(); ++r) {
- all_regions.insert (*r);
- }
-
delete apstate;
}
-
- /* delete every region */
-
- for (set<Region *>::iterator ar = all_regions.begin(); ar != all_regions.end(); ++ar) {
- (*ar)->unlock_sources ();
- delete *ar;
- }
-
}
-struct RegionSortByLayer
-{
- bool operator() (Region *a, Region *b)
- {
- return a->layer() < b->layer();
- }
+struct RegionSortByLayer {
+ bool operator() (boost::shared_ptr<Region> a, boost::shared_ptr<Region> b) {
+ return a->layer() < b->layer();
+ }
};
/** Returns the number of frames in time duration read (eg could be large when 0 events are read) */
@@ -187,22 +162,24 @@ MidiPlaylist::read (MidiRingBuffer& dst, jack_nframes_t start,
//_read_data_count = 0;
- vector<MidiRegion*> regs; // relevent regions overlapping start <--> end
+ // relevent regions overlapping start <--> end
+ vector<boost::shared_ptr<Region> > regs;
for (RegionList::iterator i = regions.begin(); i != regions.end(); ++i) {
- MidiRegion* const mr = dynamic_cast<MidiRegion*>(*i);
- if (mr && mr->coverage (start, end) != OverlapNone) {
- regs.push_back(mr);
+
+ if ((*i)->coverage (start, end) != OverlapNone) {
+ regs.push_back(*i);
}
}
RegionSortByLayer layer_cmp;
sort(regs.begin(), regs.end(), layer_cmp);
- for (vector<MidiRegion*>::iterator i = regs.begin(); i != regs.end(); ++i) {
+ for (vector<boost::shared_ptr<Region> >::iterator i = regs.begin(); i != regs.end(); ++i) {
// FIXME: ensure time is monotonic here
- (*i)->read_at (dst, start, dur, chan_n, 0, 0);// FIXME read_frames, skip_frames);
- ret += (*i)->read_data_count();
+ boost::shared_ptr<MidiRegion> mr = boost::dynamic_pointer_cast<MidiRegion>(*i);
+ mr->read_at (dst, start, dur, chan_n, 0, 0);// FIXME read_frames, skip_frames);
+ ret += mr->read_data_count();
}
_read_data_count += ret;
@@ -213,16 +190,8 @@ MidiPlaylist::read (MidiRingBuffer& dst, jack_nframes_t start,
void
-MidiPlaylist::remove_dependents (Region& region)
+MidiPlaylist::remove_dependents (boost::shared_ptr<Region> region)
{
- MidiRegion* r = dynamic_cast<MidiRegion*> (&region);
-
- if (r == 0) {
- PBD::fatal << _("programming error: non-midi Region passed to remove_overlap in midi playlist")
- << endmsg;
- return;
- }
-
}
@@ -241,17 +210,12 @@ MidiPlaylist::flush_notifications ()
}
void
-MidiPlaylist::refresh_dependents (Region& r)
+MidiPlaylist::refresh_dependents (boost::shared_ptr<Region> r)
{
- MidiRegion* ar = dynamic_cast<MidiRegion*>(&r);
-
- if (ar == 0) {
- return;
- }
}
void
-MidiPlaylist::finalize_split_region (Region *o, Region *l, Region *r)
+MidiPlaylist::finalize_split_region (boost::shared_ptr<Region> original, boost::shared_ptr<Region> left, boost::shared_ptr<Region> right)
{
throw; // I don't wanna
/*
@@ -293,48 +257,8 @@ MidiPlaylist::finalize_split_region (Region *o, Region *l, Region *r)
}
void
-MidiPlaylist::check_dependents (Region& r, bool norefresh)
+MidiPlaylist::check_dependents (boost::shared_ptr<Region> r, bool norefresh)
{
- MidiRegion* other;
- MidiRegion* region;
- MidiRegion* top;
- MidiRegion* bottom;
-
- if (in_set_state || in_partition) {
- return;
- }
-
- if ((region = dynamic_cast<MidiRegion*> (&r)) == 0) {
- PBD::fatal << _("programming error: non-midi Region tested for overlap in midi playlist")
- << endmsg;
- return;
- }
-
- if (!norefresh) {
- refresh_dependents (r);
- }
-
- for (RegionList::iterator i = regions.begin(); i != regions.end(); ++i) {
-
- other = dynamic_cast<MidiRegion*> (*i);
-
- if (other == region) {
- continue;
- }
-
- if (other->muted() || region->muted()) {
- continue;
- }
-
- if (other->layer() < region->layer()) {
- top = region;
- bottom = other;
- } else {
- top = other;
- bottom = region;
- }
-
- }
}
@@ -362,14 +286,14 @@ MidiPlaylist::set_state (const XMLNode& node)
void
MidiPlaylist::drop_all_states ()
{
- set<Region*> all_regions;
+ set<boost::shared_ptr<Region> > all_regions;
- /* find every region we've ever used, and add it to the set of
+ /* find every region we've ever used, and add it to the set of
all regions. same for xfades;
*/
for (StateMap::iterator i = states.begin(); i != states.end(); ++i) {
-
+
MidiPlaylist::State* apstate = dynamic_cast<MidiPlaylist::State*> (*i);
for (RegionList::iterator r = apstate->regions.begin(); r != apstate->regions.end(); ++r) {
@@ -379,21 +303,13 @@ MidiPlaylist::drop_all_states ()
/* now remove from the "all" lists every region that is in the current list. */
- for (list<Region*>::iterator i = regions.begin(); i != regions.end(); ++i) {
- set
- <Region*>::iterator x = all_regions.find (*i);
+ for (RegionList::iterator i = regions.begin(); i != regions.end(); ++i) {
+ set<boost::shared_ptr<Region> >::iterator x = all_regions.find (*i);
if (x != all_regions.end()) {
all_regions.erase (x);
}
}
-
- /* delete every region that is left - these are all things that are part of our "history" */
-
- for (set<Region *>::iterator ar = all_regions.begin(); ar != all_regions.end(); ++ar) {
- (*ar)->unlock_sources ();
- delete *ar;
- }
-
+
/* Now do the generic thing ... */
StateManager::drop_all_states ();
@@ -456,7 +372,7 @@ MidiPlaylist::state (bool full_state)
void
MidiPlaylist::dump () const
{
- Region *r;
+ boost::shared_ptr<Region> r;
cerr << "Playlist \"" << _name << "\" " << endl
<< regions.size() << " regions "
@@ -475,9 +391,9 @@ MidiPlaylist::dump () const
}
bool
-MidiPlaylist::destroy_region (Region* region)
+MidiPlaylist::destroy_region (boost::shared_ptr<Region> region)
{
- MidiRegion* r = dynamic_cast<MidiRegion*> (region);
+ boost::shared_ptr<MidiRegion> r = boost::dynamic_pointer_cast<MidiRegion> (region);
bool changed = false;
if (r == 0) {
@@ -498,7 +414,6 @@ MidiPlaylist::destroy_region (Region* region)
++tmp;
if ((*i) == region) {
- (*i)->unlock_sources ();
regions.erase (i);
changed = true;
}
@@ -549,41 +464,8 @@ MidiPlaylist::destroy_region (Region* region)
return changed;
}
-
-void
-MidiPlaylist::get_equivalent_regions (const MidiRegion& other, vector<MidiRegion*>& results)
-{
- for (RegionList::iterator i = regions.begin(); i != regions.end(); ++i) {
-
- MidiRegion* ar = dynamic_cast<MidiRegion*> (*i);
-
- if (ar) {
- if (Config->get_use_overlap_equivalency()) {
- if (ar->overlap_equivalent (other)) {
- results.push_back (ar);
- } else if (ar->equivalent (other)) {
- results.push_back (ar);
- }
- }
- }
- }
-}
-
-void
-MidiPlaylist::get_region_list_equivalent_regions (const MidiRegion& other, vector<MidiRegion*>& results)
-{
- for (RegionList::iterator i = regions.begin(); i != regions.end(); ++i) {
-
- MidiRegion* ar = dynamic_cast<MidiRegion*> (*i);
-
- if (ar && ar->region_list_equivalent (other)) {
- results.push_back (ar);
- }
- }
-}
-
bool
-MidiPlaylist::region_changed (Change what_changed, Region* region)
+MidiPlaylist::region_changed (Change what_changed, boost::shared_ptr<Region> region)
{
if (in_flush || in_set_state) {
return false;
diff --git a/libs/ardour/midi_region.cc b/libs/ardour/midi_region.cc
index 136b2bfc38..c4816d8121 100644
--- a/libs/ardour/midi_region.cc
+++ b/libs/ardour/midi_region.cc
@@ -48,68 +48,51 @@ using namespace std;
using namespace ARDOUR;
/** Basic MidiRegion constructor (one channel) */
-MidiRegion::MidiRegion (MidiSource& src, jack_nframes_t start, jack_nframes_t length, bool announce)
- : Region (src, start, length, PBD::basename_nosuffix(src.name()), DataType::MIDI, 0, Region::Flag(Region::DefaultFlags|Region::External))
+MidiRegion::MidiRegion (boost::shared_ptr<MidiSource> src, jack_nframes_t start, jack_nframes_t length)
+ : Region (src, start, length, PBD::basename_nosuffix(src->name()), DataType::MIDI, 0, Region::Flag(Region::DefaultFlags|Region::External))
{
save_state ("initial state");
- if (announce) {
- CheckNewRegion (this); /* EMIT SIGNAL */
- }
-
assert(_name.find("/") == string::npos);
}
/* Basic MidiRegion constructor (one channel) */
-MidiRegion::MidiRegion (MidiSource& src, jack_nframes_t start, jack_nframes_t length, const string& name, layer_t layer, Flag flags, bool announce)
+MidiRegion::MidiRegion (boost::shared_ptr<MidiSource> src, jack_nframes_t start, jack_nframes_t length, const string& name, layer_t layer, Flag flags)
: Region (src, start, length, name, DataType::MIDI, layer, flags)
{
save_state ("initial state");
- if (announce) {
- CheckNewRegion (this); /* EMIT SIGNAL */
- }
-
assert(_name.find("/") == string::npos);
}
/* Basic MidiRegion constructor (many channels) */
-MidiRegion::MidiRegion (SourceList& srcs, jack_nframes_t start, jack_nframes_t length, const string& name, layer_t layer, Flag flags, bool announce)
+MidiRegion::MidiRegion (SourceList& srcs, jack_nframes_t start, jack_nframes_t length, const string& name, layer_t layer, Flag flags)
: Region (srcs, start, length, name, DataType::MIDI, layer, flags)
{
save_state ("initial state");
- if (announce) {
- CheckNewRegion (this); /* EMIT SIGNAL */
- }
-
assert(_name.find("/") == string::npos);
}
/** Create a new MidiRegion, that is part of an existing one */
-MidiRegion::MidiRegion (const MidiRegion& other, jack_nframes_t offset, jack_nframes_t length, const string& name, layer_t layer, Flag flags, bool announce)
+MidiRegion::MidiRegion (boost::shared_ptr<const MidiRegion> other, jack_nframes_t offset, jack_nframes_t length, const string& name, layer_t layer, Flag flags)
: Region (other, offset, length, name, layer, flags)
{
save_state ("initial state");
- if (announce) {
- CheckNewRegion (this); /* EMIT SIGNAL */
- }
-
assert(_name.find("/") == string::npos);
}
-MidiRegion::MidiRegion (const MidiRegion &other)
+MidiRegion::MidiRegion (boost::shared_ptr<const MidiRegion> other)
: Region (other)
{
save_state ("initial state");
- /* NOTE: no CheckNewRegion signal emitted here. This is the copy constructor */
assert(_name.find("/") == string::npos);
}
-MidiRegion::MidiRegion (MidiSource& src, const XMLNode& node)
+MidiRegion::MidiRegion (boost::shared_ptr<MidiSource> src, const XMLNode& node)
: Region (src, node)
{
if (set_state (node)) {
@@ -120,8 +103,6 @@ MidiRegion::MidiRegion (MidiSource& src, const XMLNode& node)
assert(_name.find("/") == string::npos);
assert(_type == DataType::MIDI);
-
- CheckNewRegion (this); /* EMIT SIGNAL */
}
MidiRegion::MidiRegion (SourceList& srcs, const XMLNode& node)
@@ -135,13 +116,11 @@ MidiRegion::MidiRegion (SourceList& srcs, const XMLNode& node)
assert(_name.find("/") == string::npos);
assert(_type == DataType::MIDI);
-
- CheckNewRegion (this); /* EMIT SIGNAL */
}
MidiRegion::~MidiRegion ()
{
- GoingAway (this);
+ GoingAway (); /* EMIT SIGNAL */
}
StateManager::State*
@@ -260,12 +239,12 @@ MidiRegion::_read_at (const SourceList& srcs, MidiRingBuffer& dst,
_read_data_count = 0;
- MidiSource& src = midi_source(chan_n);
- if (src.read (dst, _start + internal_offset, to_read, _position) != to_read) {
+ boost::shared_ptr<MidiSource> src = midi_source(chan_n);
+ if (src->read (dst, _start + internal_offset, to_read, _position) != to_read) {
return 0; /* "read nothing" */
}
- _read_data_count += src.read_data_count(); // FIXME: semantics?
+ _read_data_count += src->read_data_count(); // FIXME: semantics?
return to_read;
}
@@ -380,10 +359,10 @@ MidiRegion::separate_by_channel (Session& session, vector<MidiRegion*>& v) const
return -1;
}
-MidiSource&
+boost::shared_ptr<MidiSource>
MidiRegion::midi_source (uint32_t n) const
{
// Guaranteed to succeed (use a static cast?)
- return dynamic_cast<MidiSource&>(source(n));
+ return boost::dynamic_pointer_cast<MidiSource>(source(n));
}
diff --git a/libs/ardour/osc.cc b/libs/ardour/osc.cc
index 5aaf9d5591..c43f254f6f 100644
--- a/libs/ardour/osc.cc
+++ b/libs/ardour/osc.cc
@@ -365,7 +365,7 @@ void
OSC::set_session (Session& s)
{
session = &s;
- session->going_away.connect (mem_fun (*this, &OSC::session_going_away));
+ session->GoingAway.connect (mem_fun (*this, &OSC::session_going_away));
}
void
diff --git a/libs/ardour/playlist.cc b/libs/ardour/playlist.cc
index 61aa5c587a..f778175e9e 100644
--- a/libs/ardour/playlist.cc
+++ b/libs/ardour/playlist.cc
@@ -55,19 +55,19 @@ struct ShowMeTheList {
};
struct RegionSortByLayer {
- bool operator() (Region *a, Region *b) {
+ bool operator() (boost::shared_ptr<Region> a, boost::shared_ptr<Region> b) {
return a->layer() < b->layer();
}
};
struct RegionSortByPosition {
- bool operator() (Region *a, Region *b) {
+ bool operator() (boost::shared_ptr<Region> a, boost::shared_ptr<Region> b) {
return a->position() < b->position();
}
};
struct RegionSortByLastLayerOp {
- bool operator() (Region *a, Region *b) {
+ bool operator() (boost::shared_ptr<Region> a, boost::shared_ptr<Region> b) {
return a->last_layer_op() < b->last_layer_op();
}
};
@@ -106,7 +106,7 @@ Playlist::Playlist (const Playlist& other, string namestr, bool hide)
in_set_state = true;
- for (list<Region*>::iterator x = tmp.begin(); x != tmp.end(); ++x) {
+ for (list<boost::shared_ptr<Region> >::iterator x = tmp.begin(); x != tmp.end(); ++x) {
add_region_internal( (*x), (*x)->position() );
}
@@ -140,8 +140,8 @@ Playlist::Playlist (const Playlist& other, jack_nframes_t start, jack_nframes_t
for (RegionList::const_iterator i = other.regions.begin(); i != other.regions.end(); i++) {
- Region *region;
- Region *new_region;
+ boost::shared_ptr<Region> region;
+ boost::shared_ptr<Region> new_region;
jack_nframes_t offset = 0;
jack_nframes_t position = 0;
jack_nframes_t len = 0;
@@ -183,7 +183,7 @@ Playlist::Playlist (const Playlist& other, jack_nframes_t start, jack_nframes_t
_session.region_name (new_name, region->name(), false);
- new_region = createRegion (*region, offset, len, new_name, region->layer(), region->flags());
+ new_region = RegionFactory::RegionFactory::create (region, offset, len, new_name, region->layer(), region->flags());
add_region_internal (new_region, position, true);
}
@@ -221,7 +221,7 @@ Playlist::copy_regions (RegionList& newlist) const
RegionLock rlock (const_cast<Playlist *> (this));
for (RegionList::const_iterator i = regions.begin(); i != regions.end(); ++i) {
- newlist.push_back (createRegion (**i));
+ newlist.push_back (RegionFactory::RegionFactory::create (*i));
}
}
@@ -266,6 +266,7 @@ Playlist::Playlist (Playlist& pl)
Playlist::~Playlist ()
{
+ /* GoingAway must be emitted by derived classes */
}
void
@@ -336,7 +337,7 @@ Playlist::notify_modified ()
}
void
-Playlist::notify_region_removed (Region *r)
+Playlist::notify_region_removed (boost::shared_ptr<Region> r)
{
if (holding_state ()) {
pending_removals.insert (pending_removals.end(), r);
@@ -351,7 +352,7 @@ Playlist::notify_region_removed (Region *r)
}
void
-Playlist::notify_region_added (Region *r)
+Playlist::notify_region_added (boost::shared_ptr<Region> r)
{
if (holding_state()) {
pending_adds.insert (pending_adds.end(), r);
@@ -381,7 +382,7 @@ Playlist::flush_notifications ()
{
RegionList::iterator r;
RegionList::iterator a;
- set<Region*> dependent_checks_needed;
+ set<boost::shared_ptr<Region> > dependent_checks_needed;
uint32_t n = 0;
if (in_flush) {
@@ -401,7 +402,7 @@ Playlist::flush_notifications ()
for (RegionList::iterator r = pending_bounds.begin(); r != pending_bounds.end(); ++r) {
if (_session.get_layer_model() == Session::MoveAddHigher) {
- timestamp_layer_op (**r);
+ timestamp_layer_op (*r);
}
pending_length = true;
n++;
@@ -418,12 +419,12 @@ Playlist::flush_notifications ()
n++;
}
- for (set<Region*>::iterator x = dependent_checks_needed.begin(); x != dependent_checks_needed.end(); ++x) {
- check_dependents (**x, false);
+ for (set<boost::shared_ptr<Region> >::iterator x = dependent_checks_needed.begin(); x != dependent_checks_needed.end(); ++x) {
+ check_dependents (*x, false);
}
for (r = pending_removals.begin(); r != pending_removals.end(); ++r) {
- remove_dependents (**r);
+ remove_dependents (*r);
RegionRemoved (*r); /* EMIT SIGNAL */
n++;
}
@@ -460,7 +461,7 @@ Playlist::flush_notifications ()
*************************************************************/
void
-Playlist::add_region (const Region& region, jack_nframes_t position, float times, bool with_save)
+Playlist::add_region (boost::shared_ptr<Region> region, jack_nframes_t position, float times, bool with_save)
{
RegionLock rlock (this);
@@ -471,8 +472,8 @@ Playlist::add_region (const Region& region, jack_nframes_t position, float times
jack_nframes_t pos = position;
if (itimes >= 1) {
- add_region_internal (const_cast<Region*>(&region), pos, true);
- pos += region.length();
+ add_region_internal (region, pos, true);
+ pos += region->length();
--itimes;
}
@@ -487,16 +488,16 @@ Playlist::add_region (const Region& region, jack_nframes_t position, float times
*/
for (int i = 0; i < itimes; ++i) {
- Region *copy = createRegion (region);
+ boost::shared_ptr<Region> copy = RegionFactory::create (region);
add_region_internal (copy, pos, true);
- pos += region.length();
+ pos += region->length();
}
if (floor (times) != times) {
- jack_nframes_t length = (jack_nframes_t) floor (region.length() * (times - floor (times)));
+ jack_nframes_t length = (jack_nframes_t) floor (region->length() * (times - floor (times)));
string name;
- _session.region_name (name, region.name(), false);
- Region *sub = createRegion (region, 0, length, name, region.layer(), region.flags());
+ _session.region_name (name, region->name(), false);
+ boost::shared_ptr<Region> sub = RegionFactory::create (region, 0, length, name, region->layer(), region->flags());
add_region_internal (sub, pos, true);
}
@@ -506,22 +507,19 @@ Playlist::add_region (const Region& region, jack_nframes_t position, float times
}
void
-Playlist::add_region_internal (Region *region, jack_nframes_t position, bool delay_sort)
+Playlist::add_region_internal (boost::shared_ptr<Region> region, jack_nframes_t position, bool delay_sort)
{
RegionSortByPosition cmp;
jack_nframes_t old_length = 0;
- // cerr << "adding region " << region->name() << " at " << position << endl;
-
if (!holding_state()) {
old_length = _get_maximum_extent();
}
region->set_playlist (this);
region->set_position (position, this);
- region->lock_sources ();
- timestamp_layer_op (*region);
+ timestamp_layer_op (region);
regions.insert (upper_bound (regions.begin(), regions.end(), region, cmp), region);
@@ -535,7 +533,7 @@ Playlist::add_region_internal (Region *region, jack_nframes_t position, bool del
notify_region_added (region);
if (!holding_state ()) {
- check_dependents (*region, false);
+ check_dependents (region, false);
if (old_length != _get_maximum_extent()) {
notify_length_changed ();
}
@@ -545,12 +543,12 @@ Playlist::add_region_internal (Region *region, jack_nframes_t position, bool del
}
void
-Playlist::replace_region (Region& old, Region& newr, jack_nframes_t pos)
+Playlist::replace_region (boost::shared_ptr<Region> old, boost::shared_ptr<Region> newr, jack_nframes_t pos)
{
RegionLock rlock (this);
- remove_region_internal (&old);
- add_region_internal (&newr, pos);
+ remove_region_internal (old);
+ add_region_internal (newr, pos);
if (!holding_state ()) {
possibly_splice_unlocked ();
@@ -560,7 +558,7 @@ Playlist::replace_region (Region& old, Region& newr, jack_nframes_t pos)
}
void
-Playlist::remove_region (Region *region)
+Playlist::remove_region (boost::shared_ptr<Region> region)
{
RegionLock rlock (this);
remove_region_internal (region);
@@ -573,7 +571,7 @@ Playlist::remove_region (Region *region)
}
int
-Playlist::remove_region_internal (Region *region, bool delay_sort)
+Playlist::remove_region_internal (boost::shared_ptr<Region>region, bool delay_sort)
{
RegionList::iterator i;
jack_nframes_t old_length = 0;
@@ -591,7 +589,7 @@ Playlist::remove_region_internal (Region *region, bool delay_sort)
if (!holding_state ()) {
relayer ();
- remove_dependents (*region);
+ remove_dependents (region);
if (old_length != _get_maximum_extent()) {
notify_length_changed ();
@@ -606,7 +604,7 @@ Playlist::remove_region_internal (Region *region, bool delay_sort)
}
void
-Playlist::get_equivalent_regions (const Region& other, vector<Region*>& results)
+Playlist::get_equivalent_regions (boost::shared_ptr<Region> other, vector<boost::shared_ptr<Region> >& results)
{
for (RegionList::iterator i = regions.begin(); i != regions.end(); ++i) {
if (Config->get_use_overlap_equivalency()) {
@@ -620,7 +618,7 @@ Playlist::get_equivalent_regions (const Region& other, vector<Region*>& results)
}
void
-Playlist::get_region_list_equivalent_regions (const Region& other, vector<Region*>& results)
+Playlist::get_region_list_equivalent_regions (boost::shared_ptr<Region> other, vector<boost::shared_ptr<Region> >& results)
{
for (RegionList::iterator i = regions.begin(); i != regions.end(); ++i) {
@@ -648,8 +646,8 @@ void
Playlist::partition_internal (jack_nframes_t start, jack_nframes_t end, bool cutting, RegionList& thawlist)
{
RegionLock rlock (this);
- Region *region;
- Region *current;
+ boost::shared_ptr<Region> region;
+ boost::shared_ptr<Region> current;
string new_name;
RegionList::iterator tmp;
OverlapType overlap;
@@ -709,7 +707,7 @@ Playlist::partition_internal (jack_nframes_t start, jack_nframes_t end, bool cut
/* "middle" ++++++ */
_session.region_name (new_name, current->name(), false);
- region = createRegion (*current, pos2 - pos1, pos3 - pos2, new_name,
+ region = RegionFactory::create (current, pos2 - pos1, pos3 - pos2, new_name,
regions.size(), Region::Flag(current->flags()|Region::Automatic|Region::LeftOfSplit|Region::RightOfSplit));
add_region_internal (region, start, true);
new_regions.push_back (region);
@@ -718,7 +716,7 @@ Playlist::partition_internal (jack_nframes_t start, jack_nframes_t end, bool cut
/* "end" ====== */
_session.region_name (new_name, current->name(), false);
- region = createRegion (*current, pos3 - pos1, pos4 - pos3, new_name,
+ region = RegionFactory::create (current, pos3 - pos1, pos4 - pos3, new_name,
regions.size(), Region::Flag(current->flags()|Region::Automatic|Region::RightOfSplit));
add_region_internal (region, end, true);
@@ -748,7 +746,7 @@ Playlist::partition_internal (jack_nframes_t start, jack_nframes_t end, bool cut
/* end +++++ */
_session.region_name (new_name, current->name(), false);
- region = createRegion (*current, pos2 - pos1, pos4 - pos2, new_name, (layer_t) regions.size(),
+ region = RegionFactory::create (current, pos2 - pos1, pos4 - pos2, new_name, (layer_t) regions.size(),
Region::Flag(current->flags()|Region::Automatic|Region::LeftOfSplit));
add_region_internal (region, start, true);
new_regions.push_back (region);
@@ -782,7 +780,7 @@ Playlist::partition_internal (jack_nframes_t start, jack_nframes_t end, bool cut
/* front **** */
_session.region_name (new_name, current->name(), false);
- region = createRegion (*current, 0, pos3 - pos1, new_name,
+ region = RegionFactory::create (current, 0, pos3 - pos1, new_name,
regions.size(), Region::Flag(current->flags()|Region::Automatic|Region::RightOfSplit));
add_region_internal (region, pos1, true);
new_regions.push_back (region);
@@ -822,7 +820,7 @@ Playlist::partition_internal (jack_nframes_t start, jack_nframes_t end, bool cut
in_partition = false;
for (RegionList::iterator i = new_regions.begin(); i != new_regions.end(); ++i) {
- check_dependents (**i, false);
+ check_dependents (*i, false);
}
}
@@ -943,7 +941,7 @@ Playlist::paste (Playlist& other, jack_nframes_t position, float times)
while (itimes--) {
for (RegionList::iterator i = other.regions.begin(); i != other.regions.end(); ++i) {
- Region *copy_of_region = createRegion (**i);
+ boost::shared_ptr<Region> copy_of_region = RegionFactory::create (*i);
/* put these new regions on top of all existing ones, but preserve
the ordering they had in the original playlist.
@@ -973,7 +971,7 @@ Playlist::paste (Playlist& other, jack_nframes_t position, float times)
void
-Playlist::duplicate (Region& region, jack_nframes_t position, float times)
+Playlist::duplicate (boost::shared_ptr<Region> region, jack_nframes_t position, float times)
{
times = fabs (times);
@@ -982,16 +980,16 @@ Playlist::duplicate (Region& region, jack_nframes_t position, float times)
jack_nframes_t pos = position;
while (itimes--) {
- Region *copy = createRegion (region);
+ boost::shared_ptr<Region> copy = RegionFactory::create (region);
add_region_internal (copy, pos, true);
- pos += region.length();
+ pos += region->length();
}
if (floor (times) != times) {
- jack_nframes_t length = (jack_nframes_t) floor (region.length() * (times - floor (times)));
+ jack_nframes_t length = (jack_nframes_t) floor (region->length() * (times - floor (times)));
string name;
- _session.region_name (name, region.name(), false);
- Region *sub = createRegion (region, 0, length, name, region.layer(), region.flags());
+ _session.region_name (name, region->name(), false);
+ boost::shared_ptr<Region> sub = RegionFactory::create (region, 0, length, name, region->layer(), region->flags());
add_region_internal (sub, pos, true);
}
@@ -999,40 +997,40 @@ Playlist::duplicate (Region& region, jack_nframes_t position, float times)
}
void
-Playlist::split_region (Region& region, jack_nframes_t playlist_position)
+Playlist::split_region (boost::shared_ptr<Region> region, jack_nframes_t playlist_position)
{
RegionLock rl (this);
- if (!region.covers (playlist_position)) {
+ if (!region->covers (playlist_position)) {
return;
}
- if (region.position() == playlist_position ||
- region.last_frame() == playlist_position) {
+ if (region->position() == playlist_position ||
+ region->last_frame() == playlist_position) {
return;
}
- Region *left;
- Region *right;
+ boost::shared_ptr<Region> left;
+ boost::shared_ptr<Region> right;
jack_nframes_t before;
jack_nframes_t after;
string before_name;
string after_name;
- before = playlist_position - region.position();
- after = region.length() - before;
+ before = playlist_position - region->position();
+ after = region->length() - before;
- _session.region_name (before_name, region.name(), false);
- left = createRegion (region, 0, before, before_name, region.layer(), Region::Flag (region.flags()|Region::LeftOfSplit));
+ _session.region_name (before_name, region->name(), false);
+ left = RegionFactory::create (region, 0, before, before_name, region->layer(), Region::Flag (region->flags()|Region::LeftOfSplit));
- _session.region_name (after_name, region.name(), false);
- right = createRegion (region, before, after, after_name, region.layer(), Region::Flag (region.flags()|Region::RightOfSplit));
+ _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 (right, region.position() + before);
+ add_region_internal (left, region->position(), true);
+ add_region_internal (right, region->position() + before);
- uint64_t orig_layer_op = region.last_layer_op();
+ uint64_t orig_layer_op = region->last_layer_op();
for (RegionList::iterator i = regions.begin(); i != regions.end(); ++i) {
if ((*i)->last_layer_op() > orig_layer_op) {
(*i)->set_last_layer_op( (*i)->last_layer_op() + 1 );
@@ -1044,9 +1042,9 @@ Playlist::split_region (Region& region, jack_nframes_t playlist_position)
layer_op_counter++;
- finalize_split_region (&region, left, right);
+ finalize_split_region (region, left, right);
- if (remove_region_internal (&region, true)) {
+ if (remove_region_internal (region, true)) {
return;
}
@@ -1110,7 +1108,7 @@ Playlist::core_splice ()
}
void
-Playlist::region_bounds_changed (Change what_changed, Region *region)
+Playlist::region_bounds_changed (Change what_changed, boost::shared_ptr<Region> region)
{
if (in_set_state || _splicing || _nudging) {
return;
@@ -1134,8 +1132,7 @@ Playlist::region_bounds_changed (Change what_changed, Region *region)
}
regions.erase (i);
- regions.insert (upper_bound (regions.begin(), regions.end(), region, cmp),
- region);
+ regions.insert (upper_bound (regions.begin(), regions.end(), region, cmp), region);
}
@@ -1146,11 +1143,11 @@ Playlist::region_bounds_changed (Change what_changed, Region *region)
} else {
if (_session.get_layer_model() == Session::MoveAddHigher) {
/* it moved or changed length, so change the timestamp */
- timestamp_layer_op (*region);
+ timestamp_layer_op (region);
}
possibly_splice ();
- check_dependents (*region, false);
+ check_dependents (region, false);
notify_length_changed ();
relayer ();
}
@@ -1158,7 +1155,7 @@ Playlist::region_bounds_changed (Change what_changed, Region *region)
}
void
-Playlist::region_changed_proxy (Change what_changed, Region* region)
+Playlist::region_changed_proxy (Change what_changed, boost::shared_ptr<Region> region)
{
/* this makes a virtual call to the right kind of playlist ... */
@@ -1166,7 +1163,7 @@ Playlist::region_changed_proxy (Change what_changed, Region* region)
}
bool
-Playlist::region_changed (Change what_changed, Region* region)
+Playlist::region_changed (Change what_changed, boost::shared_ptr<Region> region)
{
Change our_interests = Change (Region::MuteChanged|Region::LayerChanged|Region::OpacityChanged);
bool save = false;
@@ -1183,7 +1180,7 @@ Playlist::region_changed (Change what_changed, Region* region)
if ((what_changed & Region::MuteChanged) &&
!(what_changed & Change (ARDOUR::PositionChanged|ARDOUR::LengthChanged))) {
- check_dependents (*region, false);
+ check_dependents (region, false);
}
if (what_changed & our_interests) {
@@ -1195,7 +1192,7 @@ Playlist::region_changed (Change what_changed, Region* region)
}
void
-Playlist::clear (bool with_delete, bool with_save)
+Playlist::clear (bool with_save)
{
RegionList::iterator i;
RegionList tmp;
@@ -1208,9 +1205,6 @@ Playlist::clear (bool with_delete, bool with_save)
for (i = tmp.begin(); i != tmp.end(); ++i) {
notify_region_removed (*i);
- if (with_delete) {
- delete *i;
- }
}
if (with_save) {
@@ -1230,14 +1224,14 @@ Playlist::regions_at (jack_nframes_t frame)
return find_regions_at (frame);
}
-Region *
+boost::shared_ptr<Region>
Playlist::top_region_at (jack_nframes_t frame)
{
RegionLock rlock (this);
RegionList *rlist = find_regions_at (frame);
- Region *region = 0;
-
+ boost::shared_ptr<Region> region;
+
if (rlist->size()) {
RegionSortByLayer cmp;
rlist->sort (cmp);
@@ -1278,18 +1272,17 @@ Playlist::regions_touched (jack_nframes_t start, jack_nframes_t end)
}
-Region*
-
+boost::shared_ptr<Region>
Playlist::find_next_region (jack_nframes_t frame, RegionPoint point, int dir)
{
RegionLock rlock (this);
- Region* ret = 0;
+ boost::shared_ptr<Region> ret;
jack_nframes_t closest = max_frames;
for (RegionList::iterator i = regions.begin(); i != regions.end(); ++i) {
jack_nframes_t distance;
- Region* r = (*i);
+ boost::shared_ptr<Region> r = (*i);
jack_nframes_t pos = 0;
switch (point) {
@@ -1354,10 +1347,10 @@ Playlist::set_state (const XMLNode& node)
XMLPropertyList plist;
XMLPropertyConstIterator piter;
XMLProperty *prop;
- Region *region;
+ boost::shared_ptr<Region> region;
string region_name;
- clear (false, false);
+ clear (false);
if (node.name() != "Playlist") {
in_set_state = false;
@@ -1387,12 +1380,12 @@ Playlist::set_state (const XMLNode& node)
if (child->name() == "Region") {
- if ((region = createRegion (_session, *child, true)) == 0) {
+ if ((region = RegionFactory::create (_session, *child, true)) == 0) {
error << _("Playlist: cannot create region from state file") << endmsg;
continue;
}
- add_region (*region, region->position(), 1.0, false);
+ add_region (region, region->position(), 1.0, false);
// So that layer_op ordering doesn't get screwed up
region->set_last_layer_op( region->layer());
@@ -1406,7 +1399,7 @@ Playlist::set_state (const XMLNode& node)
*/
for (RegionList::iterator r = regions.begin(); r != regions.end(); ++r) {
- check_dependents (**r, false);
+ check_dependents (*r, false);
}
in_set_state = false;
@@ -1589,10 +1582,10 @@ Playlist::relayer ()
/* XXX these layer functions are all deprecated */
void
-Playlist::raise_region (Region& region)
+Playlist::raise_region (boost::shared_ptr<Region> region)
{
uint32_t rsz = regions.size();
- layer_t target = region.layer() + 1U;
+ layer_t target = region->layer() + 1U;
if (target >= rsz) {
/* its already at the effective top */
@@ -1603,20 +1596,20 @@ Playlist::raise_region (Region& region)
}
void
-Playlist::lower_region (Region& region)
+Playlist::lower_region (boost::shared_ptr<Region> region)
{
- if (region.layer() == 0) {
+ if (region->layer() == 0) {
/* its already at the bottom */
return;
}
- layer_t target = region.layer() - 1U;
+ layer_t target = region->layer() - 1U;
move_region_to_layer (target, region, -1);
}
void
-Playlist::raise_region_to_top (Region& region)
+Playlist::raise_region_to_top (boost::shared_ptr<Region> region)
{
/* does nothing useful if layering mode is later=higher */
if ((_session.get_layer_model() == Session::MoveAddHigher) ||
@@ -1627,21 +1620,21 @@ Playlist::raise_region_to_top (Region& region)
}
void
-Playlist::lower_region_to_bottom (Region& region)
+Playlist::lower_region_to_bottom (boost::shared_ptr<Region> region)
{
/* does nothing useful if layering mode is later=higher */
if ((_session.get_layer_model() == Session::MoveAddHigher) ||
(_session.get_layer_model() == Session::AddHigher)) {
- region.set_last_layer_op (0);
+ region->set_last_layer_op (0);
relayer ();
}
}
int
-Playlist::move_region_to_layer (layer_t target_layer, Region& region, int dir)
+Playlist::move_region_to_layer (layer_t target_layer, boost::shared_ptr<Region> region, int dir)
{
RegionList::iterator i;
- typedef pair<Region*,layer_t> LayerInfo;
+ typedef pair<boost::shared_ptr<Region>,layer_t> LayerInfo;
list<LayerInfo> layerinfo;
layer_t dest;
@@ -1650,7 +1643,7 @@ Playlist::move_region_to_layer (layer_t target_layer, Region& region, int dir)
for (i = regions.begin(); i != regions.end(); ++i) {
- if (&region == *i) {
+ if (region == *i) {
continue;
}
@@ -1660,7 +1653,7 @@ Playlist::move_region_to_layer (layer_t target_layer, Region& region, int dir)
down 1
*/
- if ((*i)->layer() > region.layer() && (*i)->layer() <= target_layer) {
+ if ((*i)->layer() > region->layer() && (*i)->layer() <= target_layer) {
dest = (*i)->layer() - 1;
} else {
/* not affected */
@@ -1672,7 +1665,7 @@ Playlist::move_region_to_layer (layer_t target_layer, Region& region, int dir)
up 1
*/
- if ((*i)->layer() < region.layer() && (*i)->layer() >= target_layer) {
+ if ((*i)->layer() < region->layer() && (*i)->layer() >= target_layer) {
dest = (*i)->layer() + 1;
} else {
/* not affected */
@@ -1695,12 +1688,12 @@ Playlist::move_region_to_layer (layer_t target_layer, Region& region, int dir)
x->first->set_layer (x->second);
}
- region.set_layer (target_layer);
+ region->set_layer (target_layer);
/* now check all dependents */
for (list<LayerInfo>::iterator x = layerinfo.begin(); x != layerinfo.end(); ++x) {
- check_dependents (*(x->first), false);
+ check_dependents (x->first, false);
}
check_dependents (region, false);
@@ -1755,19 +1748,20 @@ Playlist::nudge_after (jack_nframes_t start, jack_nframes_t distance, bool forwa
}
-Region*
+boost::shared_ptr<Region>
Playlist::find_region (const ID& id) const
{
RegionLock rlock (const_cast<Playlist*> (this));
RegionList::const_iterator i;
-
+ boost::shared_ptr<Region> ret;
+
for (i = regions.begin(); i != regions.end(); ++i) {
if ((*i)->id() == id) {
- return (*i);
+ ret = *i;
}
}
- return 0;
+ return ret;
}
void
@@ -1781,7 +1775,7 @@ Playlist::save_state (std::string why)
void
Playlist::dump () const
{
- Region *r;
+ boost::shared_ptr<Region> r;
cerr << "Playlist \"" << _name << "\" " << endl
<< regions.size() << " regions "
@@ -1806,11 +1800,11 @@ Playlist::set_frozen (bool yn)
}
void
-Playlist::timestamp_layer_op (Region& region)
+Playlist::timestamp_layer_op (boost::shared_ptr<Region> region)
{
// struct timeval tv;
// gettimeofday (&tv, 0);
- region.set_last_layer_op (++layer_op_counter);
+ region->set_last_layer_op (++layer_op_counter);
}
void
diff --git a/libs/ardour/playlist_factory.cc b/libs/ardour/playlist_factory.cc
index 7c7060dae8..05d9c76f7a 100644
--- a/libs/ardour/playlist_factory.cc
+++ b/libs/ardour/playlist_factory.cc
@@ -20,60 +20,14 @@
#include <pbd/error.h>
-#include <ardour/session.h>
-
#include <ardour/playlist.h>
#include <ardour/audioplaylist.h>
-#include <ardour/region_factory.h>
-#include <ardour/region.h>
-#include <ardour/audioregion.h>
-
#include "i18n.h"
using namespace ARDOUR;
using namespace PBD;
-Region*
-ARDOUR::createRegion (const Region& region, jack_nframes_t start,
- jack_nframes_t length, std::string name,
- layer_t layer, Region::Flag flags)
-{
- const AudioRegion* ar;
-
- if ((ar = dynamic_cast<const AudioRegion*>(&region)) != 0) {
- AudioRegion* ret;
- ret = new AudioRegion (*ar, start, length, name, layer, flags);
- return ret;
- } else {
- fatal << _("programming error: Playlist::createRegion called with unknown Region type")
- << endmsg;
- /*NOTREACHED*/
- return 0;
- }
-}
-
-Region*
-ARDOUR::createRegion (const Region& region)
-{
- const AudioRegion* ar;
-
- if ((ar = dynamic_cast<const AudioRegion*>(&region)) != 0) {
- return new AudioRegion (*ar);
- } else {
- fatal << _("programming error: Playlist::createRegion called with unknown Region type")
- << endmsg;
- /*NOTREACHED*/
- return 0;
- }
-}
-
-Region*
-ARDOUR::createRegion (Session& session, XMLNode& node, bool yn)
-{
- return session.XMLRegionFactory (node, yn);
-}
-
Playlist*
Playlist::copyPlaylist (const Playlist& playlist, jack_nframes_t start, jack_nframes_t length,
string name, bool result_is_hidden)
diff --git a/libs/ardour/region.cc b/libs/ardour/region.cc
index 3481ee3eea..48431087ae 100644
--- a/libs/ardour/region.cc
+++ b/libs/ardour/region.cc
@@ -48,10 +48,8 @@ Change Region::LockChanged = ARDOUR::new_change ();
Change Region::LayerChanged = ARDOUR::new_change ();
Change Region::HiddenChanged = ARDOUR::new_change ();
-sigc::signal<void,Region *> Region::CheckNewRegion;
-
/** Basic Region constructor (single source) */
-Region::Region (Source& src, jack_nframes_t start, jack_nframes_t length, const string& name, DataType type, layer_t layer, Region::Flag flags)
+Region::Region (boost::shared_ptr<Source> src, jack_nframes_t start, jack_nframes_t length, const string& name, DataType type, layer_t layer, Region::Flag flags)
: _name(name)
, _type(type)
, _flags(flags)
@@ -69,9 +67,9 @@ Region::Region (Source& src, jack_nframes_t start, jack_nframes_t length, const
{
_current_state_id = 0;
- _sources.push_back (&src);
- _master_sources.push_back (&src);
- src.GoingAway.connect (mem_fun (*this, &Region::source_deleted));
+ _sources.push_back (src);
+ _master_sources.push_back (src);
+ src->GoingAway.connect (bind (mem_fun (*this, &Region::source_deleted), src));
assert(_sources.size() > 0);
}
@@ -95,18 +93,18 @@ Region::Region (SourceList& srcs, jack_nframes_t start, jack_nframes_t length, c
{
_current_state_id = 0;
- set<Source*> unique_srcs;
+ set<boost::shared_ptr<Source> > unique_srcs;
for (SourceList::iterator i=srcs.begin(); i != srcs.end(); ++i) {
_sources.push_back (*i);
- (*i)->GoingAway.connect (mem_fun (*this, &Region::source_deleted));
+ (*i)->GoingAway.connect (bind (mem_fun (*this, &Region::source_deleted), (*i)));
unique_srcs.insert (*i);
}
for (SourceList::iterator i = srcs.begin(); i != srcs.end(); ++i) {
_master_sources.push_back (*i);
if (unique_srcs.find (*i) == unique_srcs.end()) {
- (*i)->GoingAway.connect (mem_fun (*this, &Region::source_deleted));
+ (*i)->GoingAway.connect (bind (mem_fun (*this, &Region::source_deleted), (*i)));
}
}
@@ -114,11 +112,11 @@ Region::Region (SourceList& srcs, jack_nframes_t start, jack_nframes_t length, c
}
/** Create a new Region from part of an existing one */
-Region::Region (const Region& other, jack_nframes_t offset, jack_nframes_t length, const string& name, layer_t layer, Flag flags)
+Region::Region (boost::shared_ptr<const Region> other, jack_nframes_t offset, jack_nframes_t length, const string& name, layer_t layer, Flag flags)
: _name(name)
- , _type(other.data_type())
+ , _type(other->data_type())
, _flags(Flag(flags & ~(Locked|WholeFile|Hidden)))
- , _start(other._start + offset)
+ , _start(other->_start + offset)
, _length(length)
, _position(0)
, _sync_position(_start)
@@ -132,20 +130,24 @@ Region::Region (const Region& other, jack_nframes_t offset, jack_nframes_t lengt
{
_current_state_id = 0;
- if (other._sync_position < offset)
- _sync_position = other._sync_position;
+ if (other->_sync_position < offset)
+ _sync_position = other->_sync_position;
- set<Source*> unique_srcs;
+ set<boost::shared_ptr<Source> > unique_srcs;
- for (SourceList::const_iterator i= other._sources.begin(); i != other._sources.end(); ++i) {
+ for (SourceList::const_iterator i= other->_sources.begin(); i != other->_sources.end(); ++i) {
_sources.push_back (*i);
- (*i)->GoingAway.connect (mem_fun (*this, &Region::source_deleted));
+ (*i)->GoingAway.connect (bind (mem_fun (*this, &Region::source_deleted), (*i)));
unique_srcs.insert (*i);
}
+
+ if (other->_sync_position < offset) {
+ _sync_position = other->_sync_position;
+ }
- for (SourceList::const_iterator i = other._master_sources.begin(); i != other._master_sources.end(); ++i) {
+ for (SourceList::const_iterator i = other->_master_sources.begin(); i != other->_master_sources.end(); ++i) {
if (unique_srcs.find (*i) == unique_srcs.end()) {
- (*i)->GoingAway.connect (mem_fun (*this, &Region::source_deleted));
+ (*i)->GoingAway.connect (bind (mem_fun (*this, &Region::source_deleted), (*i)));
}
_master_sources.push_back (*i);
}
@@ -154,44 +156,44 @@ Region::Region (const Region& other, jack_nframes_t offset, jack_nframes_t lengt
}
/** Pure copy constructor */
-Region::Region (const Region &other)
- : _name(other._name)
- , _type(other.data_type())
- , _flags(Flag(other._flags & ~Locked))
- , _start(other._start)
- , _length(other._length)
- , _position(other._position)
- , _sync_position(other._sync_position)
- , _layer(other._layer)
+Region::Region (boost::shared_ptr<const Region> other)
+ : _name(other->_name)
+ , _type(other->data_type())
+ , _flags(Flag(other->_flags & ~Locked))
+ , _start(other->_start)
+ , _length(other->_length)
+ , _position(other->_position)
+ , _sync_position(other->_sync_position)
+ , _layer(other->_layer)
, _first_edit(EditChangesID)
, _frozen(0)
, _read_data_count(0)
, _pending_changed(Change(0))
- , _last_layer_op(other._last_layer_op)
+ , _last_layer_op(other->_last_layer_op)
, _playlist(0)
{
_current_state_id = 0;
- other._first_edit = EditChangesName;
+ other->_first_edit = EditChangesName;
- if (other._extra_xml) {
- _extra_xml = new XMLNode (*other._extra_xml);
+ if (other->_extra_xml) {
+ _extra_xml = new XMLNode (*other->_extra_xml);
} else {
_extra_xml = 0;
}
- set<Source*> unique_srcs;
+ set<boost::shared_ptr<Source> > unique_srcs;
- for (SourceList::const_iterator i = other._sources.begin(); i != other._sources.end(); ++i) {
+ for (SourceList::const_iterator i = other->_sources.begin(); i != other->_sources.end(); ++i) {
_sources.push_back (*i);
- (*i)->GoingAway.connect (mem_fun (*this, &Region::source_deleted));
+ (*i)->GoingAway.connect (bind (mem_fun (*this, &Region::source_deleted), (*i)));
unique_srcs.insert (*i);
}
- for (SourceList::const_iterator i = other._master_sources.begin(); i != other._master_sources.end(); ++i) {
+ for (SourceList::const_iterator i = other->_master_sources.begin(); i != other->_master_sources.end(); ++i) {
_master_sources.push_back (*i);
if (unique_srcs.find (*i) == unique_srcs.end()) {
- (*i)->GoingAway.connect (mem_fun (*this, &Region::source_deleted));
+ (*i)->GoingAway.connect (bind (mem_fun (*this, &Region::source_deleted), (*i)));
}
}
@@ -215,23 +217,23 @@ Region::Region (SourceList& srcs, const XMLNode& node)
, _playlist(0)
{
- set<Source*> unique_srcs;
+ _current_state_id = 0;
+
+ set<boost::shared_ptr<Source> > unique_srcs;
for (SourceList::iterator i=srcs.begin(); i != srcs.end(); ++i) {
_sources.push_back (*i);
- (*i)->GoingAway.connect (mem_fun (*this, &Region::source_deleted));
+ (*i)->GoingAway.connect (bind (mem_fun (*this, &Region::source_deleted), (*i)));
unique_srcs.insert (*i);
}
for (SourceList::iterator i = srcs.begin(); i != srcs.end(); ++i) {
_master_sources.push_back (*i);
if (unique_srcs.find (*i) == unique_srcs.end()) {
- (*i)->GoingAway.connect (mem_fun (*this, &Region::source_deleted));
+ (*i)->GoingAway.connect (bind (mem_fun (*this, &Region::source_deleted), (*i)));
}
}
- _current_state_id = 0;
-
if (set_state (node)) {
throw failed_constructor();
}
@@ -240,7 +242,7 @@ Region::Region (SourceList& srcs, const XMLNode& node)
assert(_sources.size() > 0);
}
-Region::Region (Source& src, const XMLNode& node)
+Region::Region (boost::shared_ptr<Source> src, const XMLNode& node)
: _name(X_("error: XML did not reset this"))
, _type(DataType::NIL)
, _flags(Flag(0))
@@ -256,7 +258,7 @@ Region::Region (Source& src, const XMLNode& node)
, _last_layer_op(0)
, _playlist(0)
{
- _sources.push_back (&src);
+ _sources.push_back (src);
_current_state_id = 0;
@@ -270,6 +272,9 @@ Region::Region (Source& src, const XMLNode& node)
Region::~Region ()
{
+ notify_callbacks ();
+
+ /* derived classes must emit GoingAway */
}
void
@@ -395,7 +400,7 @@ Region::first_edit ()
_first_edit = EditChangesNothing;
send_change (NameChanged);
- CheckNewRegion (this);
+ /// XXX CheckNewRegion (boost::shared_ptr<Region>(this));
}
}
@@ -406,7 +411,7 @@ Region::move_to_natural_position (void *src)
return;
}
- Region* whole_file_region = get_parent();
+ boost::shared_ptr<Region> whole_file_region = get_parent();
if (whole_file_region) {
set_position (whole_file_region->position() + _start, src);
@@ -464,7 +469,7 @@ Region::set_position_on_top (jack_nframes_t pos, void *src)
}
}
- _playlist->raise_region_to_top (*this);
+ _playlist->raise_region_to_top (boost::shared_ptr<Region>(this));
/* do this even if the position is the same. this helps out
a GUI that has moved its representation already.
@@ -906,7 +911,7 @@ Region::raise ()
return;
}
- _playlist->raise_region (*this);
+ _playlist->raise_region (boost::shared_ptr<Region>(this));
}
void
@@ -916,7 +921,7 @@ Region::lower ()
return;
}
- _playlist->lower_region (*this);
+ _playlist->lower_region (boost::shared_ptr<Region>(this));
}
void
@@ -927,7 +932,7 @@ Region::raise_to_top ()
return;
}
- _playlist->raise_region_to_top (*this);
+ _playlist->raise_region_to_top (boost::shared_ptr<Region>(this));
}
void
@@ -937,7 +942,7 @@ Region::lower_to_bottom ()
return;
}
- _playlist->lower_region_to_bottom (*this);
+ _playlist->lower_region_to_bottom (boost::shared_ptr<Region>(this));
}
void
@@ -1121,74 +1126,38 @@ Region::set_last_layer_op (uint64_t when)
}
bool
-Region::overlap_equivalent (const Region& other) const
+Region::overlap_equivalent (boost::shared_ptr<const Region> other) const
{
- return coverage (other.first_frame(), other.last_frame()) != OverlapNone;
+ return coverage (other->first_frame(), other->last_frame()) != OverlapNone;
}
bool
-Region::equivalent (const Region& other) const
+Region::equivalent (boost::shared_ptr<const Region> other) const
{
- return _start == other._start &&
- _position == other._position &&
- _length == other._length;
+ return _start == other->_start &&
+ _position == other->_position &&
+ _length == other->_length;
}
bool
-Region::size_equivalent (const Region& other) const
+Region::size_equivalent (boost::shared_ptr<const Region> other) const
{
- return _start == other._start &&
- _length == other._length;
+ return _start == other->_start &&
+ _length == other->_length;
}
bool
-Region::region_list_equivalent (const Region& other) const
+Region::region_list_equivalent (boost::shared_ptr<const Region> other) const
{
- return size_equivalent (other) && source_equivalent (other) && _name == other._name;
+ return size_equivalent (other) && source_equivalent (other) && _name == other->_name;
}
void
-Region::source_deleted (Source* ignored)
+Region::source_deleted (boost::shared_ptr<Source>)
{
delete this;
}
-void
-Region::lock_sources ()
-{
- SourceList::iterator i;
- set<Source*> unique_srcs;
-
- for (i = _sources.begin(); i != _sources.end(); ++i) {
- unique_srcs.insert (*i);
- (*i)->use ();
- }
-
- for (i = _master_sources.begin(); i != _master_sources.end(); ++i) {
- if (unique_srcs.find (*i) == unique_srcs.end()) {
- (*i)->use ();
- }
- }
-}
-
-void
-Region::unlock_sources ()
-{
- SourceList::iterator i;
- set<Source*> unique_srcs;
-
- for (i = _sources.begin(); i != _sources.end(); ++i) {
- unique_srcs.insert (*i);
- (*i)->release ();
- }
-
- for (i = _master_sources.begin(); i != _master_sources.end(); ++i) {
- if (unique_srcs.find (*i) == unique_srcs.end()) {
- (*i)->release ();
- }
- }
-}
-
vector<string>
Region::master_source_names ()
{
@@ -1203,18 +1172,21 @@ Region::master_source_names ()
}
bool
-Region::source_equivalent (const Region& other) const
+Region::source_equivalent (boost::shared_ptr<const Region> other) const
{
+ if (!other)
+ return false;
+
SourceList::const_iterator i;
SourceList::const_iterator io;
- for (i = _sources.begin(), io = other._sources.begin(); i != _sources.end() && io != other._sources.end(); ++i, ++io) {
+ for (i = _sources.begin(), io = other->_sources.begin(); i != _sources.end() && io != other->_sources.end(); ++i, ++io) {
if ((*i)->id() != (*io)->id()) {
return false;
}
}
- for (i = _master_sources.begin(), io = other._master_sources.begin(); i != _master_sources.end() && io != other._master_sources.end(); ++i, ++io) {
+ for (i = _master_sources.begin(), io = other->_master_sources.begin(); i != _master_sources.end() && io != other->_master_sources.end(); ++i, ++io) {
if ((*i)->id() != (*io)->id()) {
return false;
}
@@ -1266,10 +1238,10 @@ Region::verify_start_mutable (jack_nframes_t& new_start)
return true;
}
-Region*
+boost::shared_ptr<Region>
Region::get_parent()
{
- Region* r = 0;
+ boost::shared_ptr<Region> r;
if (_playlist) {
r = _playlist->session().find_whole_file_parent (*this);
diff --git a/libs/ardour/region_factory.cc b/libs/ardour/region_factory.cc
new file mode 100644
index 0000000000..492a25a08f
--- /dev/null
+++ b/libs/ardour/region_factory.cc
@@ -0,0 +1,182 @@
+/*
+ Copyright (C) 2000-2006 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.
+
+ $Id: playlist_factory.cc 629 2006-06-21 23:01:03Z paul $
+*/
+
+#include <pbd/error.h>
+
+#include <ardour/session.h>
+
+#include <ardour/region_factory.h>
+#include <ardour/region.h>
+#include <ardour/audioregion.h>
+#include <ardour/audiosource.h>
+#include <ardour/midi_source.h>
+#include <ardour/midi_region.h>
+
+#include "i18n.h"
+
+using namespace ARDOUR;
+using namespace PBD;
+
+sigc::signal<void,boost::shared_ptr<Region> > RegionFactory::CheckNewRegion;
+
+boost::shared_ptr<Region>
+RegionFactory::create (boost::shared_ptr<Region> region, jack_nframes_t start,
+ jack_nframes_t length, std::string name,
+ layer_t layer, Region::Flag flags, bool announce)
+{
+ boost::shared_ptr<const AudioRegion> other_a;
+ boost::shared_ptr<const MidiRegion> other_m;
+
+ if ((other_a = boost::dynamic_pointer_cast<AudioRegion>(region)) != 0) {
+ AudioRegion* ar = new AudioRegion (other_a, start, length, name, layer, flags);
+ boost::shared_ptr<AudioRegion> arp (ar);
+ boost::shared_ptr<Region> ret (boost::static_pointer_cast<Region> (arp));
+ if (announce) {
+ CheckNewRegion (ret);
+ }
+ return ret;
+ } else if ((other_m = boost::dynamic_pointer_cast<MidiRegion>(region)) != 0) {
+ MidiRegion* ar = new MidiRegion (other_m, start, length, name, layer, flags);
+ boost::shared_ptr<MidiRegion> arp (ar);
+ boost::shared_ptr<Region> ret (boost::static_pointer_cast<Region> (arp));
+ if (announce) {
+ CheckNewRegion (ret);
+ }
+ return ret;
+ } else {
+ fatal << _("programming error: RegionFactory::create() called with unknown Region type")
+ << endmsg;
+ /*NOTREACHED*/
+ return boost::shared_ptr<Region>();
+ }
+}
+
+boost::shared_ptr<Region>
+RegionFactory::create (boost::shared_ptr<Region> region)
+{
+ boost::shared_ptr<AudioRegion> ar;
+ boost::shared_ptr<MidiRegion> mr;
+
+ if ((ar = boost::dynamic_pointer_cast<AudioRegion>(region)) != 0) {
+ boost::shared_ptr<Region> ret (new AudioRegion (ar));
+ /* pure copy constructor - no CheckNewRegion emitted */
+ return ret;
+ } else if ((mr = boost::dynamic_pointer_cast<MidiRegion>(region)) != 0) {
+ boost::shared_ptr<Region> ret (new MidiRegion (mr));
+ /* pure copy constructor - no CheckNewRegion emitted */
+ return ret;
+ } else {
+ fatal << _("programming error: RegionFactory::create() called with unknown Region type")
+ << endmsg;
+ /*NOTREACHED*/
+ return boost::shared_ptr<Region>();
+ }
+}
+
+boost::shared_ptr<Region>
+RegionFactory::create (boost::shared_ptr<AudioRegion> region, jack_nframes_t start,
+ jack_nframes_t length, std::string name,
+ layer_t layer, Region::Flag flags, bool announce)
+{
+ return create (boost::static_pointer_cast<Region> (region), start, length, name, layer, flags, announce);
+}
+
+boost::shared_ptr<Region>
+RegionFactory::create (Session& session, XMLNode& node, bool yn)
+{
+ boost::shared_ptr<Region> r = session.XMLRegionFactory (node, yn);
+ CheckNewRegion (r);
+ return r;
+}
+
+boost::shared_ptr<Region>
+RegionFactory::create (SourceList& srcs, jack_nframes_t start, jack_nframes_t length, const string& name, layer_t layer, Region::Flag flags, bool announce)
+{
+ if (srcs.empty()) {
+ return boost::shared_ptr<Region>();
+ }
+
+ if (srcs[0]->type() == DataType::AUDIO) {
+
+ AudioRegion* ar = new AudioRegion (srcs, start, length, name, layer, flags);
+ boost::shared_ptr<AudioRegion> arp (ar);
+ boost::shared_ptr<Region> ret (boost::static_pointer_cast<Region> (arp));
+ if (announce) {
+ CheckNewRegion (ret);
+ }
+ return ret;
+
+ } else if (srcs[0]->type() == DataType::MIDI) {
+
+ MidiRegion* ar = new MidiRegion (srcs, start, length, name, layer, flags);
+ boost::shared_ptr<MidiRegion> mrp (ar);
+ boost::shared_ptr<Region> ret (boost::static_pointer_cast<Region> (mrp));
+ if (announce) {
+ CheckNewRegion (ret);
+ }
+ return ret;
+
+ }
+
+ return boost::shared_ptr<Region> ();
+}
+
+boost::shared_ptr<Region>
+RegionFactory::create (SourceList& srcs, const XMLNode& node)
+{
+ if (srcs.empty()) {
+ return boost::shared_ptr<Region>();
+ }
+
+ if (srcs[0]->type() == DataType::AUDIO) {
+ boost::shared_ptr<Region> ret (new AudioRegion (srcs, node));
+ CheckNewRegion (ret);
+ return ret;
+ } else if (srcs[0]->type() == DataType::MIDI) {
+ boost::shared_ptr<Region> ret (new MidiRegion (srcs, node));
+ CheckNewRegion (ret);
+ return ret;
+ }
+
+ return boost::shared_ptr<Region> ();
+}
+
+boost::shared_ptr<Region>
+RegionFactory::create (boost::shared_ptr<Source> src, jack_nframes_t start, jack_nframes_t length, const string& name, layer_t layer, Region::Flag flags, bool announce)
+{
+ boost::shared_ptr<AudioSource> as;
+ boost::shared_ptr<MidiSource> ms;
+
+ if ((as = boost::dynamic_pointer_cast<AudioSource>(src)) != 0) {
+ boost::shared_ptr<Region> ret (new AudioRegion (as, start, length, name, layer, flags));
+ if (announce) {
+ CheckNewRegion (ret);
+ }
+ return ret;
+ } else if ((ms = boost::dynamic_pointer_cast<MidiSource>(src)) != 0) {
+ boost::shared_ptr<Region> ret (new MidiRegion (ms, start, length, name, layer, flags));
+ if (announce) {
+ CheckNewRegion (ret);
+ }
+ return ret;
+ }
+
+ return boost::shared_ptr<Region>();
+}
diff --git a/libs/ardour/reverse.cc b/libs/ardour/reverse.cc
index b981ff0722..15f90fec45 100644
--- a/libs/ardour/reverse.cc
+++ b/libs/ardour/reverse.cc
@@ -43,10 +43,10 @@ Reverse::~Reverse ()
}
int
-Reverse::run (AudioRegion& region)
+Reverse::run (boost::shared_ptr<AudioRegion> region)
{
- AudioRegion::SourceList nsrcs;
- AudioRegion::SourceList::iterator si;
+ SourceList nsrcs;
+ SourceList::iterator si;
const jack_nframes_t blocksize = 256 * 1048;
Sample buf[blocksize];
jack_nframes_t fpos;
@@ -61,8 +61,8 @@ Reverse::run (AudioRegion& region)
goto out;
}
- fend = region.start() + region.length();
- fstart = region.start();
+ fend = region->start() + region->length();
+ fstart = region->start();
if (blocksize < fend) {
fpos =max(fstart, fend - blocksize);
@@ -70,7 +70,7 @@ Reverse::run (AudioRegion& region)
fpos = fstart;
}
- to_read = min (region.length(), blocksize);
+ to_read = min (region->length(), blocksize);
/* now read it backwards */
@@ -78,12 +78,11 @@ Reverse::run (AudioRegion& region)
uint32_t n;
- for (n = 0, si = nsrcs.begin(); n < region.n_channels(); ++n, ++si) {
- AudioSource* const asrc = dynamic_cast<AudioSource*>(*si);
+ for (n = 0, si = nsrcs.begin(); n < region->n_channels(); ++n, ++si) {
/* read it in */
- if (region.audio_source (n).read (buf, fpos, to_read) != to_read) {
+ if (region->audio_source (n)->read (buf, fpos, to_read) != to_read) {
goto out;
}
@@ -95,7 +94,9 @@ Reverse::run (AudioRegion& region)
/* write it out */
- if (asrc->write (buf, to_read) != to_read) {
+ boost::shared_ptr<AudioSource> asrc(boost::dynamic_pointer_cast<AudioSource>(*si));
+
+ if (asrc && asrc->write (buf, to_read) != to_read) {
goto out;
}
}
@@ -117,8 +118,8 @@ Reverse::run (AudioRegion& region)
if (ret) {
for (si = nsrcs.begin(); si != nsrcs.end(); ++si) {
- (*si)->mark_for_remove ();
- delete *si;
+ boost::shared_ptr<AudioSource> asrc(boost::dynamic_pointer_cast<AudioSource>(*si));
+ asrc->mark_for_remove ();
}
}
diff --git a/libs/ardour/send.cc b/libs/ardour/send.cc
index c67e0fcdbe..9161b0492d 100644
--- a/libs/ardour/send.cc
+++ b/libs/ardour/send.cc
@@ -64,7 +64,7 @@ Send::Send (const Send& other)
Send::~Send ()
{
- GoingAway (this);
+ GoingAway ();
}
XMLNode&
diff --git a/libs/ardour/session.cc b/libs/ardour/session.cc
index 7d5f838499..0a85c47cb9 100644
--- a/libs/ardour/session.cc
+++ b/libs/ardour/session.cc
@@ -71,6 +71,7 @@
#include <ardour/click.h>
#include <ardour/data_type.h>
#include <ardour/buffer_set.h>
+#include <ardour/source_factory.h>
#ifdef HAVE_LIBLO
#include <ardour/osc.h>
@@ -282,10 +283,12 @@ Session::Session (AudioEngine &eng,
first_stage_init (fullpath, snapshot_name);
if (create (new_session, mix_template, _engine.frame_rate() * 60 * 5)) {
+ cerr << "create failed\n";
throw failed_constructor ();
}
if (second_stage_init (new_session)) {
+ cerr << "2nd state failed\n";
throw failed_constructor ();
}
@@ -386,9 +389,23 @@ Session::~Session ()
_state_of_the_state = StateOfTheState (CannotSave|Deletion);
_engine.remove_session ();
+
+ GoingAway (); /* EMIT SIGNAL */
- going_away (); /* EMIT SIGNAL */
+ /* do this */
+
+ notify_callbacks ();
+
+ /* clear history so that no references to objects are held any more */
+
+ history.clear ();
+
+ /* clear state tree so that no references to objects are held any more */
+ if (state_tree) {
+ delete state_tree;
+ }
+
terminate_butler_thread ();
//terminate_midi_thread ();
@@ -439,16 +456,12 @@ Session::~Session ()
#ifdef TRACK_DESTRUCTION
cerr << "delete regions\n";
#endif /* TRACK_DESTRUCTION */
- for (RegionList::iterator i = regions.begin(); i != regions.end(); ) {
- RegionList::iterator tmp;
-
- tmp =i;
- ++tmp;
-
- delete i->second;
-
- i = tmp;
+
+ for (RegionList::iterator i = regions.begin(); i != regions.end(); ++i) {
+ i->second->drop_references ();
}
+
+ regions.clear ();
#ifdef TRACK_DESTRUCTION
cerr << "delete routes\n";
@@ -456,12 +469,8 @@ Session::~Session ()
{
RCUWriter<RouteList> writer (routes);
boost::shared_ptr<RouteList> r = writer.get_copy ();
- for (RouteList::iterator i = r->begin(); i != r->end(); ) {
- RouteList::iterator tmp;
- tmp = i;
- ++tmp;
+ for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
(*i)->drop_references ();
- i = tmp;
}
r->clear ();
/* writer goes out of scope and updates master */
@@ -475,15 +484,8 @@ Session::~Session ()
{
RCUWriter<DiskstreamList> dwriter (diskstreams);
boost::shared_ptr<DiskstreamList> dsl = dwriter.get_copy();
- for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ) {
- DiskstreamList::iterator tmp;
-
- tmp = i;
- ++tmp;
-
+ for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
(*i)->drop_references ();
-
- i = tmp;
}
dsl->clear ();
}
@@ -492,17 +494,19 @@ Session::~Session ()
#ifdef TRACK_DESTRUCTION
cerr << "delete audio sources\n";
#endif /* TRACK_DESTRUCTION */
- for (SourceList::iterator i = sources.begin(); i != sources.end(); ) {
- SourceList::iterator tmp;
+ for (SourceMap::iterator i = sources.begin(); i != sources.end(); ) {
+ SourceMap::iterator tmp;
tmp = i;
++tmp;
- delete i->second;
+ i->second->drop_references ();
i = tmp;
}
+ sources.clear ();
+
#ifdef TRACK_DESTRUCTION
cerr << "delete mix groups\n";
#endif /* TRACK_DESTRUCTION */
@@ -558,10 +562,6 @@ Session::~Session ()
if (mmc) {
delete mmc;
}
-
- if (state_tree) {
- delete state_tree;
- }
}
void
@@ -2712,8 +2712,9 @@ Session::region_name (string& result, string base, bool newlevel) const
}
void
-Session::add_region (Region* region)
+Session::add_region (boost::shared_ptr<Region> region)
{
+ boost::shared_ptr<Region> other;
bool added = false;
{
@@ -2723,7 +2724,9 @@ Session::add_region (Region* region)
for (x = regions.begin(); x != regions.end(); ++x) {
- if (region->region_list_equivalent (*x->second)) {
+ other = x->second;
+
+ if (region->region_list_equivalent (other)) {
break;
}
}
@@ -2737,6 +2740,7 @@ Session::add_region (Region* region)
pair<RegionList::iterator,bool> x = regions.insert (entry);
+
if (!x.second) {
return;
}
@@ -2748,19 +2752,19 @@ Session::add_region (Region* region)
/* mark dirty because something has changed even if we didn't
add the region to the region list.
- */
-
+ */
+
set_dirty();
-
+
if (added) {
- region->GoingAway.connect (mem_fun (*this, &Session::remove_region));
+ region->GoingAway.connect (sigc::bind (mem_fun (*this, &Session::remove_region), region));
region->StateChanged.connect (sigc::bind (mem_fun (*this, &Session::region_changed), region));
RegionAdded (region); /* EMIT SIGNAL */
}
}
void
-Session::region_changed (Change what_changed, Region* region)
+Session::region_changed (Change what_changed, boost::shared_ptr<Region> region)
{
if (what_changed & Region::HiddenChanged) {
/* relay hidden changes */
@@ -2769,17 +2773,17 @@ Session::region_changed (Change what_changed, Region* region)
}
void
-Session::region_renamed (Region* region)
+Session::region_renamed (boost::shared_ptr<Region> region)
{
add_region (region);
}
void
-Session::remove_region (Region* region)
+Session::remove_region (boost::shared_ptr<Region> region)
{
RegionList::iterator i;
bool removed = false;
-
+
{
Glib::Mutex::Lock lm (region_lock);
@@ -2787,25 +2791,25 @@ Session::remove_region (Region* region)
regions.erase (i);
removed = true;
}
-
}
/* mark dirty because something has changed even if we didn't
remove the region from the region list.
- */
+ */
set_dirty();
if (removed) {
- RegionRemoved(region); /* EMIT SIGNAL */
+ RegionRemoved(region); /* EMIT SIGNAL */
}
}
-Region*
+boost::shared_ptr<Region>
Session::find_whole_file_parent (Region& child)
{
RegionList::iterator i;
- Region* region;
+ boost::shared_ptr<Region> region;
+
Glib::Mutex::Lock lm (region_lock);
for (i = regions.begin(); i != regions.end(); ++i) {
@@ -2814,49 +2818,51 @@ Session::find_whole_file_parent (Region& child)
if (region->whole_file()) {
- if (child.source_equivalent (*region)) {
+ if (child.source_equivalent (region)) {
return region;
}
}
}
- return 0;
+ return boost::shared_ptr<AudioRegion> ((AudioRegion*) 0);
}
void
-Session::find_equivalent_playlist_regions (Region& region, vector<Region*>& result)
+Session::find_equivalent_playlist_regions (boost::shared_ptr<Region> region, vector<boost::shared_ptr<Region> >& result)
{
for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i)
(*i)->get_region_list_equivalent_regions (region, result);
}
int
-Session::destroy_region (Region* region)
+Session::destroy_region (boost::shared_ptr<Region> region)
{
- AudioRegion* aregion;
+ boost::shared_ptr<AudioRegion> aregion;
- if ((aregion = dynamic_cast<AudioRegion*> (region)) == 0) {
+ if ((aregion = boost::dynamic_pointer_cast<AudioRegion> (region)) == 0) {
return 0;
}
-
+
if (aregion->playlist()) {
aregion->playlist()->destroy_region (region);
}
- vector<Source*> srcs;
+ vector<boost::shared_ptr<Source> > srcs;
for (uint32_t n = 0; n < aregion->n_channels(); ++n) {
- srcs.push_back (&aregion->source (n));
+ srcs.push_back (aregion->source (n));
}
- for (vector<Source*>::iterator i = srcs.begin(); i != srcs.end(); ++i) {
+ for (vector<boost::shared_ptr<Source> >::iterator i = srcs.begin(); i != srcs.end(); ++i) {
- if ((*i)->use_cnt() == 0) {
- AudioFileSource* afs = dynamic_cast<AudioFileSource*>(*i);
+ if ((*i).use_count() == 1) {
+ boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*i);
+
if (afs) {
(afs)->mark_for_remove ();
}
- delete *i;
+
+ (*i)->drop_references ();
}
}
@@ -2864,9 +2870,9 @@ Session::destroy_region (Region* region)
}
int
-Session::destroy_regions (list<Region*> regions)
+Session::destroy_regions (list<boost::shared_ptr<Region> > regions)
{
- for (list<Region*>::iterator i = regions.begin(); i != regions.end(); ++i) {
+ for (list<boost::shared_ptr<Region> >::iterator i = regions.begin(); i != regions.end(); ++i) {
destroy_region (*i);
}
return 0;
@@ -2875,12 +2881,12 @@ Session::destroy_regions (list<Region*> regions)
int
Session::remove_last_capture ()
{
- list<Region*> r;
+ list<boost::shared_ptr<Region> > r;
boost::shared_ptr<DiskstreamList> dsl = diskstreams.reader();
for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) {
- list<Region*>& l = (*i)->last_capture_regions();
+ list<boost::shared_ptr<Region> >& l = (*i)->last_capture_regions();
if (!l.empty()) {
r.insert (r.end(), l.begin(), l.end());
@@ -2893,62 +2899,77 @@ Session::remove_last_capture ()
}
int
-Session::remove_region_from_region_list (Region& r)
+Session::remove_region_from_region_list (boost::shared_ptr<Region> r)
{
- remove_region (&r);
+ remove_region (r);
return 0;
}
/* Source Management */
void
-Session::add_source (Source* source)
+Session::add_source (boost::shared_ptr<Source> source)
{
- pair<SourceList::key_type, SourceList::mapped_type> entry;
+ cerr << "add new source " << source->name() << endl;
+
+ pair<SourceMap::key_type, SourceMap::mapped_type> entry;
+ pair<SourceMap::iterator,bool> result;
- {
- Glib::Mutex::Lock lm (source_lock);
- entry.first = source->id();
- entry.second = source;
- sources.insert (entry);
- }
+ entry.first = source->id();
+ entry.second = source;
- source->GoingAway.connect (mem_fun (this, &Session::remove_source));
+ {
+ Glib::Mutex::Lock lm (source_lock);
+ result = sources.insert (entry);
+ }
+
+ if (!result.second) {
+ cerr << "\tNOT inserted ? " << result.second << endl;
+ }
+
+ source->GoingAway.connect (sigc::bind (mem_fun (this, &Session::remove_source), boost::weak_ptr<Source> (source)));
set_dirty();
SourceAdded (source); /* EMIT SIGNAL */
}
void
-Session::remove_source (Source* source)
+Session::remove_source (boost::weak_ptr<Source> src)
{
- SourceList::iterator i;
+ SourceMap::iterator i;
+ boost::shared_ptr<Source> source = src.lock();
- {
- Glib::Mutex::Lock lm (source_lock);
-
- if ((i = sources.find (source->id())) != sources.end()) {
- sources.erase (i);
- }
- }
-
- if (!_state_of_the_state & InCleanup) {
-
- /* save state so we don't end up with a session file
- referring to non-existent sources.
- */
+ if (!source) {
+ cerr << "removing a source DEAD\n";
+ } else {
+ cerr << "removing a source " << source->name () << endl;
- save_state (_current_snapshot_name);
+ {
+ Glib::Mutex::Lock lm (source_lock);
+
+ if ((i = sources.find (source->id())) != sources.end()) {
+ sources.erase (i);
+ }
+ }
+
+ if (!_state_of_the_state & InCleanup) {
+
+ /* save state so we don't end up with a session file
+ referring to non-existent sources.
+ */
+
+ save_state (_current_snapshot_name);
+ }
+
+ SourceRemoved(source); /* EMIT SIGNAL */
}
-
- SourceRemoved(source); /* EMIT SIGNAL */
}
-Source *
+boost::shared_ptr<Source>
Session::source_by_id (const PBD::ID& id)
{
Glib::Mutex::Lock lm (source_lock);
- SourceList::iterator i;
- Source* source = 0;
+ SourceMap::iterator i;
+ boost::shared_ptr<Source> source;
if ((i = sources.find (id)) != sources.end()) {
source = i->second;
@@ -3194,24 +3215,11 @@ Session::audio_path_from_name (string name, uint32_t nchan, uint32_t chan, bool
return spath;
}
-AudioFileSource *
+boost::shared_ptr<AudioFileSource>
Session::create_audio_source_for_session (AudioDiskstream& ds, uint32_t chan, bool destructive)
{
string spath = audio_path_from_name (ds.name(), ds.n_channels().get(DataType::AUDIO), chan, destructive);
-
- /* this might throw failed_constructor(), which is OK */
-
- if (destructive) {
- return new DestructiveFileSource (spath,
- Config->get_native_file_data_format(),
- Config->get_native_file_header_format(),
- frame_rate());
- } else {
- return new SndFileSource (spath,
- Config->get_native_file_data_format(),
- Config->get_native_file_header_format(),
- frame_rate());
- }
+ return boost::dynamic_pointer_cast<AudioFileSource> (SourceFactory::createWritable (DataType::AUDIO, spath, destructive, frame_rate()));
}
string
@@ -3277,13 +3285,12 @@ Session::midi_path_from_name (string name)
return spath;
}
-MidiSource *
+boost::shared_ptr<MidiSource>
Session::create_midi_source_for_session (MidiDiskstream& ds)
{
string spath = midi_path_from_name (ds.name());
-
- /* this might throw failed_constructor(), which is OK */
- return new SMFSource (spath);
+
+ return boost::dynamic_pointer_cast<SMFSource> (SourceFactory::createWritable (DataType::MIDI, spath, false, frame_rate()));
}
@@ -3319,7 +3326,7 @@ Session::add_playlist (Playlist* playlist)
playlists.insert (playlists.begin(), playlist);
// playlist->ref();
playlist->InUse.connect (mem_fun (*this, &Session::track_playlist));
- playlist->GoingAway.connect (mem_fun (*this, &Session::remove_playlist));
+ playlist->GoingAway.connect (sigc::bind (mem_fun (*this, &Session::remove_playlist), playlist));
}
}
@@ -3390,7 +3397,7 @@ Session::remove_playlist (Playlist* playlist)
}
void
-Session::set_audition (AudioRegion* r)
+Session::set_audition (boost::shared_ptr<Region> r)
{
pending_audition_region = r;
post_transport_work = PostTransportWork (post_transport_work | PostTransportAudition);
@@ -3398,42 +3405,39 @@ Session::set_audition (AudioRegion* r)
}
void
+Session::audition_playlist ()
+{
+ Event* ev = new Event (Event::Audition, Event::Add, Event::Immediate, 0, 0.0);
+ ev->region.reset ();
+ queue_event (ev);
+}
+
+void
Session::non_realtime_set_audition ()
{
- if (pending_audition_region == (AudioRegion*) 0xfeedface) {
+ if (!pending_audition_region) {
auditioner->audition_current_playlist ();
- } else if (pending_audition_region) {
- auditioner->audition_region (*pending_audition_region);
+ } else {
+ auditioner->audition_region (pending_audition_region);
+ pending_audition_region.reset ();
}
- pending_audition_region = 0;
AuditionActive (true); /* EMIT SIGNAL */
}
void
-Session::audition_playlist ()
+Session::audition_region (boost::shared_ptr<Region> r)
{
Event* ev = new Event (Event::Audition, Event::Add, Event::Immediate, 0, 0.0);
- ev->set_ptr ((void*) 0xfeedface);
+ ev->region = r;
queue_event (ev);
}
void
-Session::audition_region (Region& r)
-{
- AudioRegion* ar = dynamic_cast<AudioRegion*>(&r);
- if (ar) {
- Event* ev = new Event (Event::Audition, Event::Add, Event::Immediate, 0, 0.0);
- ev->set_ptr (ar);
- queue_event (ev);
- }
-}
-
-void
Session::cancel_audition ()
{
if (auditioner->active()) {
auditioner->cancel_audition ();
- AuditionActive (false); /* EMIT SIGNAL */
+ AuditionActive (false); /* EMIT SIGNAL */
}
}
@@ -3600,7 +3604,7 @@ Session::add_redirect (Redirect* redirect)
/*NOTREACHED*/
}
- redirect->GoingAway.connect (mem_fun (*this, &Session::remove_redirect));
+ redirect->GoingAway.connect (sigc::bind (mem_fun (*this, &Session::remove_redirect), redirect));
set_dirty();
}
@@ -3822,9 +3826,9 @@ Session::route_name_unique (string n) const
}
int
-Session::cleanup_audio_file_source (AudioFileSource& fs)
+Session::cleanup_audio_file_source (boost::shared_ptr<AudioFileSource> fs)
{
- return fs.move_to_trash (dead_sound_dir_name);
+ return fs->move_to_trash (dead_sound_dir_name);
}
uint32_t
@@ -3891,11 +3895,12 @@ Session::freeze (InterThreadInfo& itt)
int
Session::write_one_audio_track (AudioTrack& track, jack_nframes_t start, jack_nframes_t len,
- bool overwrite, vector<Source*>& srcs, InterThreadInfo& itt)
+ bool overwrite, vector<boost::shared_ptr<Source> >& srcs, InterThreadInfo& itt)
{
+ boost::shared_ptr<AudioFileSource> fsource;
+
int ret = -1;
Playlist* playlist = 0;
- AudioFileSource* fsource = 0;
uint32_t x;
char buf[PATH_MAX+1];
string dir;
@@ -3939,11 +3944,7 @@ Session::write_one_audio_track (AudioTrack& track, jack_nframes_t start, jack_nf
}
try {
- fsource = new SndFileSource (buf,
- Config->get_native_file_data_format(),
- Config->get_native_file_header_format(),
- frame_rate());
-
+ fsource = boost::dynamic_pointer_cast<AudioFileSource> (SourceFactory::createWritable (DataType::AUDIO, buf, false, frame_rate()));
}
catch (failed_constructor& err) {
@@ -3951,7 +3952,7 @@ Session::write_one_audio_track (AudioTrack& track, jack_nframes_t start, jack_nf
goto out;
}
- srcs.push_back(fsource);
+ srcs.push_back (fsource);
}
/* XXX need to flush all redirects */
@@ -3972,9 +3973,9 @@ Session::write_one_audio_track (AudioTrack& track, jack_nframes_t start, jack_nf
}
uint32_t n = 0;
- for (vector<Source*>::iterator src=srcs.begin(); src != srcs.end(); ++src, ++n) {
- AudioFileSource* afs = dynamic_cast<AudioFileSource*>(*src);
-
+ for (vector<boost::shared_ptr<Source> >::iterator src=srcs.begin(); src != srcs.end(); ++src, ++n) {
+ boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
+
if (afs) {
if (afs->write (buffers.get_audio(n).data(this_chunk), this_chunk) != this_chunk) {
goto out;
@@ -3996,8 +3997,9 @@ Session::write_one_audio_track (AudioTrack& track, jack_nframes_t start, jack_nf
time (&now);
xnow = localtime (&now);
- for (vector<Source*>::iterator src=srcs.begin(); src != srcs.end(); ++src) {
- AudioFileSource* afs = dynamic_cast<AudioFileSource*>(*src);
+ for (vector<boost::shared_ptr<Source> >::iterator src=srcs.begin(); src != srcs.end(); ++src) {
+ boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
+
if (afs) {
afs->update_header (position, *xnow, now);
}
@@ -4005,8 +4007,8 @@ Session::write_one_audio_track (AudioTrack& track, jack_nframes_t start, jack_nf
/* build peakfile for new source */
- for (vector<Source*>::iterator src=srcs.begin(); src != srcs.end(); ++src) {
- AudioFileSource* afs = dynamic_cast<AudioFileSource*>(*src);
+ for (vector<boost::shared_ptr<Source> >::iterator src=srcs.begin(); src != srcs.end(); ++src) {
+ boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
if (afs) {
afs->build_peaks ();
}
@@ -4017,12 +4019,14 @@ Session::write_one_audio_track (AudioTrack& track, jack_nframes_t start, jack_nf
out:
if (ret) {
- for (vector<Source*>::iterator src=srcs.begin(); src != srcs.end(); ++src) {
- AudioFileSource* afs = dynamic_cast<AudioFileSource*>(*src);
+ for (vector<boost::shared_ptr<Source> >::iterator src = srcs.begin(); src != srcs.end(); ++src) {
+ boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*src);
+
if (afs) {
afs->mark_for_remove ();
}
- delete *src;
+
+ (*src)->drop_references ();
}
}
diff --git a/libs/ardour/session_butler.cc b/libs/ardour/session_butler.cc
index 5d691a7425..832284901c 100644
--- a/libs/ardour/session_butler.cc
+++ b/libs/ardour/session_butler.cc
@@ -187,7 +187,7 @@ Session::butler_thread_work ()
}
if (pfd[0].revents & ~POLLIN) {
- error << _("Error on butler thread request pipe") << endmsg;
+ error << string_compose (_("Error on butler thread request pipe: fd=%1 err=%2"), pfd[0].fd, pfd[0].revents) << endmsg;
break;
}
diff --git a/libs/ardour/session_command.cc b/libs/ardour/session_command.cc
index 4e7c4151b7..fb15304e9f 100644
--- a/libs/ardour/session_command.cc
+++ b/libs/ardour/session_command.cc
@@ -13,9 +13,7 @@ using namespace PBD;
namespace ARDOUR {
-static map<PBD::ID, Stateful*> registry;
-
-void Session::register_with_memento_command_factory(PBD::ID id, Stateful *ptr)
+void Session::register_with_memento_command_factory(PBD::ID id, StatefulDestructible *ptr)
{
registry[id] = ptr;
}
@@ -90,7 +88,8 @@ Command *Session::memento_command_factory(XMLNode *n)
}
// For Editor and AutomationLine which are off-limits here
else if (registry.count(id))
- return new MementoCommand<Stateful>(*registry[id], before, after);
+ return new MementoCommand<StatefulDestructible>(*registry[id], before, after);
+
/* we failed */
error << _("could not reconstitute MementoCommand from XMLNode. id=") << id.to_s() << endmsg;
diff --git a/libs/ardour/session_events.cc b/libs/ardour/session_events.cc
index 79d20c8c39..9b6313fff3 100644
--- a/libs/ardour/session_events.cc
+++ b/libs/ardour/session_events.cc
@@ -405,7 +405,7 @@ Session::process_event (Event* ev)
break;
case Event::Audition:
- set_audition (static_cast<AudioRegion*> (ev->ptr));
+ set_audition (ev->region);
break;
case Event::InputConfigurationChange:
diff --git a/libs/ardour/session_state.cc b/libs/ardour/session_state.cc
index 5553127b90..6351b64cfe 100644
--- a/libs/ardour/session_state.cc
+++ b/libs/ardour/session_state.cc
@@ -88,6 +88,8 @@
#include <ardour/midi_region.h>
#include <ardour/crossfade.h>
#include <ardour/control_protocol_manager.h>
+#include <ardour/region_factory.h>
+#include <ardour/source_factory.h>
#include "i18n.h"
#include <locale.h>
@@ -182,7 +184,6 @@ Session::first_stage_init (string fullpath, string snapshot_name)
g_atomic_int_set (&_capture_load, 100);
g_atomic_int_set (&_playback_load_min, 100);
g_atomic_int_set (&_capture_load_min, 100);
- pending_audition_region = 0;
_edit_mode = Slide;
pending_edit_mode = _edit_mode;
_play_range = false;
@@ -197,6 +198,7 @@ Session::first_stage_init (string fullpath, string snapshot_name)
layer_model = MoveAddHigher;
xfade_model = ShortCrossfade;
destructive_index = 0;
+ current_trans = 0;
AudioDiskstream::allocate_working_buffers();
@@ -267,13 +269,13 @@ Session::first_stage_init (string fullpath, string snapshot_name)
/* These are all static "per-class" signals */
- Region::CheckNewRegion.connect (mem_fun (*this, &Session::add_region));
- Source::SourceCreated.connect (mem_fun (*this, &Session::add_source));
+ 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));
Redirect::RedirectCreated.connect (mem_fun (*this, &Session::add_redirect));
NamedSelection::NamedSelectionCreated.connect (mem_fun (*this, &Session::add_named_selection));
- Curve::CurveCreated.connect (mem_fun (*this, &Session::add_curve));
- AutomationList::AutomationListCreated.connect (mem_fun (*this, &Session::add_automation_list));
+ Curve::CurveCreated.connect (mem_fun (*this, &Session::add_curve));
+ AutomationList::AutomationListCreated.connect (mem_fun (*this, &Session::add_automation_list));
Controllable::Created.connect (mem_fun (*this, &Session::add_controllable));
Controllable::GoingAway.connect (mem_fun (*this, &Session::remove_controllable));
@@ -294,6 +296,7 @@ Session::second_stage_init (bool new_session)
if (!new_session) {
if (load_state (_current_snapshot_name)) {
+ cerr << "load state failed\n";
return -1;
}
remove_empty_sounds ();
@@ -1360,17 +1363,21 @@ Session::state(bool full_state)
if (full_state) {
Glib::Mutex::Lock sl (source_lock);
- for (SourceList::iterator siter = sources.begin(); siter != sources.end(); ++siter) {
+ for (SourceMap::iterator siter = sources.begin(); siter != sources.end(); ++siter) {
+ /* Don't save information about AudioFileSources that are empty */
+
+ boost::shared_ptr<AudioFileSource> fs;
- DestructiveFileSource* const dfs = dynamic_cast<DestructiveFileSource*> (siter->second);
-
- /* Don't save sources that are empty, unless they're destructive (which are OK
- if they are empty, because we will re-use them every time.)
- */
+ if ((fs = boost::dynamic_pointer_cast<AudioFileSource> (siter->second)) != 0) {
+ boost::shared_ptr<DestructiveFileSource> dfs = boost::dynamic_pointer_cast<DestructiveFileSource> (fs);
- if ( ! dfs && siter->second->length() == 0) {
- continue;
+ /* Don't save sources that are empty, unless they're destructive (which are OK
+ if they are empty, because we will re-use them every time.)
+ */
+ if ( ! dfs && siter->second->length() == 0) {
+ continue;
+ }
}
child->add_child_nocopy (siter->second->get_state());
@@ -1774,7 +1781,7 @@ Session::load_regions (const XMLNode& node)
{
XMLNodeList nlist;
XMLNodeConstIterator niter;
- Region* region;
+ boost::shared_ptr<Region> region;
nlist = node.children();
@@ -1785,10 +1792,11 @@ Session::load_regions (const XMLNode& node)
error << _("Session: cannot create Region from XML description.") << endmsg;
}
}
+
return 0;
}
-Region *
+boost::shared_ptr<Region>
Session::XMLRegionFactory (const XMLNode& node, bool full)
{
const XMLProperty* type = node.property("type");
@@ -1797,33 +1805,33 @@ Session::XMLRegionFactory (const XMLNode& node, bool full)
if ( !type || type->value() == "audio" ) {
- return XMLAudioRegionFactory (node, full);
+ return boost::shared_ptr<Region>(XMLAudioRegionFactory (node, full));
} else if (type->value() == "midi") {
- return XMLMidiRegionFactory (node, full);
+ return boost::shared_ptr<Region>(XMLMidiRegionFactory (node, full));
}
} catch (failed_constructor& err) {
- return 0;
+ return boost::shared_ptr<Region> ();
}
- return 0;
+ return boost::shared_ptr<Region> ();
}
-AudioRegion *
+boost::shared_ptr<AudioRegion>
Session::XMLAudioRegionFactory (const XMLNode& node, bool full)
{
const XMLProperty* prop;
- Source* source;
- AudioSource* as;
- AudioRegion::SourceList sources;
+ boost::shared_ptr<Source> source;
+ boost::shared_ptr<AudioSource> as;
+ SourceList sources;
uint32_t nchans = 1;
char buf[128];
if (node.name() != X_("Region")) {
- return 0;
+ return boost::shared_ptr<AudioRegion>();
}
if ((prop = node.property (X_("channels"))) != 0) {
@@ -1834,7 +1842,7 @@ Session::XMLAudioRegionFactory (const XMLNode& node, bool full)
if ((prop = node.property (X_("source-0"))) == 0) {
if ((prop = node.property ("source")) == 0) {
error << _("Session: XMLNode describing a AudioRegion is incomplete (no source)") << endmsg;
- return 0;
+ return boost::shared_ptr<AudioRegion>();
}
}
@@ -1842,13 +1850,13 @@ Session::XMLAudioRegionFactory (const XMLNode& node, bool full)
if ((source = source_by_id (s_id)) == 0) {
error << string_compose(_("Session: XMLNode describing a AudioRegion references an unknown source id =%1"), s_id) << endmsg;
- return 0;
+ return boost::shared_ptr<AudioRegion>();
}
-
- as = dynamic_cast<AudioSource*>(source);
+
+ as = boost::dynamic_pointer_cast<AudioSource>(source);
if (!as) {
error << string_compose(_("Session: XMLNode describing a AudioRegion references a non-audio source id =%1"), s_id) << endmsg;
- return 0;
+ return boost::shared_ptr<AudioRegion>();
}
sources.push_back (as);
@@ -1863,38 +1871,40 @@ Session::XMLAudioRegionFactory (const XMLNode& node, bool full)
if ((source = source_by_id (id2)) == 0) {
error << string_compose(_("Session: XMLNode describing a AudioRegion references an unknown source id =%1"), id2) << endmsg;
- return 0;
+ return boost::shared_ptr<AudioRegion>();
}
- as = dynamic_cast<AudioSource*>(source);
+ as = boost::dynamic_pointer_cast<AudioSource>(source);
if (!as) {
error << string_compose(_("Session: XMLNode describing a AudioRegion references a non-audio source id =%1"), id2) << endmsg;
- return 0;
+ return boost::shared_ptr<AudioRegion>();
}
sources.push_back (as);
}
}
try {
- return new AudioRegion (sources, node);
+ boost::shared_ptr<AudioRegion> region (boost::dynamic_pointer_cast<AudioRegion> (RegionFactory::create (sources, node)));
+ return region;
+
}
catch (failed_constructor& err) {
- return 0;
+ return boost::shared_ptr<AudioRegion>();
}
}
-MidiRegion *
+boost::shared_ptr<MidiRegion>
Session::XMLMidiRegionFactory (const XMLNode& node, bool full)
{
const XMLProperty* prop;
- Source* source;
- MidiSource* ms;
+ boost::shared_ptr<Source> source;
+ boost::shared_ptr<MidiSource> ms;
MidiRegion::SourceList sources;
uint32_t nchans = 1;
if (node.name() != X_("Region")) {
- return 0;
+ return boost::shared_ptr<MidiRegion>();
}
if ((prop = node.property (X_("channels"))) != 0) {
@@ -1907,7 +1917,7 @@ Session::XMLMidiRegionFactory (const XMLNode& node, bool full)
if ((prop = node.property (X_("source-0"))) == 0) {
if ((prop = node.property ("source")) == 0) {
error << _("Session: XMLNode describing a MidiRegion is incomplete (no source)") << endmsg;
- return 0;
+ return boost::shared_ptr<MidiRegion>();
}
}
@@ -1915,23 +1925,24 @@ Session::XMLMidiRegionFactory (const XMLNode& node, bool full)
if ((source = source_by_id (s_id)) == 0) {
error << string_compose(_("Session: XMLNode describing a MidiRegion references an unknown source id =%1"), s_id) << endmsg;
- return 0;
+ return boost::shared_ptr<MidiRegion>();
}
- ms = dynamic_cast<MidiSource*>(source);
+ ms = boost::dynamic_pointer_cast<MidiSource>(source);
if (!ms) {
- error << string_compose(_("Session: XMLNode describing a MidiRegion references a non-audio source id =%1"), s_id) << endmsg;
- return 0;
+ error << string_compose(_("Session: XMLNode describing a MidiRegion references a non-midi source id =%1"), s_id) << endmsg;
+ return boost::shared_ptr<MidiRegion>();
}
sources.push_back (ms);
try {
- return new MidiRegion (sources, node);
+ boost::shared_ptr<MidiRegion> region (boost::dynamic_pointer_cast<MidiRegion> (RegionFactory::create (sources, node)));
+ return region;
}
catch (failed_constructor& err) {
- return 0;
+ return boost::shared_ptr<MidiRegion>();
}
}
@@ -1942,7 +1953,7 @@ Session::get_sources_as_xml ()
XMLNode* node = new XMLNode (X_("Sources"));
Glib::Mutex::Lock lm (source_lock);
- for (SourceList::iterator i = sources.begin(); i != sources.end(); ++i) {
+ for (SourceMap::iterator i = sources.begin(); i != sources.end(); ++i) {
node->add_child_nocopy (i->second->get_state());
}
@@ -1979,7 +1990,7 @@ Session::load_sources (const XMLNode& node)
{
XMLNodeList nlist;
XMLNodeConstIterator niter;
- Source* source;
+ boost::shared_ptr<Source> source;
nlist = node.children();
@@ -1995,41 +2006,22 @@ Session::load_sources (const XMLNode& node)
return 0;
}
-Source *
+boost::shared_ptr<Source>
Session::XMLSourceFactory (const XMLNode& node)
{
- Source *src = 0;
if (node.name() != "Source") {
- return 0;
- }
-
- DataType type = DataType::AUDIO;
- const XMLProperty* prop = node.property("type");
- if (prop) {
- type = DataType(prop->value());
+ return boost::shared_ptr<Source>();
}
try {
-
-
- if (type == DataType::AUDIO) {
-
- src = AudioFileSource::create (node);
-
- } else if (type == DataType::MIDI) {
-
- src = new SMFSource (node);
-
+ return SourceFactory::create (node);
}
-
- } catch (failed_constructor& err) {
- error << _("Found a file that cannot be read by Ardour. Talk to the progammers.") << endmsg;
- return 0;
+ catch (failed_constructor& err) {
+ error << _("Found a sound file that cannot be used by Ardour. Talk to the progammers.") << endmsg;
+ return boost::shared_ptr<Source>();
}
-
- return src;
}
int
@@ -2699,8 +2691,8 @@ Session::set_meter_falloff (float val)
void
Session::begin_reversible_command (string name)
{
- current_trans.clear ();
- current_trans.set_name (name);
+ current_trans = new UndoTransaction;
+ current_trans->set_name (name);
}
void
@@ -2709,11 +2701,11 @@ Session::commit_reversible_command (Command *cmd)
struct timeval now;
if (cmd) {
- current_trans.add_command (cmd);
+ current_trans->add_command (cmd);
}
gettimeofday (&now, 0);
- current_trans.set_timestamp (now);
+ current_trans->set_timestamp (now);
history.add (current_trans);
}
@@ -3007,7 +2999,7 @@ Session::find_all_sources_across_snapshots (set<string>& result, bool exclude_th
int
Session::cleanup_sources (Session::cleanup_report& rep)
{
- vector<Source*> dead_sources;
+ vector<boost::shared_ptr<Source> > dead_sources;
vector<Playlist*> playlists_tbd;
PathScanner scanner;
string sound_path;
@@ -3067,9 +3059,9 @@ Session::cleanup_sources (Session::cleanup_report& rep)
rep.paths.clear ();
rep.space = 0;
- for (SourceList::iterator i = sources.begin(); i != sources.end(); ) {
+ for (SourceMap::iterator i = sources.begin(); i != sources.end(); ) {
- SourceList::iterator tmp;
+ SourceMap::iterator tmp;
tmp = i;
++tmp;
@@ -3079,7 +3071,7 @@ Session::cleanup_sources (Session::cleanup_report& rep)
capture files.
*/
- if (i->second->use_cnt() == 0 && i->second->length() > 0) {
+ if (i->second.use_count() == 1 && i->second->length() > 0) {
dead_sources.push_back (i->second);
/* remove this source from our own list to avoid us
@@ -3097,7 +3089,7 @@ Session::cleanup_sources (Session::cleanup_report& rep)
other snapshots).
*/
- for (vector<Source*>::iterator i = dead_sources.begin(); i != dead_sources.end();++i) {
+ for (vector<boost::shared_ptr<Source> >::iterator i = dead_sources.begin(); i != dead_sources.end();++i) {
for (RegionList::iterator r = regions.begin(); r != regions.end(); ) {
RegionList::iterator tmp;
@@ -3105,10 +3097,10 @@ Session::cleanup_sources (Session::cleanup_report& rep)
tmp = r;
++tmp;
- Region* const reg = r->second;
+ boost::shared_ptr<Region> reg = r->second;
for (uint32_t n = 0; n < reg->n_channels(); ++n) {
- if (&reg->source (n) == (*i)) {
+ if (reg->source (n) == (*i)) {
/* this region is dead */
remove_region (reg);
}
@@ -3155,10 +3147,10 @@ Session::cleanup_sources (Session::cleanup_report& rep)
/* add our current source list
*/
- for (SourceList::iterator i = sources.begin(); i != sources.end(); ++i) {
- AudioFileSource* fs;
+ for (SourceMap::iterator i = sources.begin(); i != sources.end(); ++i) {
+ boost::shared_ptr<AudioFileSource> fs;
- if ((fs = dynamic_cast<AudioFileSource*> (i->second)) != 0) {
+ if ((fs = boost::dynamic_pointer_cast<AudioFileSource> (i->second)) != 0) {
all_sources.insert (fs->path());
}
}
@@ -3484,15 +3476,15 @@ Session::restore_history (string snapshot_name)
it++)
{
XMLNode *t = *it;
- UndoTransaction ut;
+ UndoTransaction* ut = new UndoTransaction ();
struct timeval tv;
- ut.set_name(t->property("name")->value());
+ ut->set_name(t->property("name")->value());
stringstream ss(t->property("tv_sec")->value());
ss >> tv.tv_sec;
ss.str(t->property("tv_usec")->value());
ss >> tv.tv_usec;
- ut.set_timestamp(tv);
+ ut->set_timestamp(tv);
for (XMLNodeConstIterator child_it = t->children().begin();
child_it != t->children().end();
@@ -3506,7 +3498,7 @@ Session::restore_history (string snapshot_name)
{
c = memento_command_factory(n);
if (c)
- ut.add_command(c);
+ ut->add_command(c);
}
else
{
diff --git a/libs/ardour/session_timefx.cc b/libs/ardour/session_timefx.cc
index 82fd25ddb2..4ba8d42d9e 100644
--- a/libs/ardour/session_timefx.cc
+++ b/libs/ardour/session_timefx.cc
@@ -28,6 +28,8 @@
#include <ardour/session.h>
#include <ardour/audioregion.h>
#include <ardour/sndfilesource.h>
+#include <ardour/region_factory.h>
+#include <ardour/source_factory.h>
#include "i18n.h"
@@ -36,12 +38,12 @@ using namespace ARDOUR;
using namespace PBD;
using namespace soundtouch;
-AudioRegion*
+boost::shared_ptr<AudioRegion>
Session::tempoize_region (TimeStretchRequest& tsr)
{
- AudioRegion::SourceList sources;
- AudioRegion::SourceList::iterator it;
- AudioRegion* r = 0;
+ SourceList sources;
+ SourceList::iterator it;
+ boost::shared_ptr<AudioRegion> r;
SoundTouch st;
string region_name;
string ident = X_("-TIMEFX-");
@@ -80,10 +82,9 @@ Session::tempoize_region (TimeStretchRequest& tsr)
}
try {
- sources.push_back (new SndFileSource (path,
- Config->get_native_file_data_format(),
- Config->get_native_file_header_format(),
- frame_rate()));
+ sources.push_back (boost::dynamic_pointer_cast<AudioFileSource> (
+ SourceFactory::createWritable (DataType::AUDIO, path, false, frame_rate())));
+
} catch (failed_constructor& err) {
error << string_compose (_("tempoize: error creating new audio file %1 (%2)"), path, strerror (errno)) << endmsg;
goto out;
@@ -99,7 +100,7 @@ Session::tempoize_region (TimeStretchRequest& tsr)
jack_nframes_t pos = 0;
jack_nframes_t this_read = 0;
- AudioSource* const asrc = dynamic_cast<AudioSource*>(sources[i]);
+ boost::shared_ptr<AudioSource> asrc = boost::dynamic_pointer_cast<AudioSource>(sources[i]);
if (!asrc) {
cerr << "FIXME: TimeFX for non-audio" << endl;
continue;
@@ -158,7 +159,7 @@ Session::tempoize_region (TimeStretchRequest& tsr)
xnow = localtime (&now);
for (it = sources.begin(); it != sources.end(); ++it) {
- AudioFileSource* afs = dynamic_cast<AudioFileSource*>(*it);
+ boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource>(*it);
if (afs) {
afs->update_header (tsr.region->position(), *xnow, now);
}
@@ -166,10 +167,9 @@ Session::tempoize_region (TimeStretchRequest& tsr)
region_name = tsr.region->name() + X_(".t");
- r = new AudioRegion (sources, 0, sources.front()->length(), region_name,
- 0, AudioRegion::Flag (AudioRegion::DefaultFlags | AudioRegion::WholeFile));
-
-
+ r = (boost::dynamic_pointer_cast<AudioRegion> (RegionFactory::create (sources, 0, sources.front()->length(), region_name,
+ 0, AudioRegion::Flag (AudioRegion::DefaultFlags | AudioRegion::WholeFile))));
+
out:
if (sources.size()) {
@@ -178,21 +178,19 @@ Session::tempoize_region (TimeStretchRequest& tsr)
for deletion.
*/
- if ((r == 0 || !tsr.running)) {
+ if ((!r || !tsr.running)) {
for (it = sources.begin(); it != sources.end(); ++it) {
(*it)->mark_for_remove ();
- delete *it;
}
}
+
+ sources.clear ();
}
/* if the process was cancelled, delete the region */
if (!tsr.running) {
- if (r) {
- delete r;
- r = 0;
- }
+ r.reset ();
}
return r;
diff --git a/libs/ardour/smf_source.cc b/libs/ardour/smf_source.cc
index 5a5bafb6ca..44186ef86f 100644
--- a/libs/ardour/smf_source.cc
+++ b/libs/ardour/smf_source.cc
@@ -70,8 +70,6 @@ SMFSource::SMFSource (std::string path, Flag flags)
}
assert(_name.find("/") == string::npos);
-
- SourceCreated (this); /* EMIT SIGNAL */
}
SMFSource::SMFSource (const XMLNode& node)
@@ -100,8 +98,6 @@ SMFSource::SMFSource (const XMLNode& node)
}
assert(_name.find("/") == string::npos);
-
- SourceCreated (this); /* EMIT SIGNAL */
}
SMFSource::~SMFSource ()
diff --git a/libs/ardour/sndfilesource.cc b/libs/ardour/sndfilesource.cc
index 83c3c982b0..2bdcdc5a02 100644
--- a/libs/ardour/sndfilesource.cc
+++ b/libs/ardour/sndfilesource.cc
@@ -50,8 +50,6 @@ SndFileSource::SndFileSource (const XMLNode& node)
throw failed_constructor ();
}
}
-
- SourceCreated (this); /* EMIT SIGNAL */
}
SndFileSource::SndFileSource (string idstr, Flag flags)
@@ -71,9 +69,6 @@ SndFileSource::SndFileSource (string idstr, Flag flags)
throw failed_constructor ();
}
}
-
-
- SourceCreated (this); /* EMIT SIGNAL */
}
SndFileSource::SndFileSource (string idstr, SampleFormat sfmt, HeaderFormat hf, jack_nframes_t rate, Flag flags)
@@ -183,9 +178,6 @@ SndFileSource::SndFileSource (string idstr, SampleFormat sfmt, HeaderFormat hf,
throw failed_constructor ();
}
}
-
- SourceCreated (this); /* EMIT SIGNAL */
-
}
void
@@ -235,7 +227,8 @@ SndFileSource::open ()
_length = _info.frames;
- _broadcast_info = (SF_BROADCAST_INFO*) calloc (1, sizeof (SF_BROADCAST_INFO));
+ _broadcast_info = new SF_BROADCAST_INFO;
+ memset (_broadcast_info, 0, sizeof (*_broadcast_info));
/* lookup broadcast info */
@@ -244,7 +237,7 @@ SndFileSource::open ()
/* if the file has data but no broadcast info, then clearly, there is no broadcast info */
if (_length) {
- free (_broadcast_info);
+ delete _broadcast_info;
_broadcast_info = 0;
_flags = Flag (_flags & ~Broadcast);
}
@@ -269,7 +262,7 @@ SndFileSource::open ()
SndFileSource::~SndFileSource ()
{
- GoingAway (this); /* EMIT SIGNAL */
+ GoingAway (); /* EMIT SIGNAL */
if (sf) {
sf_close (sf);
@@ -412,7 +405,7 @@ SndFileSource::write_unlocked (Sample *data, jack_nframes_t cnt)
if (_build_peakfiles) {
- queue_for_peaks (*this);
+ queue_for_peaks (this);
}
_write_data_count = cnt;
@@ -485,7 +478,7 @@ SndFileSource::setup_broadcast_info (jack_nframes_t when, struct tm& now, time_t
if (sf_command (sf, SFC_SET_BROADCAST_INFO, _broadcast_info, sizeof (*_broadcast_info)) != SF_TRUE) {
error << string_compose (_("cannot set broadcast info for audio file %1; Dropping broadcast info for this file"), _path) << endmsg;
_flags = Flag (_flags & ~Broadcast);
- free (_broadcast_info);
+ delete _broadcast_info;
_broadcast_info = 0;
return -1;
}
@@ -506,7 +499,7 @@ SndFileSource::set_header_timeline_position ()
if (sf_command (sf, SFC_SET_BROADCAST_INFO, _broadcast_info, sizeof (*_broadcast_info)) != SF_TRUE) {
error << string_compose (_("cannot set broadcast info for audio file %1; Dropping broadcast info for this file"), _path) << endmsg;
_flags = Flag (_flags & ~Broadcast);
- free (_broadcast_info);
+ delete _broadcast_info;
_broadcast_info = 0;
}
}
diff --git a/libs/ardour/source.cc b/libs/ardour/source.cc
index 0b15a8b5b8..d218e2cf94 100644
--- a/libs/ardour/source.cc
+++ b/libs/ardour/source.cc
@@ -51,7 +51,6 @@ Source::Source (string name, DataType type)
assert(_name.find("/") == string::npos);
_name = name;
- _use_cnt = 0;
_timestamp = 0;
_length = 0;
}
@@ -59,7 +58,6 @@ Source::Source (string name, DataType type)
Source::Source (const XMLNode& node)
: _type(DataType::AUDIO)
{
- _use_cnt = 0;
_timestamp = 0;
_length = 0;
@@ -71,6 +69,7 @@ Source::Source (const XMLNode& node)
Source::~Source ()
{
+ notify_callbacks ();
}
XMLNode&
@@ -122,18 +121,6 @@ Source::set_state (const XMLNode& node)
}
void
-Source::use ()
-{
- _use_cnt++;
-}
-
-void
-Source::release ()
-{
- if (_use_cnt) --_use_cnt;
-}
-
-void
Source::update_length (jack_nframes_t pos, jack_nframes_t cnt)
{
if (pos + cnt > _length) {
diff --git a/libs/ardour/source_factory.cc b/libs/ardour/source_factory.cc
new file mode 100644
index 0000000000..2fcdd29033
--- /dev/null
+++ b/libs/ardour/source_factory.cc
@@ -0,0 +1,219 @@
+/*
+ Copyright (C) 2000-2006 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.
+
+ $Id$
+*/
+
+#include <ardour/source_factory.h>
+#include <ardour/sndfilesource.h>
+#include <ardour/smf_source.h>
+#include <ardour/destructive_filesource.h>
+#include <ardour/configuration.h>
+
+#include "i18n.h"
+
+using namespace ARDOUR;
+using namespace std;
+
+sigc::signal<void,boost::shared_ptr<Source> > SourceFactory::SourceCreated;
+
+#ifdef HAVE_COREAUDIO
+
+
+boost::shared_ptr<Source>
+SourceFactory::create (const XMLNode& node)
+{
+ DataType type = DataType::AUDIO;
+ const XMLProperty* prop = node.property("type");
+ if (prop) {
+ type = DataType(prop->value());
+ }
+
+ if (type == DataType::AUDIO) {
+
+ if (node.property (X_("destructive")) != 0) {
+
+ boost::shared_ptr<Source> ret (new DestructiveFileSource (node));
+ SourceCreated (ret);
+ return ret;
+
+ } else {
+
+ try {
+ boost::shared_ptr<Source> ret (new CoreAudioSource (node));
+ SourceCreated (ret);
+ return ret;
+ }
+
+
+ catch (failed_constructor& err) {
+ boost::shared_ptr<Source> ret (new SndFileSource (node));
+ SourceCreated (ret);
+ return ret;
+ }
+ }
+
+ } else if (type == DataType::MIDI) {
+
+ boost::shared_ptr<Source> ret (new SMFSource (node));
+ SourceCreated (ret);
+ return ret;
+
+ }
+
+ return boost::shared_ptr<Source>();
+}
+
+#else
+
+boost::shared_ptr<Source>
+SourceFactory::create (const XMLNode& node)
+{
+ DataType type = DataType::AUDIO;
+ const XMLProperty* prop = node.property("type");
+ if (prop) {
+ type = DataType(prop->value());
+ }
+
+ if (type == DataType::AUDIO) {
+
+ if (node.property (X_("destructive")) != 0) {
+
+ boost::shared_ptr<Source> ret (new DestructiveFileSource (node));
+ SourceCreated (ret);
+ return ret;
+
+ } else {
+
+ boost::shared_ptr<Source> ret (new SndFileSource (node));
+ SourceCreated (ret);
+ return ret;
+ }
+
+ } else if (type == DataType::MIDI) {
+
+ boost::shared_ptr<Source> ret (new SMFSource (node));
+ SourceCreated (ret);
+ return ret;
+
+ }
+
+ return boost::shared_ptr<Source> ();
+}
+
+#endif // HAVE_COREAUDIO
+
+#ifdef HAVE_COREAUDIO
+boost::shared_ptr<Source>
+SourceFactory::createReadable (string idstr, AudioFileSource::Flag flags, bool announce)
+{
+ if (type == DataType::AUDIO) {
+ if (flags & Destructive) {
+ boost::shared_ptr<Source> ret (new DestructiveFileSource (idstr, flags));
+ if (announce) {
+ SourceCreated (ret);
+ }
+ return ret;
+ }
+
+ try {
+ boost::shared_ptr<Source> ret (new CoreAudioSource (idstr, flags));
+ if (announce) {
+ SourceCreated (ret);
+ }
+ return ret;
+ }
+
+ catch (failed_constructor& err) {
+ boost::shared_ptr<Source> ret (new SndFileSource (idstr, flags));
+ if (announce) {
+ SourceCreated (ret);
+ }
+ return ret;
+ }
+ } else if (type == DataType::MIDI) {
+
+ boost::shared_ptr<Source> ret (new SMFSource (node));
+ SourceCreated (ret);
+ return ret;
+
+ }
+
+ return boost::shared_ptr<Source>();
+}
+
+#else
+
+boost::shared_ptr<Source>
+SourceFactory::createReadable (DataType type, string idstr, AudioFileSource::Flag flags, bool announce)
+{
+ if (type == DataType::AUDIO) {
+ boost::shared_ptr<Source> ret (new SndFileSource (idstr, flags));
+ if (announce) {
+ SourceCreated (ret);
+ }
+ return ret;
+
+ } else if (type == DataType::MIDI) {
+
+ boost::shared_ptr<Source> ret (new SMFSource (idstr, SMFSource::Flag(0))); // FIXME: flags?
+ SourceCreated (ret);
+ return ret;
+
+ }
+
+ return boost::shared_ptr<Source> ();
+}
+
+#endif // HAVE_COREAUDIO
+
+boost::shared_ptr<Source>
+SourceFactory::createWritable (DataType type, std::string path, bool destructive, jack_nframes_t rate, bool announce)
+{
+ /* this might throw failed_constructor(), which is OK */
+
+ if (type == DataType::AUDIO) {
+ if (destructive) {
+ boost::shared_ptr<Source> ret (new DestructiveFileSource (path,
+ Config->get_native_file_data_format(),
+ Config->get_native_file_header_format(),
+ rate));
+ if (announce) {
+ SourceCreated (ret);
+ }
+ return ret;
+
+ } else {
+ boost::shared_ptr<Source> ret (new SndFileSource (path,
+ Config->get_native_file_data_format(),
+ Config->get_native_file_header_format(),
+ rate));
+ if (announce) {
+ SourceCreated (ret);
+ }
+ return ret;
+ }
+ } else if (type == DataType::MIDI) {
+
+ boost::shared_ptr<Source> ret (new SMFSource (path));
+ SourceCreated (ret);
+ return ret;
+
+ }
+
+ return boost::shared_ptr<Source> ();
+}
diff --git a/libs/ardour/vst_plugin.cc b/libs/ardour/vst_plugin.cc
index 4c09ba3440..dbb7547052 100644
--- a/libs/ardour/vst_plugin.cc
+++ b/libs/ardour/vst_plugin.cc
@@ -98,7 +98,7 @@ VSTPlugin::VSTPlugin (const VSTPlugin &other)
VSTPlugin::~VSTPlugin ()
{
deactivate ();
- GoingAway (this); /* EMIT SIGNAL */
+ GoingAway (); /* EMIT SIGNAL */
fst_close (_fst);
}