From 82232f06ba3eea4a2b4342ad91fab552f4044402 Mon Sep 17 00:00:00 2001 From: David Robillard Date: Tue, 29 Aug 2006 21:21:48 +0000 Subject: 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 --- libs/ardour/SConscript | 2 + libs/ardour/ardour/audio_diskstream.h | 14 +- libs/ardour/ardour/audiofilesource.h | 10 - libs/ardour/ardour/audiofilter.h | 8 +- libs/ardour/ardour/audioplaylist.h | 14 +- libs/ardour/ardour/audioregion.h | 20 +- libs/ardour/ardour/audiosource.h | 4 +- libs/ardour/ardour/auditioner.h | 4 +- libs/ardour/ardour/automation_event.h | 5 +- libs/ardour/ardour/crossfade.h | 29 +-- libs/ardour/ardour/diskstream.h | 10 +- libs/ardour/ardour/io.h | 6 +- libs/ardour/ardour/location.h | 6 +- libs/ardour/ardour/midi_diskstream.h | 4 +- libs/ardour/ardour/midi_playlist.h | 17 +- libs/ardour/ardour/midi_region.h | 20 +- libs/ardour/ardour/playlist.h | 75 ++++---- libs/ardour/ardour/playlist_templates.h | 4 +- libs/ardour/ardour/plugin.h | 6 +- libs/ardour/ardour/redirect.h | 1 - libs/ardour/ardour/region.h | 59 +++--- libs/ardour/ardour/region_factory.h | 30 ++- libs/ardour/ardour/reverse.h | 2 +- libs/ardour/ardour/route.h | 2 +- libs/ardour/ardour/session.h | 134 +++++++------- libs/ardour/ardour/session_region.h | 4 +- libs/ardour/ardour/source.h | 20 +- libs/ardour/ardour/source_factory.h | 28 +++ libs/ardour/ardour/tempo.h | 6 +- libs/ardour/ardour/types.h | 4 + libs/ardour/audio_diskstream.cc | 95 ++++------ libs/ardour/audio_playlist.cc | 151 +++++++--------- libs/ardour/audio_track.cc | 18 +- libs/ardour/audioengine.cc | 24 +-- libs/ardour/audiofilesource.cc | 83 +-------- libs/ardour/audiofilter.cc | 32 ++-- libs/ardour/audioregion.cc | 96 ++++------ libs/ardour/audiosource.cc | 14 +- libs/ardour/auditioner.cc | 25 ++- libs/ardour/automation_event.cc | 2 + libs/ardour/control_protocol_manager.cc | 2 +- libs/ardour/coreaudiosource.cc | 2 +- libs/ardour/crossfade.cc | 38 ++-- libs/ardour/destructive_filesource.cc | 2 +- libs/ardour/diskstream.cc | 6 +- libs/ardour/import.cc | 40 ++-- libs/ardour/insert.cc | 4 +- libs/ardour/io.cc | 19 +- libs/ardour/ladspa_plugin.cc | 2 +- libs/ardour/location.cc | 34 +++- libs/ardour/midi_diskstream.cc | 39 ++-- libs/ardour/midi_playlist.cc | 174 +++--------------- libs/ardour/midi_region.cc | 47 ++--- libs/ardour/osc.cc | 2 +- libs/ardour/playlist.cc | 222 +++++++++++------------ libs/ardour/playlist_factory.cc | 46 ----- libs/ardour/region.cc | 180 ++++++++---------- libs/ardour/region_factory.cc | 182 +++++++++++++++++++ libs/ardour/reverse.cc | 25 +-- libs/ardour/send.cc | 2 +- libs/ardour/session.cc | 312 ++++++++++++++++---------------- libs/ardour/session_butler.cc | 2 +- libs/ardour/session_command.cc | 7 +- libs/ardour/session_events.cc | 2 +- libs/ardour/session_state.cc | 172 +++++++++--------- libs/ardour/session_timefx.cc | 38 ++-- libs/ardour/smf_source.cc | 4 - libs/ardour/sndfilesource.cc | 21 +-- libs/ardour/source.cc | 15 +- libs/ardour/source_factory.cc | 219 ++++++++++++++++++++++ libs/ardour/vst_plugin.cc | 2 +- 71 files changed, 1519 insertions(+), 1431 deletions(-) create mode 100644 libs/ardour/ardour/source_factory.h create mode 100644 libs/ardour/region_factory.cc create mode 100644 libs/ardour/source_factory.cc (limited to 'libs/ardour') 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 write_source (uint32_t n=0) { if (n < channels.size()) return channels[n].write_source; - return 0; + return boost::shared_ptr(); } int add_channel (); @@ -141,8 +141,6 @@ class AudioDiskstream : public Diskstream } } - std::list& 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 fades_source; + boost::shared_ptr 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 capturing_sources; + std::vector > capturing_sources; typedef vector 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 results; + virtual int run (boost::shared_ptr) = 0; + std::vector > 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::SourceList&); + int finish (boost::shared_ptr, 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); 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 orig, boost::shared_ptr left, boost::shared_ptr 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); + void check_dependents (boost::shared_ptr region, bool norefresh); + void remove_dependents (boost::shared_ptr 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); 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 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, jack_nframes_t start, jack_nframes_t length); + AudioRegion (boost::shared_ptr, 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, jack_nframes_t start, jack_nframes_t length, const string& name, layer_t = 0, Region::Flag flags = Region::DefaultFlags); + AudioRegion (boost::shared_ptr); + AudioRegion (boost::shared_ptr, 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, sigc::connection&) const; - + mutable sigc::signal PeaksReady; mutable sigc::signal PeakRangeReady; @@ -129,7 +129,7 @@ class AudioSource : public Source static vector 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); 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 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 #include + #include #include +#include + #include #include @@ -51,7 +54,7 @@ struct ControlEvent { }; -class AutomationList : public StateManager, public Stateful + class AutomationList : public StateManager, public PBD::StatefulDestructible { public: typedef std::list 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 #include +#include #include #include +#include #include #include @@ -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 in, boost::shared_ptr 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 in, boost::shared_ptr 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, boost::shared_ptr); /* 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 in() const { return _in; } + boost::shared_ptr 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 == ®ion || _out == ®ion; + bool involves (boost::shared_ptr 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 a, boost::shared_ptr 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 Invalidated; - sigc::signal 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 _in; + boost::shared_ptr _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, boost::shared_ptr, 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 #include #include -#include +#include #include #include @@ -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& last_capture_regions () { return _last_capture_regions; } + std::list >& last_capture_regions () { return _last_capture_regions; } void handle_input_change (IOChange, void *src); @@ -147,7 +147,7 @@ class IO; static sigc::signal DiskOverrun; static sigc::signal DiskUnderrun; - static sigc::signal*> DeleteSources; + static sigc::signal >*> DeleteSources; protected: friend class Session; @@ -224,7 +224,7 @@ class IO; virtual bool realtime_set_speed (double, bool global_change); - std::list _last_capture_regions; + std::list > _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 #include -#include +#include #include #include @@ -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 #include +#include #include #include @@ -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 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 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 _write_source; RingBufferNPT* _capture_transition_buf; //RingBufferNPT::rw_vector _playback_vector; //RingBufferNPT::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&); - void get_region_list_equivalent_regions (const MidiRegion&, std::vector&); + bool destroy_region (boost::shared_ptr); 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 original, boost::shared_ptr left, boost::shared_ptr right); + + void check_dependents (boost::shared_ptr region, bool norefresh); + void refresh_dependents (boost::shared_ptr region); + void remove_dependents (boost::shared_ptr 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); }; } /* 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 midi_source (uint32_t n=0) const; jack_nframes_t read_at (MidiRingBuffer& dst, jack_nframes_t position, @@ -76,6 +69,17 @@ class MidiRegion : public Region UndoAction get_memento() const; + private: + friend class RegionFactory; + + MidiRegion (boost::shared_ptr, jack_nframes_t start, jack_nframes_t length); + MidiRegion (boost::shared_ptr, 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, jack_nframes_t start, jack_nframes_t length, const string& name, layer_t = 0, Region::Flag flags = Region::DefaultFlags); + MidiRegion (boost::shared_ptr); + MidiRegion (boost::shared_ptr, const XMLNode&); + MidiRegion (SourceList &, const XMLNode&); + private: friend class Playlist; 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 #include #include +#include #include @@ -34,6 +35,7 @@ #include #include +#include #include #include @@ -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 RegionList; + typedef list > 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&); - void get_region_list_equivalent_regions (const Region&, std::vector&); - 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, jack_nframes_t position, float times = 1, bool with_save = true); + void remove_region (boost::shared_ptr); + void get_equivalent_regions (boost::shared_ptr, std::vector >&); + void get_region_list_equivalent_regions (boost::shared_ptr, std::vector >&); + void replace_region (boost::shared_ptr old, boost::shared_ptr newr, jack_nframes_t pos); + void split_region (boost::shared_ptr, 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, 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 find_region (const PBD::ID&) const; Playlist* cut (list&, bool result_is_hidden = true); Playlist* copy (list&, 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 top_region_at (jack_nframes_t frame); - Region* find_next_region (jack_nframes_t frame, RegionPoint point, int dir); + boost::shared_ptr find_next_region (jack_nframes_t frame, RegionPoint point, int dir); - template void foreach_region (T *t, void (T::*func)(Region *, void *), void *arg); - template void foreach_region (T *t, void (T::*func)(Region *)); + template void foreach_region (T *t, void (T::*func)(boost::shared_ptr, void *), void *arg); + template void foreach_region (T *t, void (T::*func)(boost::shared_ptr)); XMLNode& get_state (); int set_state (const XMLNode&); XMLNode& get_template (); - sigc::signal RegionAdded; - sigc::signal RegionRemoved; + sigc::signal > RegionAdded; + sigc::signal > RegionRemoved; sigc::signal InUse; sigc::signal Modified; sigc::signal NameChanged; sigc::signal LengthChanged; sigc::signal LayeringChanged; - sigc::signal GoingAway; sigc::signal StatePushed; static sigc::signal 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); + void lower_region (boost::shared_ptr); + void raise_region_to_top (boost::shared_ptr); + void lower_region_to_bottom (boost::shared_ptr); 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) = 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); + void notify_region_added (boost::shared_ptr); 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); + virtual bool region_changed (Change, boost::shared_ptr); - void region_bounds_changed (Change, Region *); - void region_deleted (Region *); + void region_bounds_changed (Change, boost::shared_ptr); + void region_deleted (boost::shared_ptr); 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 original, boost::shared_ptr left, boost::shared_ptr 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, bool norefresh) {} + virtual void refresh_dependents (boost::shared_ptr region) {} + virtual void remove_dependents (boost::shared_ptr 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, jack_nframes_t position, bool delay_sort = false); - int remove_region_internal (Region *, bool delay_sort = false); + int remove_region_internal (boost::shared_ptr, 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 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); 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 void AudioPlaylist::foreach_crossfade (T *t, void (T::*func)(C } } -template void Playlist::foreach_region (T *t, void (T::*func)(Region *, void *), void *arg) { +template void Playlist::foreach_region (T *t, void (T::*func)(boost::shared_ptr, void *), void *arg) { RegionLock rlock (this, false); for (RegionList::iterator i = regions.begin(); i != regions.end(); i++) { (t->*func) ((*i), arg); } } -template void Playlist::foreach_region (T *t, void (T::*func)(Region *)) { +template void Playlist::foreach_region (T *t, void (T::*func)(boost::shared_ptr)) { 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 #include -#include +#include #include #include @@ -78,8 +78,7 @@ class PluginInfo { typedef boost::shared_ptr PluginInfoPtr; typedef std::list 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 ParameterChanged; - sigc::signal 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 placement_changed; sigc::signal AutomationPlaybackChanged; sigc::signal AutomationChanged; - sigc::signal GoingAway; static sigc::signal 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 +#include #include +#include #include #include @@ -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 SourceList; + typedef std::vector > 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; + bool size_equivalent (boost::shared_ptr) const; + bool overlap_equivalent (boost::shared_ptr) const; + bool region_list_equivalent (boost::shared_ptr) const; + bool source_equivalent (boost::shared_ptr) 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 (uint32_t n=0) const { return *_sources[ (n < _sources.size()) ? n : 0 ]; } - uint32_t n_channels() const { return _sources.size(); } + boost::shared_ptr source (uint32_t n=0) const { return _sources[ (n < _sources.size()) ? n : 0 ]; } + uint32_t n_channels() const { return _sources.size(); } std::vector master_source_names(); @@ -210,23 +201,23 @@ class Region : public Stateful, public StateManager virtual XMLNode& state (bool); virtual int set_state (const XMLNode&); - sigc::signal 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 CheckNewRegion; - - Region* get_parent(); + boost::shared_ptr 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 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, jack_nframes_t start, jack_nframes_t length, const string& name, layer_t = 0, Flag flags = DefaultFlags); + Region (boost::shared_ptr); + Region (boost::shared_ptr src, const XMLNode&); + Region (SourceList& srcs, const XMLNode&); + protected: XMLNode& get_short_state (); /* used only by Session */ 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 > CheckNewRegion; + + static boost::shared_ptr create (boost::shared_ptr, 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 create (boost::shared_ptr, 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 create (boost::shared_ptr, 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 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 create (boost::shared_ptr); + static boost::shared_ptr create (Session&, XMLNode&, bool); + static boost::shared_ptr 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); }; } /* 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 #include #include + +#include + #include #include @@ -37,11 +40,13 @@ #include #include #include +#include #include #include #include +#include #include #include @@ -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,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; + list audio_range; list 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 going_away; - /* Proxy signal for region hidden changes */ - sigc::signal RegionHiddenChange; + sigc::signal > 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); 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 RegionAdded; - sigc::signal RegionRemoved; + sigc::signal > RegionAdded; + sigc::signal > 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& result); + boost::shared_ptr find_whole_file_parent (Region&); + void find_equivalent_playlist_regions (boost::shared_ptr, std::vector >& result); - Region* XMLRegionFactory (const XMLNode&, bool full); - AudioRegion* XMLAudioRegionFactory (const XMLNode&, bool full); - MidiRegion* XMLMidiRegionFactory (const XMLNode&, bool full); + boost::shared_ptr XMLRegionFactory (const XMLNode&, bool full); + boost::shared_ptr XMLAudioRegionFactory (const XMLNode&, bool full); + boost::shared_ptr XMLMidiRegionFactory (const XMLNode&, bool full); - template void foreach_region (T *obj, void (T::*func)(Region *)); + template void foreach_region (T *obj, void (T::*func)(boost::shared_ptr)); /* source management */ @@ -661,8 +664,7 @@ class Session : public sigc::trackable, public Stateful string pathname; /* result */ - std::vector new_regions; - + std::vector > 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); + void remove_source (boost::weak_ptr); + int cleanup_audio_file_source (boost::shared_ptr); struct cleanup_report { vector 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); + int destroy_region (boost::shared_ptr); + int destroy_regions (std::list >); int remove_last_capture (); @@ -706,14 +708,14 @@ class Session : public sigc::trackable, public Stateful static sigc::signal AskAboutPendingState; - sigc::signal SourceAdded; - sigc::signal SourceRemoved; + sigc::signal > SourceAdded; + sigc::signal > SourceRemoved; - AudioFileSource *create_audio_source_for_session (ARDOUR::AudioDiskstream&, uint32_t which_channel, bool destructive); + boost::shared_ptr create_audio_source_for_session (ARDOUR::AudioDiskstream&, uint32_t which_channel, bool destructive); - MidiSource *create_midi_source_for_session (ARDOUR::MidiDiskstream&); + boost::shared_ptr create_midi_source_for_session (ARDOUR::MidiDiskstream&); - Source *source_by_id (const PBD::ID&); + boost::shared_ptr source_by_id (const PBD::ID&); /* playlist management */ @@ -750,7 +752,7 @@ class Session : public sigc::trackable, public Stateful boost::shared_ptr the_auditioner() { return auditioner; } void audition_playlist (); - void audition_region (Region&); + void audition_region (boost::shared_ptr); 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&, InterThreadInfo& wot); + int write_one_audio_track (AudioTrack&, jack_nframes_t start, jack_nframes_t cnt, bool overwrite, vector >&, + 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 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 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 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 RegionList; + typedef map > 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); + void region_changed (Change, boost::shared_ptr); + void add_region (boost::shared_ptr); + void remove_region (boost::shared_ptr); int load_regions (const XMLNode& node); /* SOURCES */ mutable Glib::Mutex source_lock; - typedef std::map SourceList; + typedef std::map > SourceMap; - SourceList sources; + SourceMap sources; int load_sources (const XMLNode& node); XMLNode& get_sources_as_xml (); - Source *XMLSourceFactory (const XMLNode&); + boost::shared_ptr 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 curves; - std::map automation_lists; + /* CURVES and AUTOMATION LISTS */ + std::map curves; + std::map automation_lists; /* DEFAULT FADE CURVES */ @@ -1621,9 +1627,9 @@ class Session : public sigc::trackable, public Stateful /* AUDITIONING */ boost::shared_ptr auditioner; - void set_audition (AudioRegion*); + void set_audition (boost::shared_ptr); void non_realtime_set_audition (); - AudioRegion *pending_audition_region; + boost::shared_ptr 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 void Session::foreach_region (T *obj, void (T::*func)(Region *)) +template void Session::foreach_region (T *obj, void (T::*func)(boost::shared_ptr)) { Glib::Mutex::Lock lm (region_lock); for (RegionList::iterator i = regions.begin(); i != regions.end(); i++) { @@ -14,6 +14,6 @@ template 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 #include +#include -#include +#include #include #include namespace ARDOUR { -class Source : public Stateful, public sigc::trackable +class Source : public PBD::StatefulDestructible, public sigc::trackable, public boost::enable_shared_from_this { 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 SourceCreated; - sigc::signal 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 +#include +#include +#include + +#include +#include + +class XMLNode; + +namespace ARDOUR { + +class SourceFactory { + public: + static sigc::signal > SourceCreated; + + static boost::shared_ptr create (const XMLNode& node); + + static boost::shared_ptr createReadable (DataType type, std::string idstr, AudioFileSource::Flag flags, bool announce = true); + static boost::shared_ptr 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 #include #include + #include #include +#include + #include #include @@ -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 +#include +#include #include #include @@ -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 > 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 #include #include +#include #include #include #include #include +#include #include "i18n.h" #include @@ -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 (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 (rl->front()); + boost::shared_ptr region = boost::dynamic_pointer_cast (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(®ion->source (n)); + (*chan).write_source = boost::dynamic_pointer_cast(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 region; jack_nframes_t total_capture; - AudioRegion::SourceList srcs; - AudioRegion::SourceList::iterator src; + SourceList srcs; + SourceList::iterator src; ChannelList::iterator chan; vector::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* deletion_list = new list; + list >* deletion_list = new list >; 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 s = (*chan).write_source; if (s) { - - AudioFileSource* fsrc; - srcs.push_back (s); - - if ((fsrc = dynamic_cast(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 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 (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 rx (RegionFactory::create (srcs, buffer_position, (*ci)->frames, region_name)); + region = boost::dynamic_pointer_cast (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::iterator i = capturing_sources.begin(); i != capturing_sources.end(); ++i) { + for (vector >::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 fs; + boost::shared_ptr 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 (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 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 (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 (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::const_iterator in_o = other.regions.begin(); - list::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( (*in_o) ); + boost::shared_ptr ar = boost::dynamic_pointer_cast(*in_o); // We look only for crossfades which begin with the current region, so we don't get doubles for (list::const_iterator xfades = other._crossfades.begin(); xfades != other._crossfades.end(); ++xfades) { - if ( &(*xfades)->in() == ar) { + if ((*xfades)->in() == ar) { // We found one! Now copy it! - list::const_iterator out_o = other.regions.begin(); - list::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( (*out_o) ); + boost::shared_ptrar2 = boost::dynamic_pointer_cast(*out_o); - if ( &(*xfades)->out() == ar2) { - AudioRegion *in = dynamic_cast( (*in_n) ); - AudioRegion *out = dynamic_cast( (*out_n) ); - Crossfade *new_fade = new Crossfade( *(*xfades), in, out); + if ((*xfades)->out() == ar2) { + boost::shared_ptrin = boost::dynamic_pointer_cast(*in_n); + boost::shared_ptrout = boost::dynamic_pointer_cast(*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 all_xfades; - set 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 (*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::iterator ar = all_regions.begin(); ar != all_regions.end(); ++ar) { - (*ar)->unlock_sources (); - delete *ar; - } - /* delete every crossfade */ for (set::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 a, boost::shared_ptr 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 > relevant_regions; + map > > relevant_regions; map > relevant_xfades; vector relevant_layers; @@ -246,12 +231,11 @@ AudioPlaylist::read (Sample *buf, Sample *mixdown_buffer, float *gain_buffer, ja for (vector::iterator l = relevant_layers.begin(); l != relevant_layers.end(); ++l) { - // FIXME: Should be vector - vector& r (relevant_regions[*l]); + vector > r (relevant_regions[*l]); vector& x (relevant_xfades[*l]); - for (vector::iterator i = r.begin(); i != r.end(); ++i) { - AudioRegion* const ar = dynamic_cast(*i); + for (vector >::iterator i = r.begin(); i != r.end(); ++i) { + boost::shared_ptr ar = boost::dynamic_pointer_cast(*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) { Crossfades::iterator i, tmp; - AudioRegion* r = dynamic_cast (®ion); + boost::shared_ptr r = boost::dynamic_pointer_cast (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 r) { - AudioRegion* ar = dynamic_cast(&r); + boost::shared_ptr ar = boost::dynamic_pointer_cast(r); set 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 o, boost::shared_ptr l, boost::shared_ptr r) { - AudioRegion *orig = dynamic_cast(o); - AudioRegion *left = dynamic_cast(l); - AudioRegion *right = dynamic_cast(r); + boost::shared_ptr orig = boost::dynamic_pointer_cast(o); + boost::shared_ptr left = boost::dynamic_pointer_cast(l); + boost::shared_ptr right = boost::dynamic_pointer_cast(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 r, bool norefresh) { - AudioRegion* other; - AudioRegion* region; - AudioRegion* top; - AudioRegion* bottom; + boost::shared_ptr other; + boost::shared_ptr region; + boost::shared_ptr top; + boost::shared_ptr bottom; Crossfade* xfade; if (in_set_state || in_partition) { return; } - if ((region = dynamic_cast (&r)) == 0) { + if ((region = boost::dynamic_pointer_cast (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 (*i); + other = boost::dynamic_pointer_cast (*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 all_xfades; - set all_regions; + set > 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::iterator i = regions.begin(); i != regions.end(); ++i) { - set::iterator x = all_regions.find (*i); + for (RegionList::iterator i = regions.begin(); i != regions.end(); ++i) { + set >::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::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::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_ptrr; 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) { - AudioRegion* r = dynamic_cast (region); + boost::shared_ptr r = boost::dynamic_pointer_cast (region); bool changed = false; Crossfades::iterator c, ctmp; set 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) { 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 #include #include +#include #include #include #include @@ -719,7 +720,7 @@ AudioTrack::export_stuff (BufferSet& buffers, jack_nframes_t start, jack_nframes void AudioTrack::bounce (InterThreadInfo& itt) { - vector srcs; + vector > 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 srcs; + vector > srcs; _session.write_one_audio_track (*this, start, end, false, srcs, itt); } void AudioTrack::freeze (InterThreadInfo& itt) { - vector srcs; + vector > srcs; string new_playlist_name; Playlist* new_playlist; string dir; - AudioRegion* region; string region_name; boost::shared_ptr 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 (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(arg)->GraphReordered (); /* EMIT SIGNAL */ + static_cast(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 #include #include +#include // 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 afs = boost::dynamic_pointer_cast ( + 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 #include #include +#include +#include #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 region, SourceList& nsrcs) { - vector names = region.master_source_names(); + vector 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 ( + 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 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(*si); + for (SourceList::iterator si = nsrcs.begin(); si != nsrcs.end(); ++si) { + boost::shared_ptr afs = boost::dynamic_pointer_cast(*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 (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 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 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 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 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 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 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& v) con int AudioRegion::apply (AudioFilter& filter) { - return filter.run (*this); + return filter.run (boost::shared_ptr (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 AudioRegion::audio_source (uint32_t n) const { // Guaranteed to succeed (use a static cast?) - return dynamic_cast(source(n)); + return boost::dynamic_pointer_cast(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 #include #include +#include #include #include @@ -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 +#include + #include #include #include @@ -28,9 +30,13 @@ #include #include #include +#include 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(_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) { 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(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 the_region (boost::dynamic_pointer_cast (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 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::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 in, boost::shared_ptr 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 = ∈ - _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 a, boost::shared_ptr 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 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 (r)) == 0) { + if ((_in = boost::dynamic_pointer_cast (r)) == 0) { throw failed_constructor(); } @@ -146,7 +146,7 @@ Crossfade::Crossfade (const Playlist& playlist, XMLNode& node) throw failed_constructor(); } - if ((_out = dynamic_cast (r)) == 0) { + if ((_out = boost::dynamic_pointer_cast (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 newin, boost::shared_ptr 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 a, boost::shared_ptr b, CrossfadeModel model) { - AudioRegion* top; - AudioRegion* bottom; + boost::shared_ptr top; + boost::shared_ptr 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 #include +#include + #include #include #include @@ -63,7 +65,7 @@ using namespace PBD; */ jack_nframes_t Diskstream::disk_io_chunk_frames = 1024 * 256; -sigc::signal*> Diskstream::DeleteSources; +sigc::signal >*> Diskstream::DeleteSources; sigc::signal Diskstream::DiskOverrun; sigc::signal 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 #include +#include #include #include #include #include #include +#include +#include + #include "i18n.h" @@ -52,8 +56,8 @@ int Session::import_audiofile (import_status& status) { SNDFILE *in; - AudioFileSource **newfiles = 0; - AudioRegion::SourceList sources; + vector > 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()); } - + 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 ( + 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 r (boost::dynamic_pointer_cast (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 + (RegionFactory::create (boost::static_pointer_cast (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::iterator i = status.new_regions.begin(); i != status.new_regions.end(); ++i) { - delete *i; - } + status.new_regions.clear (); for (vector::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::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 #include #include +#include #include #include #include @@ -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 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* deletion_list = new list; + list >* deletion_list = new list >; 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 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 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 (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 rx (RegionFactory::create (srcs, buffer_position, (*ci)->frames, region_name)); + region = boost::dynamic_pointer_cast (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(_session.create_midi_source_for_session (*this)); + _write_source = boost::dynamic_pointer_cast(_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 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 (*i); - - for (RegionList::iterator r = apstate->regions.begin(); r != apstate->regions.end(); ++r) { - all_regions.insert (*r); - } - delete apstate; } - - /* delete every region */ - - for (set::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 a, boost::shared_ptr 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 regs; // relevent regions overlapping start <--> end + // relevent regions overlapping start <--> end + vector > regs; for (RegionList::iterator i = regions.begin(); i != regions.end(); ++i) { - MidiRegion* const mr = dynamic_cast(*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::iterator i = regs.begin(); i != regs.end(); ++i) { + for (vector >::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 mr = boost::dynamic_pointer_cast(*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) { - MidiRegion* r = dynamic_cast (®ion); - - 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 r) { - MidiRegion* ar = dynamic_cast(&r); - - if (ar == 0) { - return; - } } void -MidiPlaylist::finalize_split_region (Region *o, Region *l, Region *r) +MidiPlaylist::finalize_split_region (boost::shared_ptr original, boost::shared_ptr left, boost::shared_ptr 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 r, bool norefresh) { - MidiRegion* other; - MidiRegion* region; - MidiRegion* top; - MidiRegion* bottom; - - if (in_set_state || in_partition) { - return; - } - - if ((region = dynamic_cast (&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 (*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 all_regions; + set > 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 (*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::iterator i = regions.begin(); i != regions.end(); ++i) { - set - ::iterator x = all_regions.find (*i); + for (RegionList::iterator i = regions.begin(); i != regions.end(); ++i) { + set >::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::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 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) { - MidiRegion* r = dynamic_cast (region); + boost::shared_ptr r = boost::dynamic_pointer_cast (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& results) -{ - for (RegionList::iterator i = regions.begin(); i != regions.end(); ++i) { - - MidiRegion* ar = dynamic_cast (*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& results) -{ - for (RegionList::iterator i = regions.begin(); i != regions.end(); ++i) { - - MidiRegion* ar = dynamic_cast (*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) { 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 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 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 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 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 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 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& v) const return -1; } -MidiSource& +boost::shared_ptr MidiRegion::midi_source (uint32_t n) const { // Guaranteed to succeed (use a static cast?) - return dynamic_cast(source(n)); + return boost::dynamic_pointer_cast(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 a, boost::shared_ptr b) { return a->layer() < b->layer(); } }; struct RegionSortByPosition { - bool operator() (Region *a, Region *b) { + bool operator() (boost::shared_ptr a, boost::shared_ptr b) { return a->position() < b->position(); } }; struct RegionSortByLastLayerOp { - bool operator() (Region *a, Region *b) { + bool operator() (boost::shared_ptr a, boost::shared_ptr 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::iterator x = tmp.begin(); x != tmp.end(); ++x) { + for (list >::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; + boost::shared_ptr 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 (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 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 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 dependent_checks_needed; + set > 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::iterator x = dependent_checks_needed.begin(); x != dependent_checks_needed.end(); ++x) { - check_dependents (**x, false); + for (set >::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, 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(®ion), 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 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 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, 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 old, boost::shared_ptr 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) { 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_ptrregion, 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& results) +Playlist::get_equivalent_regions (boost::shared_ptr other, vector >& 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& results) } void -Playlist::get_region_list_equivalent_regions (const Region& other, vector& results) +Playlist::get_region_list_equivalent_regions (boost::shared_ptr other, vector >& 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; + boost::shared_ptr 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 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, 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 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 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, 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 left; + boost::shared_ptr 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 (®ion, left, right); + finalize_split_region (region, left, right); - if (remove_region_internal (®ion, 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) { 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) { /* 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) { 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 Playlist::top_region_at (jack_nframes_t frame) { RegionLock rlock (this); RegionList *rlist = find_regions_at (frame); - Region *region = 0; - + boost::shared_ptr 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 Playlist::find_next_region (jack_nframes_t frame, RegionPoint point, int dir) { RegionLock rlock (this); - Region* ret = 0; + boost::shared_ptr 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 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; 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) { 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) { - 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) { /* 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) { /* 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, int dir) { RegionList::iterator i; - typedef pair LayerInfo; + typedef pair,layer_t> LayerInfo; list 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 (®ion == *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::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 Playlist::find_region (const ID& id) const { RegionLock rlock (const_cast (this)); RegionList::const_iterator i; - + boost::shared_ptr 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 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) { // 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 -#include - #include #include -#include -#include -#include - #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(®ion)) != 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(®ion)) != 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 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 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 unique_srcs; + set > 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 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 unique_srcs; + set > 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 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 unique_srcs; + set > 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 unique_srcs; + _current_state_id = 0; + + set > 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 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(this)); } } @@ -406,7 +411,7 @@ Region::move_to_natural_position (void *src) return; } - Region* whole_file_region = get_parent(); + boost::shared_ptr 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(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(this)); } void @@ -916,7 +921,7 @@ Region::lower () return; } - _playlist->lower_region (*this); + _playlist->lower_region (boost::shared_ptr(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(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(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 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 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 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 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) { delete this; } -void -Region::lock_sources () -{ - SourceList::iterator i; - set 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 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 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 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::get_parent() { - Region* r = 0; + boost::shared_ptr 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 + +#include + +#include +#include +#include +#include +#include +#include + +#include "i18n.h" + +using namespace ARDOUR; +using namespace PBD; + +sigc::signal > RegionFactory::CheckNewRegion; + +boost::shared_ptr +RegionFactory::create (boost::shared_ptr region, jack_nframes_t start, + jack_nframes_t length, std::string name, + layer_t layer, Region::Flag flags, bool announce) +{ + boost::shared_ptr other_a; + boost::shared_ptr other_m; + + if ((other_a = boost::dynamic_pointer_cast(region)) != 0) { + AudioRegion* ar = new AudioRegion (other_a, start, length, name, layer, flags); + boost::shared_ptr arp (ar); + boost::shared_ptr ret (boost::static_pointer_cast (arp)); + if (announce) { + CheckNewRegion (ret); + } + return ret; + } else if ((other_m = boost::dynamic_pointer_cast(region)) != 0) { + MidiRegion* ar = new MidiRegion (other_m, start, length, name, layer, flags); + boost::shared_ptr arp (ar); + boost::shared_ptr ret (boost::static_pointer_cast (arp)); + if (announce) { + CheckNewRegion (ret); + } + return ret; + } else { + fatal << _("programming error: RegionFactory::create() called with unknown Region type") + << endmsg; + /*NOTREACHED*/ + return boost::shared_ptr(); + } +} + +boost::shared_ptr +RegionFactory::create (boost::shared_ptr region) +{ + boost::shared_ptr ar; + boost::shared_ptr mr; + + if ((ar = boost::dynamic_pointer_cast(region)) != 0) { + boost::shared_ptr ret (new AudioRegion (ar)); + /* pure copy constructor - no CheckNewRegion emitted */ + return ret; + } else if ((mr = boost::dynamic_pointer_cast(region)) != 0) { + boost::shared_ptr 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(); + } +} + +boost::shared_ptr +RegionFactory::create (boost::shared_ptr 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), start, length, name, layer, flags, announce); +} + +boost::shared_ptr +RegionFactory::create (Session& session, XMLNode& node, bool yn) +{ + boost::shared_ptr r = session.XMLRegionFactory (node, yn); + CheckNewRegion (r); + return r; +} + +boost::shared_ptr +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(); + } + + if (srcs[0]->type() == DataType::AUDIO) { + + AudioRegion* ar = new AudioRegion (srcs, start, length, name, layer, flags); + boost::shared_ptr arp (ar); + boost::shared_ptr ret (boost::static_pointer_cast (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 mrp (ar); + boost::shared_ptr ret (boost::static_pointer_cast (mrp)); + if (announce) { + CheckNewRegion (ret); + } + return ret; + + } + + return boost::shared_ptr (); +} + +boost::shared_ptr +RegionFactory::create (SourceList& srcs, const XMLNode& node) +{ + if (srcs.empty()) { + return boost::shared_ptr(); + } + + if (srcs[0]->type() == DataType::AUDIO) { + boost::shared_ptr ret (new AudioRegion (srcs, node)); + CheckNewRegion (ret); + return ret; + } else if (srcs[0]->type() == DataType::MIDI) { + boost::shared_ptr ret (new MidiRegion (srcs, node)); + CheckNewRegion (ret); + return ret; + } + + return boost::shared_ptr (); +} + +boost::shared_ptr +RegionFactory::create (boost::shared_ptr src, jack_nframes_t start, jack_nframes_t length, const string& name, layer_t layer, Region::Flag flags, bool announce) +{ + boost::shared_ptr as; + boost::shared_ptr ms; + + if ((as = boost::dynamic_pointer_cast(src)) != 0) { + boost::shared_ptr ret (new AudioRegion (as, start, length, name, layer, flags)); + if (announce) { + CheckNewRegion (ret); + } + return ret; + } else if ((ms = boost::dynamic_pointer_cast(src)) != 0) { + boost::shared_ptr ret (new MidiRegion (ms, start, length, name, layer, flags)); + if (announce) { + CheckNewRegion (ret); + } + return ret; + } + + return boost::shared_ptr(); +} 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 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(*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 asrc(boost::dynamic_pointer_cast(*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 asrc(boost::dynamic_pointer_cast(*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 #include #include +#include #ifdef HAVE_LIBLO #include @@ -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 writer (routes); boost::shared_ptr 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 dwriter (diskstreams); boost::shared_ptr 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) { + boost::shared_ptr 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 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) { 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) { add_region (region); } void -Session::remove_region (Region* region) +Session::remove_region (boost::shared_ptr 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 Session::find_whole_file_parent (Region& child) { RegionList::iterator i; - Region* region; + boost::shared_ptr 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*) 0); } void -Session::find_equivalent_playlist_regions (Region& region, vector& result) +Session::find_equivalent_playlist_regions (boost::shared_ptr region, vector >& 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) { - AudioRegion* aregion; + boost::shared_ptr aregion; - if ((aregion = dynamic_cast (region)) == 0) { + if ((aregion = boost::dynamic_pointer_cast (region)) == 0) { return 0; } - + if (aregion->playlist()) { aregion->playlist()->destroy_region (region); } - vector srcs; + vector > 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::iterator i = srcs.begin(); i != srcs.end(); ++i) { + for (vector >::iterator i = srcs.begin(); i != srcs.end(); ++i) { - if ((*i)->use_cnt() == 0) { - AudioFileSource* afs = dynamic_cast(*i); + if ((*i).use_count() == 1) { + boost::shared_ptr afs = boost::dynamic_pointer_cast(*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 regions) +Session::destroy_regions (list > regions) { - for (list::iterator i = regions.begin(); i != regions.end(); ++i) { + for (list >::iterator i = regions.begin(); i != regions.end(); ++i) { destroy_region (*i); } return 0; @@ -2875,12 +2881,12 @@ Session::destroy_regions (list regions) int Session::remove_last_capture () { - list r; + list > r; boost::shared_ptr dsl = diskstreams.reader(); for (DiskstreamList::iterator i = dsl->begin(); i != dsl->end(); ++i) { - list& l = (*i)->last_capture_regions(); + list >& 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 r) { - remove_region (&r); + remove_region (r); return 0; } /* Source Management */ void -Session::add_source (Source* source) +Session::add_source (boost::shared_ptr source) { - pair entry; + cerr << "add new source " << source->name() << endl; + + pair entry; + pair 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))); set_dirty(); SourceAdded (source); /* EMIT SIGNAL */ } void -Session::remove_source (Source* source) +Session::remove_source (boost::weak_ptr src) { - SourceList::iterator i; + SourceMap::iterator i; + boost::shared_ptr 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 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; 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 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 (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 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 (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,50 +3397,47 @@ Session::remove_playlist (Playlist* playlist) } void -Session::set_audition (AudioRegion* r) +Session::set_audition (boost::shared_ptr r) { pending_audition_region = r; post_transport_work = PostTransportWork (post_transport_work | PostTransportAudition); schedule_butler_transport_work (); } +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 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(&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 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& srcs, InterThreadInfo& itt) + bool overwrite, vector >& srcs, InterThreadInfo& itt) { + boost::shared_ptr 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 (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::iterator src=srcs.begin(); src != srcs.end(); ++src, ++n) { - AudioFileSource* afs = dynamic_cast(*src); - + for (vector >::iterator src=srcs.begin(); src != srcs.end(); ++src, ++n) { + boost::shared_ptr afs = boost::dynamic_pointer_cast(*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::iterator src=srcs.begin(); src != srcs.end(); ++src) { - AudioFileSource* afs = dynamic_cast(*src); + for (vector >::iterator src=srcs.begin(); src != srcs.end(); ++src) { + boost::shared_ptr afs = boost::dynamic_pointer_cast(*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::iterator src=srcs.begin(); src != srcs.end(); ++src) { - AudioFileSource* afs = dynamic_cast(*src); + for (vector >::iterator src=srcs.begin(); src != srcs.end(); ++src) { + boost::shared_ptr afs = boost::dynamic_pointer_cast(*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::iterator src=srcs.begin(); src != srcs.end(); ++src) { - AudioFileSource* afs = dynamic_cast(*src); + for (vector >::iterator src = srcs.begin(); src != srcs.end(); ++src) { + boost::shared_ptr afs = boost::dynamic_pointer_cast(*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 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(*registry[id], before, after); + return new MementoCommand(*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 (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 #include #include +#include +#include #include "i18n.h" #include @@ -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 fs; - DestructiveFileSource* const dfs = dynamic_cast (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 (siter->second)) != 0) { + boost::shared_ptr dfs = boost::dynamic_pointer_cast (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; 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 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(XMLAudioRegionFactory (node, full)); } else if (type->value() == "midi") { - return XMLMidiRegionFactory (node, full); + return boost::shared_ptr(XMLMidiRegionFactory (node, full)); } } catch (failed_constructor& err) { - return 0; + return boost::shared_ptr (); } - return 0; + return boost::shared_ptr (); } -AudioRegion * +boost::shared_ptr Session::XMLAudioRegionFactory (const XMLNode& node, bool full) { const XMLProperty* prop; - Source* source; - AudioSource* as; - AudioRegion::SourceList sources; + boost::shared_ptr source; + boost::shared_ptr as; + SourceList sources; uint32_t nchans = 1; char buf[128]; if (node.name() != X_("Region")) { - return 0; + return boost::shared_ptr(); } 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(); } } @@ -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(); } - - as = dynamic_cast(source); + + as = boost::dynamic_pointer_cast(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(); } 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(); } - as = dynamic_cast(source); + as = boost::dynamic_pointer_cast(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(); } sources.push_back (as); } } try { - return new AudioRegion (sources, node); + boost::shared_ptr region (boost::dynamic_pointer_cast (RegionFactory::create (sources, node))); + return region; + } catch (failed_constructor& err) { - return 0; + return boost::shared_ptr(); } } -MidiRegion * +boost::shared_ptr Session::XMLMidiRegionFactory (const XMLNode& node, bool full) { const XMLProperty* prop; - Source* source; - MidiSource* ms; + boost::shared_ptr source; + boost::shared_ptr ms; MidiRegion::SourceList sources; uint32_t nchans = 1; if (node.name() != X_("Region")) { - return 0; + return boost::shared_ptr(); } 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(); } } @@ -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(); } - ms = dynamic_cast(source); + ms = boost::dynamic_pointer_cast(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(); } sources.push_back (ms); try { - return new MidiRegion (sources, node); + boost::shared_ptr region (boost::dynamic_pointer_cast (RegionFactory::create (sources, node))); + return region; } catch (failed_constructor& err) { - return 0; + return boost::shared_ptr(); } } @@ -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; nlist = node.children(); @@ -1995,41 +2006,22 @@ Session::load_sources (const XMLNode& node) return 0; } -Source * +boost::shared_ptr 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(); } 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(); } - - 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& result, bool exclude_th int Session::cleanup_sources (Session::cleanup_report& rep) { - vector dead_sources; + vector > dead_sources; vector 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::iterator i = dead_sources.begin(); i != dead_sources.end();++i) { + for (vector >::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 reg = r->second; for (uint32_t n = 0; n < reg->n_channels(); ++n) { - if (®->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 fs; - if ((fs = dynamic_cast (i->second)) != 0) { + if ((fs = boost::dynamic_pointer_cast (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 #include #include +#include +#include #include "i18n.h" @@ -36,12 +38,12 @@ using namespace ARDOUR; using namespace PBD; using namespace soundtouch; -AudioRegion* +boost::shared_ptr Session::tempoize_region (TimeStretchRequest& tsr) { - AudioRegion::SourceList sources; - AudioRegion::SourceList::iterator it; - AudioRegion* r = 0; + SourceList sources; + SourceList::iterator it; + boost::shared_ptr 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 ( + 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(sources[i]); + boost::shared_ptr asrc = boost::dynamic_pointer_cast(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(*it); + boost::shared_ptr afs = boost::dynamic_pointer_cast(*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 (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& @@ -121,18 +120,6 @@ Source::set_state (const XMLNode& node) return 0; } -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) { 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 +#include +#include +#include +#include + +#include "i18n.h" + +using namespace ARDOUR; +using namespace std; + +sigc::signal > SourceFactory::SourceCreated; + +#ifdef HAVE_COREAUDIO + + +boost::shared_ptr +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 ret (new DestructiveFileSource (node)); + SourceCreated (ret); + return ret; + + } else { + + try { + boost::shared_ptr ret (new CoreAudioSource (node)); + SourceCreated (ret); + return ret; + } + + + catch (failed_constructor& err) { + boost::shared_ptr ret (new SndFileSource (node)); + SourceCreated (ret); + return ret; + } + } + + } else if (type == DataType::MIDI) { + + boost::shared_ptr ret (new SMFSource (node)); + SourceCreated (ret); + return ret; + + } + + return boost::shared_ptr(); +} + +#else + +boost::shared_ptr +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 ret (new DestructiveFileSource (node)); + SourceCreated (ret); + return ret; + + } else { + + boost::shared_ptr ret (new SndFileSource (node)); + SourceCreated (ret); + return ret; + } + + } else if (type == DataType::MIDI) { + + boost::shared_ptr ret (new SMFSource (node)); + SourceCreated (ret); + return ret; + + } + + return boost::shared_ptr (); +} + +#endif // HAVE_COREAUDIO + +#ifdef HAVE_COREAUDIO +boost::shared_ptr +SourceFactory::createReadable (string idstr, AudioFileSource::Flag flags, bool announce) +{ + if (type == DataType::AUDIO) { + if (flags & Destructive) { + boost::shared_ptr ret (new DestructiveFileSource (idstr, flags)); + if (announce) { + SourceCreated (ret); + } + return ret; + } + + try { + boost::shared_ptr ret (new CoreAudioSource (idstr, flags)); + if (announce) { + SourceCreated (ret); + } + return ret; + } + + catch (failed_constructor& err) { + boost::shared_ptr ret (new SndFileSource (idstr, flags)); + if (announce) { + SourceCreated (ret); + } + return ret; + } + } else if (type == DataType::MIDI) { + + boost::shared_ptr ret (new SMFSource (node)); + SourceCreated (ret); + return ret; + + } + + return boost::shared_ptr(); +} + +#else + +boost::shared_ptr +SourceFactory::createReadable (DataType type, string idstr, AudioFileSource::Flag flags, bool announce) +{ + if (type == DataType::AUDIO) { + boost::shared_ptr ret (new SndFileSource (idstr, flags)); + if (announce) { + SourceCreated (ret); + } + return ret; + + } else if (type == DataType::MIDI) { + + boost::shared_ptr ret (new SMFSource (idstr, SMFSource::Flag(0))); // FIXME: flags? + SourceCreated (ret); + return ret; + + } + + return boost::shared_ptr (); +} + +#endif // HAVE_COREAUDIO + +boost::shared_ptr +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 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 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 ret (new SMFSource (path)); + SourceCreated (ret); + return ret; + + } + + return boost::shared_ptr (); +} 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); } -- cgit v1.2.3