From 8277d134b9733aee344782891c99f07114384d9e Mon Sep 17 00:00:00 2001 From: David Robillard Date: Fri, 28 Jul 2006 01:08:57 +0000 Subject: Merged with trunk R708 git-svn-id: svn://localhost/ardour2/branches/midi@712 d708f5d6-7413-0410-9779-e7cbd77b26cf --- libs/ardour/ardour/ardour.h | 2 +- libs/ardour/ardour/audio_diskstream.h | 2 +- libs/ardour/ardour/audio_library.h | 2 + libs/ardour/ardour/audio_track.h | 5 +- libs/ardour/ardour/audioengine.h | 2 +- libs/ardour/ardour/audiofilesource.h | 5 +- libs/ardour/ardour/audioregion.h | 3 +- libs/ardour/ardour/configuration.h | 2 +- libs/ardour/ardour/curve.h | 2 +- libs/ardour/ardour/destructive_filesource.h | 3 + libs/ardour/ardour/export.h | 2 +- libs/ardour/ardour/insert.h | 14 +- libs/ardour/ardour/io.h | 2 +- libs/ardour/ardour/location.h | 2 +- libs/ardour/ardour/logcurve.h | 2 +- libs/ardour/ardour/panner.h | 2 +- libs/ardour/ardour/plugin.h | 3 +- libs/ardour/ardour/plugin_manager.h | 4 +- libs/ardour/ardour/port.h | 2 +- libs/ardour/ardour/redirect.h | 5 +- libs/ardour/ardour/route.h | 26 ++- libs/ardour/ardour/route_group.h | 2 +- libs/ardour/ardour/send.h | 2 +- libs/ardour/ardour/session.h | 84 +++---- libs/ardour/ardour/session_route.h | 33 +-- libs/ardour/ardour/sndfilesource.h | 2 +- libs/ardour/ardour/track.h | 14 +- libs/ardour/ardour/types.h | 6 +- libs/ardour/audio_library.cc | 13 +- libs/ardour/audio_track.cc | 22 +- libs/ardour/audiofilesource.cc | 4 + libs/ardour/audiosource.cc | 2 +- libs/ardour/configuration.cc | 4 + libs/ardour/destructive_filesource.cc | 18 +- libs/ardour/globals.cc | 6 +- libs/ardour/insert.cc | 56 ++--- libs/ardour/midi_track.cc | 321 +-------------------------- libs/ardour/panner.cc | 2 +- libs/ardour/plugin_manager.cc | 22 +- libs/ardour/redirect.cc | 26 +-- libs/ardour/route.cc | 110 +++++---- libs/ardour/session.cc | 332 +++++++++++++--------------- libs/ardour/session_export.cc | 5 +- libs/ardour/session_midi.cc | 6 +- libs/ardour/session_process.cc | 43 ++-- libs/ardour/session_state.cc | 75 +++---- libs/ardour/session_transport.cc | 23 +- 47 files changed, 493 insertions(+), 832 deletions(-) (limited to 'libs/ardour') diff --git a/libs/ardour/ardour/ardour.h b/libs/ardour/ardour/ardour.h index dba588702f..ba92416339 100644 --- a/libs/ardour/ardour/ardour.h +++ b/libs/ardour/ardour/ardour.h @@ -74,7 +74,7 @@ namespace ARDOUR { const char* old; }; -}; +} /* how do we make these be within the Ardour namespace? */ diff --git a/libs/ardour/ardour/audio_diskstream.h b/libs/ardour/ardour/audio_diskstream.h index 247939b378..c4a942a5d7 100644 --- a/libs/ardour/ardour/audio_diskstream.h +++ b/libs/ardour/ardour/audio_diskstream.h @@ -305,6 +305,6 @@ class AudioDiskstream : public Diskstream void disengage_record_enable (void* src); }; -}; /* namespace ARDOUR */ +} // namespace ARDOUR #endif /* __ardour_audio_diskstream_h__ */ diff --git a/libs/ardour/ardour/audio_library.h b/libs/ardour/ardour/audio_library.h index 3d4585fbd8..f5ac6da654 100644 --- a/libs/ardour/ardour/audio_library.h +++ b/libs/ardour/ardour/audio_library.h @@ -42,6 +42,8 @@ class AudioLibrary : public Stateful AudioLibrary (); ~AudioLibrary (); + static string state_node_name; + XMLNode& get_state (void); int set_state (const XMLNode&); diff --git a/libs/ardour/ardour/audio_track.h b/libs/ardour/ardour/audio_track.h index b03205dfaf..2616705918 100644 --- a/libs/ardour/ardour/audio_track.h +++ b/libs/ardour/ardour/audio_track.h @@ -81,13 +81,12 @@ class AudioTrack : public Track uint32_t n_process_buffers (); private: - int set_diskstream (AudioDiskstream&, void *); - + int set_diskstream (AudioDiskstream&, void *); int deprecated_use_diskstream_connections (); void set_state_part_two (); void set_state_part_three (); }; -} /* namespace ARDOUR*/ +} // namespace ARDOUR #endif /* __ardour_audio_track_h__ */ diff --git a/libs/ardour/ardour/audioengine.h b/libs/ardour/ardour/audioengine.h index 6f3de18473..bac1e3720a 100644 --- a/libs/ardour/ardour/audioengine.h +++ b/libs/ardour/ardour/audioengine.h @@ -244,6 +244,6 @@ class AudioEngine : public sigc::trackable mutable gint m_meter_exit; }; -}; /* namespace ARDOUR */ +} // namespace ARDOUR #endif /* __ardour_audioengine_h__ */ diff --git a/libs/ardour/ardour/audiofilesource.h b/libs/ardour/ardour/audiofilesource.h index b793ed14f0..3e0d4c45ae 100644 --- a/libs/ardour/ardour/audiofilesource.h +++ b/libs/ardour/ardour/audiofilesource.h @@ -42,7 +42,8 @@ class AudioFileSource : public AudioSource { Removable = 0x8, RemovableIfEmpty = 0x10, RemoveAtDestroy = 0x20, - NoPeakFile = 0x40 + NoPeakFile = 0x40, + Destructive = 0x80 }; virtual ~AudioFileSource (); @@ -150,7 +151,7 @@ class AudioFileSource : public AudioSource { bool writable() const { return _flags & Writable; } }; -}; /* namespace ARDOUR */ +} // namespace ARDOUR #endif /* __ardour_audiofilesource_h__ */ diff --git a/libs/ardour/ardour/audioregion.h b/libs/ardour/ardour/audioregion.h index f3d34eb262..54e2d73af0 100644 --- a/libs/ardour/ardour/audioregion.h +++ b/libs/ardour/ardour/audioregion.h @@ -123,8 +123,7 @@ class AudioRegion : public Region Fast, Slow, LogA, - LogB, - + LogB }; void set_fade_in_active (bool yn); diff --git a/libs/ardour/ardour/configuration.h b/libs/ardour/ardour/configuration.h index cc4376f781..dd689e9a2d 100644 --- a/libs/ardour/ardour/configuration.h +++ b/libs/ardour/ardour/configuration.h @@ -99,6 +99,6 @@ class Configuration : public Stateful extern Configuration *Config; extern gain_t speed_quietning; /* see comment in configuration.cc */ -}; /* namespace ARDOUR */ +} // namespace ARDOUR #endif /* __ardour_configuration_h__ */ diff --git a/libs/ardour/ardour/curve.h b/libs/ardour/ardour/curve.h index ede060e1cb..7f8a43cfe1 100644 --- a/libs/ardour/ardour/curve.h +++ b/libs/ardour/ardour/curve.h @@ -76,7 +76,7 @@ class Curve : public AutomationList }; -}; /* namespace ARDOUR */ +} // namespace ARDOUR extern "C" { void curve_get_vector_from_c (void *arg, double, double, float*, int32_t); diff --git a/libs/ardour/ardour/destructive_filesource.h b/libs/ardour/ardour/destructive_filesource.h index 947367f754..5b773898c3 100644 --- a/libs/ardour/ardour/destructive_filesource.h +++ b/libs/ardour/ardour/destructive_filesource.h @@ -34,6 +34,8 @@ class DestructiveFileSource : public SndFileSource { DestructiveFileSource (std::string path, SampleFormat samp_format, HeaderFormat hdr_format, jack_nframes_t rate, Flag flags = AudioFileSource::Flag (AudioFileSource::Writable)); + DestructiveFileSource (std::string path, Flag flags); + DestructiveFileSource (const XMLNode&); ~DestructiveFileSource (); @@ -62,6 +64,7 @@ class DestructiveFileSource : public SndFileSource { jack_nframes_t file_pos; // unit is frames Sample* xfade_buf; + void init (); jack_nframes_t crossfade (Sample* data, jack_nframes_t cnt, int dir, char * workbuf); void set_timeline_position (jack_nframes_t); }; diff --git a/libs/ardour/ardour/export.h b/libs/ardour/ardour/export.h index 9a6da1592b..075464767e 100644 --- a/libs/ardour/ardour/export.h +++ b/libs/ardour/ardour/export.h @@ -83,6 +83,6 @@ namespace ARDOUR int status; }; -}; +} // namespace ARDOUR #endif /* __ardour_export_h__ */ diff --git a/libs/ardour/ardour/insert.h b/libs/ardour/ardour/insert.h index 2d6b672064..a4c4439942 100644 --- a/libs/ardour/ardour/insert.h +++ b/libs/ardour/ardour/insert.h @@ -98,7 +98,7 @@ struct PluginInsertState : public RedirectState class PluginInsert : public Insert { public: - PluginInsert (Session&, Plugin&, Placement); + PluginInsert (Session&, boost::shared_ptr, Placement); PluginInsert (Session&, const XMLNode&); PluginInsert (const PluginInsert&); ~PluginInsert (); @@ -141,11 +141,11 @@ class PluginInsert : public Insert float default_parameter_value (uint32_t which); - Plugin& plugin(uint32_t num=0) const { + boost::shared_ptr plugin(uint32_t num=0) const { if (num < _plugins.size()) { - return *_plugins[num]; + return _plugins[num]; } else { - return *_plugins[0]; // we always have one + return _plugins[0]; // we always have one } } @@ -163,7 +163,7 @@ class PluginInsert : public Insert void parameter_changed (uint32_t, float); - vector _plugins; + vector > _plugins; void automation_run (vector& bufs, uint32_t nbufs, jack_nframes_t nframes, jack_nframes_t offset); void connect_and_run (vector& bufs, uint32_t nbufs, jack_nframes_t nframes, jack_nframes_t offset, bool with_auto, jack_nframes_t now = 0); @@ -172,9 +172,9 @@ class PluginInsert : public Insert void auto_state_changed (uint32_t which); void automation_list_creation_callback (uint32_t, AutomationList&); - Plugin* plugin_factory (Plugin&); + boost::shared_ptr plugin_factory (boost::shared_ptr); }; -}; /* namespace ARDOUR */ +} // namespace ARDOUR #endif /* __ardour_insert_h__ */ diff --git a/libs/ardour/ardour/io.h b/libs/ardour/ardour/io.h index 6cff58eef8..94e1483ad6 100644 --- a/libs/ardour/ardour/io.h +++ b/libs/ardour/ardour/io.h @@ -393,6 +393,6 @@ public: int32_t find_output_port_hole (); }; -}; /* namespace ARDOUR */ +} // namespace ARDOUR #endif /*__ardour_io_h__ */ diff --git a/libs/ardour/ardour/location.h b/libs/ardour/ardour/location.h index 2c9f947541..30c02a80a1 100644 --- a/libs/ardour/ardour/location.h +++ b/libs/ardour/ardour/location.h @@ -199,6 +199,6 @@ class Locations : public Stateful, public StateManager StateManager::State* state_factory (std::string why) const; }; -}; /* namespace ARDOUR */ +} // namespace ARDOUR #endif /* __ardour_location_h__ */ diff --git a/libs/ardour/ardour/logcurve.h b/libs/ardour/ardour/logcurve.h index e65be55772..ac60a10fd7 100644 --- a/libs/ardour/ardour/logcurve.h +++ b/libs/ardour/ardour/logcurve.h @@ -126,7 +126,7 @@ class LogCurveOut : public LogCurve }; -}; /* namespace ARDOUR */ +} // namespace ARDOUR #endif /* __ardour_logcurve_h__ */ diff --git a/libs/ardour/ardour/panner.h b/libs/ardour/ardour/panner.h index 37c985a2ef..75c59eb924 100644 --- a/libs/ardour/ardour/panner.h +++ b/libs/ardour/ardour/panner.h @@ -312,6 +312,6 @@ class Panner : public std::vector, public Stateful, public sigc:: static float current_automation_version_number; }; -}; /* namespace ARDOUR */ +} // namespace ARDOUR #endif /*__ardour_panner_h__ */ diff --git a/libs/ardour/ardour/plugin.h b/libs/ardour/ardour/plugin.h index e7d05aa352..97708065e4 100644 --- a/libs/ardour/ardour/plugin.h +++ b/libs/ardour/ardour/plugin.h @@ -21,6 +21,7 @@ #ifndef __ardour_ladspa_h__ #define __ardour_ladspa_h__ +#include #include #include @@ -179,7 +180,7 @@ class Plugin : public Stateful, public sigc::trackable /* this is actually defined in plugin_manager.cc */ -Plugin * find_plugin(ARDOUR::Session&, string name, long unique_id, PluginInfo::Type); +boost::shared_ptr find_plugin(ARDOUR::Session&, string name, long unique_id, PluginInfo::Type); } // namespace ARDOUR diff --git a/libs/ardour/ardour/plugin_manager.h b/libs/ardour/ardour/plugin_manager.h index 1a07c67c8d..cc9a04738e 100644 --- a/libs/ardour/ardour/plugin_manager.h +++ b/libs/ardour/ardour/plugin_manager.h @@ -5,6 +5,8 @@ #include #include +#include + #include namespace ARDOUR { @@ -26,7 +28,7 @@ class PluginManager { int add_ladspa_directory (std::string dirpath); int add_vst_directory (std::string dirpath); - Plugin *load (ARDOUR::Session& s, PluginInfo* info); + boost::shared_ptr load (ARDOUR::Session& s, PluginInfo* info); static PluginManager* the_manager() { return _manager; } diff --git a/libs/ardour/ardour/port.h b/libs/ardour/ardour/port.h index 0b7d79cbd6..86c99cb7e3 100644 --- a/libs/ardour/ardour/port.h +++ b/libs/ardour/ardour/port.h @@ -207,6 +207,6 @@ class Port : public sigc::trackable { static jack_nframes_t _short_over_length; }; -}; /* namespace ARDOUR */ +} // namespace ARDOUR #endif /* __ardour_port_h__ */ diff --git a/libs/ardour/ardour/redirect.h b/libs/ardour/ardour/redirect.h index ede55a1d80..658cab5d3b 100644 --- a/libs/ardour/ardour/redirect.h +++ b/libs/ardour/ardour/redirect.h @@ -25,6 +25,7 @@ #include #include #include +#include #include #include @@ -64,7 +65,7 @@ class Redirect : public IO Redirect (const Redirect&); virtual ~Redirect (); - static Redirect *clone (const Redirect&); + static boost::shared_ptr clone (boost::shared_ptr); bool active () const { return _active; } void set_active (bool yn, void *src); @@ -148,6 +149,6 @@ class Redirect : public IO void* _gui; /* generic, we don't know or care what this is */ }; -}; /* namespace ARDOUR */ +} // namespace ARDOUR #endif /* __ardour_redirect_h__ */ diff --git a/libs/ardour/ardour/route.h b/libs/ardour/ardour/route.h index d30138640a..c85f34f1fa 100644 --- a/libs/ardour/ardour/route.h +++ b/libs/ardour/ardour/route.h @@ -27,6 +27,8 @@ #include #include +#include + #include #include #include @@ -57,13 +59,13 @@ class Route : public IO { protected: - typedef list RedirectList; + typedef list > RedirectList; public: enum Flag { Hidden = 0x1, MasterOut = 0x2, - ControlOut = 0x4, + ControlOut = 0x4 }; @@ -141,19 +143,19 @@ class Route : public IO void flush_redirects (); - template void foreach_redirect (T *obj, void (T::*func)(Redirect *)) { + template void foreach_redirect (T *obj, void (T::*func)(boost::shared_ptr)) { Glib::RWLock::ReaderLock lm (redirect_lock); for (RedirectList::iterator i = _redirects.begin(); i != _redirects.end(); ++i) { (obj->*func) (*i); } } - Redirect *nth_redirect (uint32_t n) { + boost::shared_ptr nth_redirect (uint32_t n) { Glib::RWLock::ReaderLock lm (redirect_lock); RedirectList::iterator i; for (i = _redirects.begin(); i != _redirects.end() && n; ++i, --n); if (i == _redirects.end()) { - return 0; + return boost::shared_ptr (); } else { return *i; } @@ -161,9 +163,9 @@ class Route : public IO uint32_t max_redirect_outs () const { return redirect_max_outs; } - int add_redirect (Redirect *, void *src, uint32_t* err_streams = 0); + int add_redirect (boost::shared_ptr, void *src, uint32_t* err_streams = 0); int add_redirects (const RedirectList&, void *src, uint32_t* err_streams = 0); - int remove_redirect (Redirect *, void *src, uint32_t* err_streams = 0); + int remove_redirect (boost::shared_ptr, void *src, uint32_t* err_streams = 0); int copy_redirects (const Route&, Placement, uint32_t* err_streams = 0); int sort_redirects (uint32_t* err_streams = 0); @@ -212,8 +214,8 @@ class Route : public IO int set_control_outs (const vector& ports); IO* control_outs() { return _control_outs; } - bool feeds (Route *); - set fed_by; + bool feeds (boost::shared_ptr); + set > fed_by; struct ToggleControllable : public PBD::Controllable { enum ToggleType { @@ -339,12 +341,12 @@ class Route : public IO /* plugin count handling */ struct InsertCount { - ARDOUR::Insert& insert; + boost::shared_ptr insert; int32_t cnt; int32_t in; int32_t out; - InsertCount (ARDOUR::Insert& ins) : insert (ins), cnt (-1) {} + InsertCount (boost::shared_ptr ins) : insert (ins), cnt (-1) {} }; int32_t apply_some_plugin_counts (std::list& iclist); @@ -355,6 +357,6 @@ class Route : public IO void redirect_active_proxy (Redirect*, void*); }; -}; /* namespace ARDOUR*/ +} // namespace ARDOUR #endif /* __ardour_route_h__ */ diff --git a/libs/ardour/ardour/route_group.h b/libs/ardour/ardour/route_group.h index 19374b4f65..11253eda5b 100644 --- a/libs/ardour/ardour/route_group.h +++ b/libs/ardour/ardour/route_group.h @@ -43,7 +43,7 @@ class RouteGroup : public Stateful, public sigc::trackable { enum Flag { Relative = 0x1, Active = 0x2, - Hidden = 0x4, + Hidden = 0x4 }; RouteGroup (Session& s, const string &n, Flag f = Flag(0)); diff --git a/libs/ardour/ardour/send.h b/libs/ardour/ardour/send.h index 54d4cbd7a9..0a068e8af0 100644 --- a/libs/ardour/ardour/send.h +++ b/libs/ardour/ardour/send.h @@ -58,6 +58,6 @@ class Send : public Redirect { uint32_t expected_inputs; }; -}; /* namespace ARDOUR */ +} // namespace ARDOUR #endif /* __ardour_send_h__ */ diff --git a/libs/ardour/ardour/session.h b/libs/ardour/ardour/session.h index 10cb554842..7bd24b96cc 100644 --- a/libs/ardour/ardour/session.h +++ b/libs/ardour/ardour/session.h @@ -36,6 +36,7 @@ #include #include #include +#include #include #include @@ -112,9 +113,9 @@ class Session : public sigc::trackable, public Stateful { private: - typedef std::pair RouteBooleanState; + typedef std::pair,bool> RouteBooleanState; typedef vector GlobalRouteBooleanState; - typedef std::pair RouteMeterState; + typedef std::pair,MeterPoint> RouteMeterState; typedef vector GlobalRouteMeterState; public: @@ -127,7 +128,7 @@ class Session : public sigc::trackable, public Stateful enum SlaveSource { None = 0, MTC, - JACK, + JACK }; enum AutoConnectOption { @@ -158,7 +159,7 @@ class Session : public sigc::trackable, public Stateful */ StopOnce, - AutoLoop, + AutoLoop }; enum Action { @@ -178,6 +179,7 @@ class Session : public sigc::trackable, public Stateful void* ptr; bool yes_or_no; Session::SlaveSource slave; + Route* route; }; list audio_range; @@ -292,27 +294,26 @@ class Session : public sigc::trackable, public Stateful typedef list DiskstreamList; - typedef list RouteList; + typedef std::list > RouteList; - RouteList get_routes() const { - Glib::RWLock::ReaderLock rlock (route_lock); - return routes; /* XXX yes, force a copy */ + boost::shared_ptr get_routes() const { + return routes.reader (); } - uint32_t nroutes() const { return routes.size(); } + uint32_t nroutes() const { return routes.reader()->size(); } uint32_t ntracks () const; uint32_t nbusses () const; struct RoutePublicOrderSorter { - bool operator() (Route *, Route *b); + bool operator() (boost::shared_ptr, boost::shared_ptr b); }; template void foreach_route (T *obj, void (T::*func)(Route&)); - template void foreach_route (T *obj, void (T::*func)(Route*)); + template void foreach_route (T *obj, void (T::*func)(boost::shared_ptr)); template void foreach_route (T *obj, void (T::*func)(Route&, A), A arg); - Route *route_by_name (string); - Route *route_by_remote_id (uint32_t id); + boost::shared_ptr route_by_name (string); + boost::shared_ptr route_by_remote_id (uint32_t id); bool route_name_unique (string) const; @@ -354,7 +355,7 @@ class Session : public sigc::trackable, public Stateful sigc::signal DurationChanged; sigc::signal HaltOnXrun; - sigc::signal RouteAdded; + sigc::signal > RouteAdded; sigc::signal DiskstreamAdded; void request_roll (); @@ -505,9 +506,6 @@ class Session : public sigc::trackable, public Stateful void add_instant_xml (XMLNode&, const std::string& dir); - void swap_configuration(Configuration** new_config); - void copy_configuration(Configuration* new_config); - enum StateOfTheState { Clean = 0x0, Dirty = 0x1, @@ -548,15 +546,19 @@ class Session : public sigc::trackable, public Stateful /* fundamental operations. duh. */ - AudioTrack *new_audio_track (int input_channels, int output_channels, TrackMode mode = Normal); - Route *new_audio_route (int input_channels, int output_channels); + boost::shared_ptr new_audio_track (int input_channels, int output_channels, TrackMode mode = Normal); + boost::shared_ptr new_audio_route (int input_channels, int output_channels); + + boost::shared_ptr new_midi_track (TrackMode mode = Normal); + boost::shared_ptr new_midi_route (); + + void remove_route (boost::shared_ptr); + void resort_routes (); + void resort_routes_using (boost::shared_ptr); + void resort_routes_proxy (void* src) { + resort_routes (); + } - MidiTrack *new_midi_track (TrackMode mode = Normal); - Route *new_midi_route (); - - void remove_route (Route&); - void resort_routes (void *src); - AudioEngine &engine() { return _engine; }; /* configuration. there should really be accessors/mutators @@ -735,7 +737,7 @@ class Session : public sigc::trackable, public Stateful /* auditioning */ - Auditioner& the_auditioner() { return *auditioner; } + boost::shared_ptr the_auditioner() { return auditioner; } void audition_playlist (); void audition_region (AudioRegion&); void cancel_audition (); @@ -774,8 +776,8 @@ class Session : public sigc::trackable, public Stateful /* control/master out */ - IO* control_out() const { return _control_out; } - IO* master_out() const { return _master_out; } + boost::shared_ptr control_out() const { return _control_out; } + boost::shared_ptr master_out() const { return _master_out; } /* insert/send management */ @@ -870,7 +872,7 @@ class Session : public sigc::trackable, public Stateful /* clicking */ - IO& click_io() { return *_click_io; } + boost::shared_ptr click_io() { return _click_io; } void set_clicking (bool yn); bool get_clicking() const; @@ -1040,9 +1042,9 @@ class Session : public sigc::trackable, public Stateful float _meter_falloff; bool _end_location_is_free; - void set_worst_io_latencies (bool take_lock); + void set_worst_io_latencies (); void set_worst_io_latencies_x (IOChange asifwecare, void *ignored) { - set_worst_io_latencies (true); + set_worst_io_latencies (); } void update_latency_compensation_proxy (void* ignored); @@ -1481,13 +1483,13 @@ class Session : public sigc::trackable, public Stateful /* routes stuff */ - RouteList routes; - mutable Glib::RWLock route_lock; - void add_route (Route*); + SerializedRCUManager routes; + + void add_route (boost::shared_ptr); uint32_t destructive_index; int load_routes (const XMLNode&); - Route* XMLRouteFactory (const XMLNode&); + boost::shared_ptr XMLRouteFactory (const XMLNode&); /* mixer stuff */ @@ -1497,7 +1499,7 @@ class Session : public sigc::trackable, public Stateful bool currently_soloing; void route_mute_changed (void *src); - void route_solo_changed (void *src, Route *); + void route_solo_changed (void *src, boost::shared_ptr); void catch_up_on_solo (); void update_route_solo_state (); void modify_solo_mute (bool, bool); @@ -1564,7 +1566,7 @@ class Session : public sigc::trackable, public Stateful /* AUDITIONING */ - Auditioner *auditioner; + boost::shared_ptr auditioner; void set_audition (AudioRegion*); void non_realtime_set_audition (); AudioRegion *pending_audition_region; @@ -1681,7 +1683,7 @@ class Session : public sigc::trackable, public Stateful Clicks clicks; bool _clicking; - IO* _click_io; + boost::shared_ptr _click_io; Sample* click_data; Sample* click_emphasis_data; jack_nframes_t click_length; @@ -1713,8 +1715,8 @@ class Session : public sigc::trackable, public Stateful /* main outs */ uint32_t main_outs; - IO* _master_out; - IO* _control_out; + boost::shared_ptr _master_out; + boost::shared_ptr _control_out; AutoConnectOption input_auto_connect; AutoConnectOption output_auto_connect; @@ -1756,6 +1758,6 @@ class Session : public sigc::trackable, public Stateful void remove_controllable (PBD::Controllable*); }; -}; /* namespace ARDOUR */ +} // namespace ARDOUR #endif /* __ardour_session_h__ */ diff --git a/libs/ardour/ardour/session_route.h b/libs/ardour/ardour/session_route.h index afe78b394e..feacc14775 100644 --- a/libs/ardour/ardour/session_route.h +++ b/libs/ardour/ardour/session_route.h @@ -33,14 +33,10 @@ namespace ARDOUR { template void Session::foreach_route (T *obj, void (T::*func)(Route&)) { - RouteList public_order; - - { - Glib::RWLock::ReaderLock lm (route_lock); - public_order = routes; - } - + boost::shared_ptr r = routes.reader(); + RouteList public_order (*r); RoutePublicOrderSorter cmp; + public_order.sort (cmp); for (RouteList::iterator i = public_order.begin(); i != public_order.end(); i++) { @@ -49,16 +45,12 @@ Session::foreach_route (T *obj, void (T::*func)(Route&)) } template void -Session::foreach_route (T *obj, void (T::*func)(Route*)) +Session::foreach_route (T *obj, void (T::*func)(boost::shared_ptr)) { - RouteList public_order; - - { - Glib::RWLock::ReaderLock lm (route_lock); - public_order = routes; - } - + boost::shared_ptr r = routes.reader(); + RouteList public_order (*r); RoutePublicOrderSorter cmp; + public_order.sort (cmp); for (RouteList::iterator i = public_order.begin(); i != public_order.end(); i++) { @@ -66,18 +58,13 @@ Session::foreach_route (T *obj, void (T::*func)(Route*)) } } - template void Session::foreach_route (T *obj, void (T::*func)(Route&, A), A arg1) { - RouteList public_order; - - { - Glib::RWLock::ReaderLock lm (route_lock); - public_order = routes; - } - + boost::shared_ptr r = routes.reader(); + RouteList public_order (*r); RoutePublicOrderSorter cmp; + public_order.sort (cmp); for (RouteList::iterator i = public_order.begin(); i != public_order.end(); i++) { diff --git a/libs/ardour/ardour/sndfilesource.h b/libs/ardour/ardour/sndfilesource.h index 55a0e990a0..4764339451 100644 --- a/libs/ardour/ardour/sndfilesource.h +++ b/libs/ardour/ardour/sndfilesource.h @@ -75,7 +75,7 @@ class SndFileSource : public AudioFileSource { int setup_broadcast_info (jack_nframes_t when, struct tm&, time_t); }; -}; /* namespace ARDOUR */ +} // namespace ARDOUR #endif /* __sndfile_source_h__ */ diff --git a/libs/ardour/ardour/track.h b/libs/ardour/ardour/track.h index 7389e174b0..86bfeb0c9b 100644 --- a/libs/ardour/ardour/track.h +++ b/libs/ardour/ardour/track.h @@ -103,15 +103,15 @@ class Track : public Route MeterPoint _saved_meter_point; TrackMode _mode; - //private: + //private: (FIXME) struct FreezeRecordInsertInfo { - FreezeRecordInsertInfo(XMLNode& st) - : state (st), insert (0) {} + FreezeRecordInsertInfo(XMLNode& st, boost::shared_ptr ins) + : state (st), insert (ins) {} - XMLNode state; - Insert* insert; - PBD::ID id; - UndoAction memento; + XMLNode state; + boost::shared_ptr insert; + PBD::ID id; + UndoAction memento; }; struct FreezeRecord { diff --git a/libs/ardour/ardour/types.h b/libs/ardour/ardour/types.h index 1ae58039d9..c5b79a950c 100644 --- a/libs/ardour/ardour/types.h +++ b/libs/ardour/ardour/types.h @@ -73,7 +73,7 @@ namespace ARDOUR { PanAutomation = 0x2, PluginAutomation = 0x4, SoloAutomation = 0x8, - MuteAutomation = 0x10, + MuteAutomation = 0x10 }; enum AutoState { @@ -192,7 +192,7 @@ namespace ARDOUR { enum EditMode { Slide, - Splice, + Splice }; enum RegionPoint { @@ -245,7 +245,7 @@ namespace ARDOUR { PeakDatum min; PeakDatum max; }; -}; +} std::istream& operator>>(std::istream& o, ARDOUR::SampleFormat& sf); std::istream& operator>>(std::istream& o, ARDOUR::HeaderFormat& sf); diff --git a/libs/ardour/audio_library.cc b/libs/ardour/audio_library.cc index 168a1dcf5d..ad008f6312 100644 --- a/libs/ardour/audio_library.cc +++ b/libs/ardour/audio_library.cc @@ -46,6 +46,8 @@ using namespace PBD; static char* SOUNDFILE = "http://ardour.org/ontology/Soundfile"; +string AudioLibrary::state_node_name = "AudioLibrary"; + AudioLibrary::AudioLibrary () { // sfdb_paths.push_back("/Users/taybin/sounds"); @@ -74,17 +76,10 @@ AudioLibrary::AudioLibrary () } lrdf_free_statements(matches); - - XMLNode* state = instant_xml(X_("AudioLibrary"), get_user_ardour_path()); - if (state) { - set_state(*state); - } - scan_paths(); } AudioLibrary::~AudioLibrary () { - add_instant_xml(get_state(), get_user_ardour_path()); } void @@ -361,6 +356,8 @@ void AudioLibrary::set_paths (vector paths) { sfdb_paths = paths; + + scan_paths (); } vector @@ -477,7 +474,7 @@ AudioLibrary::set_state (const XMLNode& node) } } - sfdb_paths = paths; + set_paths (paths); return 0; } diff --git a/libs/ardour/audio_track.cc b/libs/ardour/audio_track.cc index f2a63193b3..eae9076105 100644 --- a/libs/ardour/audio_track.cc +++ b/libs/ardour/audio_track.cc @@ -424,8 +424,8 @@ AudioTrack::set_state_part_two () continue; } - FreezeRecordInsertInfo* frii = new FreezeRecordInsertInfo (*((*citer)->children().front())); - frii->insert = 0; + FreezeRecordInsertInfo* frii = new FreezeRecordInsertInfo (*((*citer)->children().front()), + boost::shared_ptr()); frii->id = prop->value (); _freeze_record.insert_info.push_back (frii); } @@ -740,9 +740,9 @@ AudioTrack::export_stuff (vector& buffers, char * workbuf, uint32_t nbu */ for (i = _redirects.begin(); i != _redirects.end(); ++i) { - Insert *insert; + boost::shared_ptr insert; - if ((insert = dynamic_cast(*i)) != 0) { + if ((insert = boost::dynamic_pointer_cast(*i)) != 0) { switch (insert->placement()) { case PreFader: insert->run (buffers, nbufs, nframes, 0); @@ -778,9 +778,9 @@ AudioTrack::export_stuff (vector& buffers, char * workbuf, uint32_t nbu if (post_fader_work) { for (i = _redirects.begin(); i != _redirects.end(); ++i) { - PluginInsert *insert; + boost::shared_ptr insert; - if ((insert = dynamic_cast(*i)) != 0) { + if ((insert = boost::dynamic_pointer_cast(*i)) != 0) { switch ((*i)->placement()) { case PreFader: break; @@ -820,7 +820,6 @@ AudioTrack::bounce_range (jack_nframes_t start, jack_nframes_t end, InterThreadI void AudioTrack::freeze (InterThreadInfo& itt) { - Insert* insert; vector srcs; string new_playlist_name; Playlist* new_playlist; @@ -851,7 +850,7 @@ AudioTrack::freeze (InterThreadInfo& itt) } if (n == (UINT_MAX-1)) { - error << string_compose (X_("There Are too many frozen versions of playlist \"%1\"" + error << string_compose (X_("There are too many frozen versions of playlist \"%1\"" " to create another one"), _freeze_record.playlist->name()) << endmsg; return; @@ -869,11 +868,12 @@ AudioTrack::freeze (InterThreadInfo& itt) for (RedirectList::iterator r = _redirects.begin(); r != _redirects.end(); ++r) { - if ((insert = dynamic_cast(*r)) != 0) { + boost::shared_ptr insert; + + if ((insert = boost::dynamic_pointer_cast(*r)) != 0) { - FreezeRecordInsertInfo* frii = new FreezeRecordInsertInfo ((*r)->get_state()); + FreezeRecordInsertInfo* frii = new FreezeRecordInsertInfo ((*r)->get_state(), insert); - frii->insert = insert; frii->id = insert->id(); frii->memento = (*r)->get_memento(); diff --git a/libs/ardour/audiofilesource.cc b/libs/ardour/audiofilesource.cc index 87700cedb3..e7264b9cf3 100644 --- a/libs/ardour/audiofilesource.cc +++ b/libs/ardour/audiofilesource.cc @@ -213,6 +213,10 @@ AudioFileSource::create (const string& idstr, Flag flags) { AudioFileSource* es = 0; + if (flags & Destructive) { + return new DestructiveFileSource (idstr, flags); + } + try { es = new CoreAudioSource (idstr, flags); } diff --git a/libs/ardour/audiosource.cc b/libs/ardour/audiosource.cc index add9364cad..bf7a32c885 100644 --- a/libs/ardour/audiosource.cc +++ b/libs/ardour/audiosource.cc @@ -640,7 +640,7 @@ AudioSource::read_peaks (PeakData *peaks, jack_nframes_t npeaks, jack_nframes_t to_read = min (chunksize, (_length - current_frame)); - if ((frames_read = read_unlocked (raw_staging, current_frame, to_read, workbuf)) < 0) { + if ((frames_read = read_unlocked (raw_staging, current_frame, to_read, workbuf)) == 0) { error << string_compose(_("AudioSource[%1]: peak read - cannot read %2 samples at offset %3") , _name, to_read, current_frame) << endmsg; diff --git a/libs/ardour/configuration.cc b/libs/ardour/configuration.cc index fc708f805d..58da77f933 100644 --- a/libs/ardour/configuration.cc +++ b/libs/ardour/configuration.cc @@ -25,6 +25,7 @@ #include #include +#include #include #include #include @@ -178,6 +179,7 @@ Configuration::state (bool user_only) } root->add_child_nocopy (ControlProtocolManager::instance().get_state()); + root->add_child_nocopy (Library->get_state()); return *root; } @@ -229,6 +231,8 @@ Configuration::set_state (const XMLNode& root) } else if (node->name() == ControlProtocolManager::state_node_name) { _control_protocol_state = new XMLNode (*node); + } else if (node->name() == AudioLibrary::state_node_name) { + Library->set_state (*node); } } diff --git a/libs/ardour/destructive_filesource.cc b/libs/ardour/destructive_filesource.cc index 68eeded9b2..43fafff30a 100644 --- a/libs/ardour/destructive_filesource.cc +++ b/libs/ardour/destructive_filesource.cc @@ -70,18 +70,24 @@ jack_nframes_t DestructiveFileSource::xfade_frames = 64; DestructiveFileSource::DestructiveFileSource (string path, SampleFormat samp_format, HeaderFormat hdr_format, jack_nframes_t rate, Flag flags) : SndFileSource (path, samp_format, hdr_format, rate, flags) { - xfade_buf = new Sample[xfade_frames]; + init (); +} - _capture_start = false; - _capture_end = false; - file_pos = 0; - timeline_position = header_position_offset; - AudioFileSource::HeaderPositionOffsetChanged.connect (mem_fun (*this, &DestructiveFileSource::handle_header_position_change)); +DestructiveFileSource::DestructiveFileSource (string path, Flag flags) + : SndFileSource (path, flags) +{ + init (); } DestructiveFileSource::DestructiveFileSource (const XMLNode& node) : SndFileSource (node) +{ + init (); +} + +void +DestructiveFileSource::init () { xfade_buf = new Sample[xfade_frames]; diff --git a/libs/ardour/globals.cc b/libs/ardour/globals.cc index 951d155d9e..4eafbbe9a1 100644 --- a/libs/ardour/globals.cc +++ b/libs/ardour/globals.cc @@ -201,6 +201,9 @@ ARDOUR::init (AudioEngine& engine, bool use_vst, bool try_optimization) PBD::ID::init (); + lrdf_init(); + Library = new AudioLibrary; + Config = new Configuration; if (Config->load_state ()) { @@ -299,9 +302,6 @@ ARDOUR::init (AudioEngine& engine, bool use_vst, bool try_optimization) info << "No H/W specific optimizations in use" << endmsg; } - lrdf_init(); - Library = new AudioLibrary; - /* singleton - first object is "it" */ new PluginManager (engine); diff --git a/libs/ardour/insert.cc b/libs/ardour/insert.cc index a2b03ad38d..11b1e25a74 100644 --- a/libs/ardour/insert.cc +++ b/libs/ardour/insert.cc @@ -62,12 +62,12 @@ Insert::Insert(Session& s, string name, Placement p) const string PluginInsert::port_automation_node_name = "PortAutomation"; -PluginInsert::PluginInsert (Session& s, Plugin& plug, Placement placement) - : Insert (s, plug.name(), placement) +PluginInsert::PluginInsert (Session& s, boost::shared_ptr plug, Placement placement) + : Insert (s, plug->name(), placement) { /* the first is the master */ - _plugins.push_back(&plug); + _plugins.push_back (plug); _plugins[0]->ParameterChanged.connect (mem_fun (*this, &PluginInsert::parameter_changed)); @@ -103,13 +103,13 @@ PluginInsert::PluginInsert (Session& s, const XMLNode& node) } PluginInsert::PluginInsert (const PluginInsert& other) - : Insert (other._session, other.plugin().name(), other.placement()) + : Insert (other._session, other.plugin()->name(), other.placement()) { uint32_t count = other._plugins.size(); /* make as many copies as requested */ for (uint32_t n = 0; n < count; ++n) { - _plugins.push_back (plugin_factory (other.plugin())); + _plugins.push_back (plugin_factory (other.plugin (n))); } @@ -137,7 +137,7 @@ PluginInsert::set_count (uint32_t num) uint32_t diff = num - _plugins.size(); for (uint32_t n = 0; n < diff; ++n) { - _plugins.push_back (plugin_factory (*_plugins[0])); + _plugins.push_back (plugin_factory (_plugins[0])); if (require_state) { /* XXX do something */ @@ -147,9 +147,7 @@ PluginInsert::set_count (uint32_t num) } else if (num < _plugins.size()) { uint32_t diff = _plugins.size() - num; for (uint32_t n= 0; n < diff; ++n) { - Plugin * plug = _plugins.back(); _plugins.pop_back(); - delete plug; } } @@ -167,12 +165,6 @@ PluginInsert::init () PluginInsert::~PluginInsert () { GoingAway (this); /* EMIT SIGNAL */ - - while (!_plugins.empty()) { - Plugin* p = _plugins.back(); - _plugins.pop_back(); - delete p; - } } void @@ -240,7 +232,7 @@ PluginInsert::set_automatable () void PluginInsert::parameter_changed (uint32_t which, float val) { - vector::iterator i = _plugins.begin(); + vector >::iterator i = _plugins.begin(); /* don't set the first plugin, just all the slaves */ @@ -255,7 +247,7 @@ PluginInsert::parameter_changed (uint32_t which, float val) void PluginInsert::set_block_size (jack_nframes_t nframes) { - for (vector::iterator i = _plugins.begin(); i != _plugins.end(); ++i) { + for (vector >::iterator i = _plugins.begin(); i != _plugins.end(); ++i) { (*i)->set_block_size (nframes); } } @@ -263,7 +255,7 @@ PluginInsert::set_block_size (jack_nframes_t nframes) void PluginInsert::activate () { - for (vector::iterator i = _plugins.begin(); i != _plugins.end(); ++i) { + for (vector >::iterator i = _plugins.begin(); i != _plugins.end(); ++i) { (*i)->activate (); } } @@ -271,7 +263,7 @@ PluginInsert::activate () void PluginInsert::deactivate () { - for (vector::iterator i = _plugins.begin(); i != _plugins.end(); ++i) { + for (vector >::iterator i = _plugins.begin(); i != _plugins.end(); ++i) { (*i)->deactivate (); } } @@ -309,7 +301,7 @@ PluginInsert::connect_and_run (vector& bufs, uint32_t nbufs, jack_nfram } } - for (vector::iterator i = _plugins.begin(); i != _plugins.end(); ++i) { + for (vector >::iterator i = _plugins.begin(); i != _plugins.end(); ++i) { (*i)->connect_and_run (bufs, nbufs, in_index, out_index, nframes, offset); } @@ -357,7 +349,7 @@ PluginInsert::silence (jack_nframes_t nframes, jack_nframes_t offset) uint32_t n; if (active()) { - for (vector::iterator i = _plugins.begin(); i != _plugins.end(); ++i) { + for (vector >::iterator i = _plugins.begin(); i != _plugins.end(); ++i) { n = (*i) -> get_info().n_inputs; (*i)->connect_and_run (_session.get_silent_buffers (n), n, in_index, out_index, nframes, offset); } @@ -506,19 +498,19 @@ PluginInsert::protect_automation () } } -Plugin* -PluginInsert::plugin_factory (Plugin& other) +boost::shared_ptr +PluginInsert::plugin_factory (boost::shared_ptr other) { - LadspaPlugin* lp; + boost::shared_ptr lp; #ifdef VST_SUPPORT - VSTPlugin* vp; + boost::shared_ptr vp; #endif - if ((lp = dynamic_cast (&other)) != 0) { - return new LadspaPlugin (*lp); + if ((lp = boost::dynamic_pointer_cast (other)) != 0) { + return boost::shared_ptr (new LadspaPlugin (*lp)); #ifdef VST_SUPPORT - } else if ((vp = dynamic_cast (&other)) != 0) { - return new VSTPlugin (*vp); + } else if ((vp = boost::dynamic_pointer_cast (other)) != 0) { + return boost::shared_ptr (new VSTPlugin (*vp)); #endif } @@ -526,7 +518,7 @@ PluginInsert::plugin_factory (Plugin& other) X_("unknown plugin type in PluginInsert::plugin_factory")) << endmsg; /*NOTREACHED*/ - return 0; + return boost::shared_ptr ((Plugin*) 0); } int32_t @@ -666,7 +658,7 @@ PluginInsert::set_state(const XMLNode& node) return -1; } - Plugin* plugin; + boost::shared_ptr plugin; if (unique != 0) { plugin = find_plugin (_session, "", unique, type); @@ -692,13 +684,13 @@ PluginInsert::set_state(const XMLNode& node) _plugins.push_back (plugin); for (uint32_t n=1; n < count; ++n) { - _plugins.push_back (plugin_factory (*plugin)); + _plugins.push_back (plugin_factory (plugin)); } } for (niter = nlist.begin(); niter != nlist.end(); ++niter) { if ((*niter)->name() == plugin->state_node_name()) { - for (vector::iterator i = _plugins.begin(); i != _plugins.end(); ++i) { + for (vector >::iterator i = _plugins.begin(); i != _plugins.end(); ++i) { (*i)->set_state (**niter); } break; diff --git a/libs/ardour/midi_track.cc b/libs/ardour/midi_track.cc index d7d1dae965..1e00879d53 100644 --- a/libs/ardour/midi_track.cc +++ b/libs/ardour/midi_track.cc @@ -80,14 +80,6 @@ MidiTrack::~MidiTrack () } } -#if 0 -void -MidiTrack::handle_smpte_offset_change () -{ - diskstream -} -#endif - int MidiTrack::set_diskstream (MidiDiskstream& ds, void *src) @@ -372,8 +364,8 @@ MidiTrack::set_state_part_two () continue; } - FreezeRecordInsertInfo* frii = new FreezeRecordInsertInfo (*((*citer)->children().front())); - frii->insert = 0; + FreezeRecordInsertInfo* frii = new FreezeRecordInsertInfo (*((*citer)->children().front()), + boost::shared_ptr()); frii->id = prop->value (); _freeze_record.insert_info.push_back (frii); } @@ -491,111 +483,6 @@ int MidiTrack::roll (jack_nframes_t nframes, jack_nframes_t start_frame, jack_nframes_t end_frame, jack_nframes_t offset, int declick, bool can_record, bool rec_monitors_input) { -#if 0 - int dret; - Sample* b; - Sample* tmpb; - jack_nframes_t transport_frame; - - { - Glib::RWLock::ReaderLock lm (redirect_lock, Glib::TRY_LOCK); - if (lm.locked()) { - // automation snapshot can also be called from the non-rt context - // and it uses the redirect list, so we take the lock out here - automation_snapshot (start_frame); - } - } - - if (n_outputs() == 0 && _redirects.empty()) { - return 0; - } - - if (!_active) { - silence (nframes, offset); - return 0; - } - - transport_frame = _session.transport_frame(); - - if ((nframes = check_initial_delay (nframes, offset, transport_frame)) == 0) { - /* need to do this so that the diskstream sets its - playback distance to zero, thus causing diskstream::commit - to do nothing. - */ - return diskstream->process (transport_frame, 0, 0, can_record, rec_monitors_input); - } - - _silent = false; - apply_gain_automation = false; - - if ((dret = diskstream->process (transport_frame, nframes, offset, can_record, rec_monitors_input)) != 0) { - - silence (nframes, offset); - - return dret; - } - - /* special condition applies */ - - if (_meter_point == MeterInput) { - just_meter_input (start_frame, end_frame, nframes, offset); - } - - if (diskstream->record_enabled() && !can_record && !_session.get_auto_input()) { - - /* not actually recording, but we want to hear the input material anyway, - at least potentially (depending on monitoring options) - */ - - passthru (start_frame, end_frame, nframes, offset, 0, true); - - } else if ((b = diskstream->playback_buffer(0)) != 0) { - - /* - XXX is it true that the earlier test on n_outputs() - means that we can avoid checking it again here? i think - so, because changing the i/o configuration of an IO - requires holding the AudioEngine lock, which we hold - while in the process() tree. - */ - - - /* copy the diskstream data to all output buffers */ - - vector& bufs = _session.get_passthru_buffers (); - uint32_t limit = n_process_buffers (); - - uint32_t n; - uint32_t i; - - - for (i = 0, n = 1; i < limit; ++i, ++n) { - memcpy (bufs[i], b, sizeof (Sample) * nframes); - if (n < diskstream->n_channels()) { - tmpb = diskstream->playback_buffer(n); - if (tmpb!=0) { - b = tmpb; - } - } - } - - /* don't waste time with automation if we're recording or we've just stopped (yes it can happen) */ - - if (!diskstream->record_enabled() && _session.transport_rolling()) { - Glib::Mutex::Lock am (automation_lock, Glib::TRY_LOCK); - - if (am.locked() && gain_automation_playback()) { - apply_gain_automation = _gain_automation_curve.rt_safe_get_vector (start_frame, end_frame, _session.gain_automation_buffer(), nframes); - } - } - - process_output_buffers (bufs, limit, start_frame, end_frame, nframes, offset, (!_session.get_record_enabled() || !_session.get_do_not_record_plugins()), declick, (_meter_point != MeterInput)); - - } else { - /* problem with the diskstream; just be quiet for a bit */ - silence (nframes, offset); - } -#endif return 0; } @@ -645,97 +532,6 @@ MidiTrack::set_name (string str, void *src) int MidiTrack::export_stuff (vector& buffers, char * workbuf, uint32_t nbufs, jack_nframes_t start, jack_nframes_t nframes) { -#if 0 - gain_t gain_automation[nframes]; - gain_t gain_buffer[nframes]; - float mix_buffer[nframes]; - RedirectList::iterator i; - bool post_fader_work = false; - gain_t this_gain = _gain; - vector::iterator bi; - Sample * b; - - Glib::RWLock::ReaderLock rlock (redirect_lock); - - if (diskstream->playlist()->read (buffers[0], mix_buffer, gain_buffer, workbuf, start, nframes) != nframes) { - return -1; - } - - uint32_t n=1; - bi = buffers.begin(); - b = buffers[0]; - ++bi; - for (; bi != buffers.end(); ++bi, ++n) { - if (n < diskstream->n_channels()) { - if (diskstream->playlist()->read ((*bi), mix_buffer, gain_buffer, workbuf, start, nframes, n) != nframes) { - return -1; - } - b = (*bi); - } - else { - /* duplicate last across remaining buffers */ - memcpy ((*bi), b, sizeof (Sample) * nframes); - } - } - - - /* note: only run inserts during export. other layers in the machinery - will already have checked that there are no external port inserts. - */ - - for (i = _redirects.begin(); i != _redirects.end(); ++i) { - Insert *insert; - - if ((insert = dynamic_cast(*i)) != 0) { - switch (insert->placement()) { - case PreFader: - insert->run (buffers, nbufs, nframes, 0); - break; - case PostFader: - post_fader_work = true; - break; - } - } - } - - if (_gain_automation_curve.automation_state() == Play) { - - _gain_automation_curve.get_vector (start, start + nframes, gain_automation, nframes); - - for (bi = buffers.begin(); bi != buffers.end(); ++bi) { - Sample *b = *bi; - for (jack_nframes_t n = 0; n < nframes; ++n) { - b[n] *= gain_automation[n]; - } - } - - } else { - - for (bi = buffers.begin(); bi != buffers.end(); ++bi) { - Sample *b = *bi; - for (jack_nframes_t n = 0; n < nframes; ++n) { - b[n] *= this_gain; - } - } - } - - if (post_fader_work) { - - for (i = _redirects.begin(); i != _redirects.end(); ++i) { - PluginInsert *insert; - - if ((insert = dynamic_cast(*i)) != 0) { - switch ((*i)->placement()) { - case PreFader: - break; - case PostFader: - insert->run (buffers, nbufs, nframes, 0); - break; - } - } - } - } -#endif return 0; } @@ -764,124 +560,11 @@ MidiTrack::bounce_range (jack_nframes_t start, jack_nframes_t end, InterThreadIn void MidiTrack::freeze (InterThreadInfo& itt) { -#if 0 - Insert* insert; - vector srcs; - string new_playlist_name; - Playlist* new_playlist; - string dir; - AudioRegion* region; - string region_name; - - if ((_freeze_record.playlist = diskstream->playlist()) == 0) { - return; - } - - uint32_t n = 1; - - while (n < (UINT_MAX-1)) { - - string candidate; - - candidate = string_compose ("%1", _freeze_record.playlist->name(), n); - - if (_session.playlist_by_name (candidate) == 0) { - new_playlist_name = candidate; - break; - } - - ++n; - - } - - if (n == (UINT_MAX-1)) { - PBD::error << string_compose (X_("There Are too many frozen versions of playlist \"%1\"" - " to create another one"), _freeze_record.playlist->name()) - << endmsg; - return; - } - - if (_session.write_one_midi_track (*this, 0, _session.current_end_frame(), true, srcs, itt)) { - return; - } - - _freeze_record.insert_info.clear (); - _freeze_record.have_mementos = true; - - { - Glib::RWLock::ReaderLock lm (redirect_lock); - - for (RedirectList::iterator r = _redirects.begin(); r != _redirects.end(); ++r) { - - if ((insert = dynamic_cast(*r)) != 0) { - - FreezeRecordInsertInfo* frii = new FreezeRecordInsertInfo ((*r)->get_state()); - - frii->insert = insert; - frii->id = insert->id(); - frii->memento = (*r)->get_memento(); - - _freeze_record.insert_info.push_back (frii); - - /* now deactivate the insert */ - - insert->set_active (false, this); - } - } - } - - new_playlist = new MidiPlaylist (_session, new_playlist_name, false); - region_name = new_playlist_name; - - /* 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); - - new_playlist->set_orig_diskstream_id (diskstream->id()); - new_playlist->add_region (*region, 0); - new_playlist->set_frozen (true); - region->set_locked (true); - - diskstream->use_playlist (dynamic_cast(new_playlist)); - diskstream->set_record_enabled (false, this); - - _freeze_record.state = Frozen; - FreezeChange(); /* EMIT SIGNAL */ -#endif } void MidiTrack::unfreeze () { -#if 0 - if (_freeze_record.playlist) { - diskstream->use_playlist (_freeze_record.playlist); - - if (_freeze_record.have_mementos) { - - for (vector::iterator i = _freeze_record.insert_info.begin(); i != _freeze_record.insert_info.end(); ++i) { - (*i)->memento (); - } - - } else { - - Glib::RWLock::ReaderLock lm (redirect_lock); // should this be a write lock? jlc - for (RedirectList::iterator i = _redirects.begin(); i != _redirects.end(); ++i) { - for (vector::iterator ii = _freeze_record.insert_info.begin(); ii != _freeze_record.insert_info.end(); ++ii) { - if ((*ii)->id == (*i)->id()) { - (*i)->set_state (((*ii)->state)); - break; - } - } - } - } - - _freeze_record.playlist = 0; - } -#endif _freeze_record.state = UnFrozen; FreezeChange (); /* EMIT SIGNAL */ } diff --git a/libs/ardour/panner.cc b/libs/ardour/panner.cc index a56424cfea..4984e13fa9 100644 --- a/libs/ardour/panner.cc +++ b/libs/ardour/panner.cc @@ -1179,7 +1179,7 @@ struct PanPlugins { PanPlugins pan_plugins[] = { { EqualPowerStereoPanner::name, 2, EqualPowerStereoPanner::factory }, { Multi2dPanner::name, 3, Multi2dPanner::factory }, - { string (""), 0 } + { string (""), 0, 0 } }; XMLNode& diff --git a/libs/ardour/plugin_manager.cc b/libs/ardour/plugin_manager.cc index b096e81785..c8787a7d34 100644 --- a/libs/ardour/plugin_manager.cc +++ b/libs/ardour/plugin_manager.cc @@ -280,13 +280,14 @@ PluginManager::ladspa_discover (string path) return 0; } -Plugin * +boost::shared_ptr PluginManager::load (Session& session, PluginInfo *info) { void *module; - Plugin *plugin = 0; try { + boost::shared_ptr plugin; + if (info->type == PluginInfo::VST) { #ifdef VST_SUPPORT @@ -296,14 +297,14 @@ PluginManager::load (Session& session, PluginInfo *info) if ((handle = fst_load (info->path.c_str())) == 0) { error << string_compose(_("VST: cannot load module from \"%1\""), info->path) << endmsg; } else { - plugin = new VSTPlugin (_engine, session, handle); + plugin.reset (new VSTPlugin (_engine, session, handle)); } } else { error << _("You asked ardour to not use any VST plugins") << endmsg; } #else error << _("This version of ardour has no support for VST plugins") << endmsg; - return 0; + return boost::shared_ptr ((Plugin*) 0); #endif } else { @@ -312,21 +313,20 @@ PluginManager::load (Session& session, PluginInfo *info) error << string_compose(_("LADSPA: cannot load module from \"%1\""), info->path) << endmsg; error << dlerror() << endmsg; } else { - plugin = new LadspaPlugin (module, _engine, session, info->index, session.frame_rate()); + plugin.reset (new LadspaPlugin (module, _engine, session, info->index, session.frame_rate())); } } plugin->set_info(*info); + return plugin; } catch (failed_constructor &err) { - plugin = 0; + return boost::shared_ptr ((Plugin*) 0); } - - return plugin; } -Plugin * +boost::shared_ptr ARDOUR::find_plugin(Session& session, string name, long unique_id, PluginInfo::Type type) { PluginManager *mgr = PluginManager::the_manager(); @@ -343,7 +343,7 @@ ARDOUR::find_plugin(Session& session, string name, long unique_id, PluginInfo::T break; case PluginInfo::AudioUnit: default: - return 0; + return boost::shared_ptr ((Plugin *) 0); } for (i = plugs->begin(); i != plugs->end(); ++i) { @@ -353,7 +353,7 @@ ARDOUR::find_plugin(Session& session, string name, long unique_id, PluginInfo::T } } - return 0; + return boost::shared_ptr ((Plugin*) 0); } string diff --git a/libs/ardour/redirect.cc b/libs/ardour/redirect.cc index 9800c5b1a2..1ab2f91cf0 100644 --- a/libs/ardour/redirect.cc +++ b/libs/ardour/redirect.cc @@ -60,25 +60,25 @@ Redirect::~Redirect () { } -Redirect* -Redirect::clone (const Redirect& other) +boost::shared_ptr +Redirect::clone (boost::shared_ptr other) { - const Send *send; - const PortInsert *port_insert; - const PluginInsert *plugin_insert; - - if ((send = dynamic_cast(&other)) != 0) { - return new Send (*send); - } else if ((port_insert = dynamic_cast(&other)) != 0) { - return new PortInsert (*port_insert); - } else if ((plugin_insert = dynamic_cast(&other)) != 0) { - return new PluginInsert (*plugin_insert); + boost::shared_ptr send; + boost::shared_ptr port_insert; + boost::shared_ptr plugin_insert; + + if ((send = boost::dynamic_pointer_cast(other)) != 0) { + return boost::shared_ptr (new Send (*send)); + } else if ((port_insert = boost::dynamic_pointer_cast(other)) != 0) { + return boost::shared_ptr (new PortInsert (*port_insert)); + } else if ((plugin_insert = boost::dynamic_pointer_cast(other)) != 0) { + return boost::shared_ptr (new PluginInsert (*plugin_insert)); } else { fatal << _("programming error: unknown Redirect type in Redirect::Clone!\n") << endmsg; /*NOTREACHED*/ } - return 0; + return boost::shared_ptr(); } void diff --git a/libs/ardour/route.cc b/libs/ardour/route.cc index fb5c175bba..95b5d0ddaf 100644 --- a/libs/ardour/route.cc +++ b/libs/ardour/route.cc @@ -757,7 +757,7 @@ Route::set_mute (bool yn, void *src) } int -Route::add_redirect (Redirect *redirect, void *src, uint32_t* err_streams) +Route::add_redirect (boost::shared_ptr redirect, void *src, uint32_t* err_streams) { uint32_t old_rmo = redirect_max_outs; @@ -768,12 +768,12 @@ Route::add_redirect (Redirect *redirect, void *src, uint32_t* err_streams) { Glib::RWLock::WriterLock lm (redirect_lock); - PluginInsert* pi; - PortInsert* porti; + boost::shared_ptr pi; + boost::shared_ptr porti; uint32_t potential_max_streams = 0; - if ((pi = dynamic_cast(redirect)) != 0) { + if ((pi = boost::dynamic_pointer_cast(redirect)) != 0) { pi->set_count (1); if (pi->input_streams() == 0) { @@ -782,8 +782,8 @@ Route::add_redirect (Redirect *redirect, void *src, uint32_t* err_streams) } potential_max_streams = max(pi->input_streams(), pi->output_streams()); - - } else if ((porti = dynamic_cast(redirect)) != 0) { + + } else if ((porti = boost::dynamic_pointer_cast(redirect)) != 0) { /* force new port inserts to start out with an i/o configuration that matches this route's i/o configuration. @@ -848,9 +848,9 @@ Route::add_redirects (const RedirectList& others, void *src, uint32_t* err_strea for (RedirectList::const_iterator i = others.begin(); i != others.end(); ++i) { - PluginInsert* pi; + boost::shared_ptr pi; - if ((pi = dynamic_cast(*i)) != 0) { + if ((pi = boost::dynamic_pointer_cast(*i)) != 0) { pi->set_count (1); uint32_t m = max(pi->input_streams(), pi->output_streams()); @@ -899,11 +899,6 @@ Route::clear_redirects (void *src) { Glib::RWLock::WriterLock lm (redirect_lock); - - for (RedirectList::iterator i = _redirects.begin(); i != _redirects.end(); ++i) { - delete *i; - } - _redirects.clear (); } @@ -917,7 +912,7 @@ Route::clear_redirects (void *src) } int -Route::remove_redirect (Redirect *redirect, void *src, uint32_t* err_streams) +Route::remove_redirect (boost::shared_ptr redirect, void *src, uint32_t* err_streams) { uint32_t old_rmo = redirect_max_outs; @@ -949,13 +944,13 @@ Route::remove_redirect (Redirect *redirect, void *src, uint32_t* err_streams) run. */ - Send* send; - PortInsert* port_insert; + boost::shared_ptr send; + boost::shared_ptr port_insert; - if ((send = dynamic_cast (*i)) != 0) { + if ((send = boost::dynamic_pointer_cast (*i)) != 0) { send->disconnect_inputs (this); send->disconnect_outputs (this); - } else if ((port_insert = dynamic_cast (*i)) != 0) { + } else if ((port_insert = boost::dynamic_pointer_cast (*i)) != 0) { port_insert->disconnect_inputs (this); port_insert->disconnect_outputs (this); } @@ -984,9 +979,9 @@ Route::remove_redirect (Redirect *redirect, void *src, uint32_t* err_streams) bool foo = false; for (i = _redirects.begin(); i != _redirects.end(); ++i) { - PluginInsert* pi; - - if ((pi = dynamic_cast(*i)) != 0) { + boost::shared_ptr pi; + + if ((pi = boost::dynamic_pointer_cast(*i)) != 0) { if (pi->is_generator()) { foo = true; } @@ -1033,7 +1028,7 @@ Route::_reset_plugin_counts (uint32_t* err_streams) for (r = _redirects.begin(); r != _redirects.end(); ++r) { - Insert *insert; + boost::shared_ptr insert; /* do this here in case we bomb out before we get to the end of this function. @@ -1041,22 +1036,22 @@ Route::_reset_plugin_counts (uint32_t* err_streams) redirect_max_outs = max ((*r)->output_streams (), redirect_max_outs); - if ((insert = dynamic_cast(*r)) != 0) { + if ((insert = boost::dynamic_pointer_cast(*r)) != 0) { ++i_cnt; - insert_map[insert->placement()].push_back (InsertCount (*insert)); + insert_map[insert->placement()].push_back (InsertCount (insert)); /* reset plugin counts back to one for now so that we have a predictable, controlled state to try to configure. */ - PluginInsert* pi; + boost::shared_ptr pi; - if ((pi = dynamic_cast(insert)) != 0) { + if ((pi = boost::dynamic_pointer_cast(insert)) != 0) { pi->set_count (1); } - } else if (dynamic_cast (*r) != 0) { + } else if (boost::dynamic_pointer_cast (*r) != 0) { ++s_cnt; } } @@ -1083,7 +1078,7 @@ Route::_reset_plugin_counts (uint32_t* err_streams) if (!insert_map[PreFader].empty()) { InsertCount& ic (insert_map[PreFader].back()); - initial_streams = ic.insert.compute_output_streams (ic.cnt); + initial_streams = ic.insert->compute_output_streams (ic.cnt); } else { initial_streams = n_inputs (); } @@ -1107,9 +1102,9 @@ Route::_reset_plugin_counts (uint32_t* err_streams) RedirectList::iterator prev = _redirects.end(); for (r = _redirects.begin(); r != _redirects.end(); prev = r, ++r) { - Send* s; + boost::shared_ptr s; - if ((s = dynamic_cast (*r)) != 0) { + if ((s = boost::dynamic_pointer_cast (*r)) != 0) { if (r == _redirects.begin()) { s->expect_inputs (n_inputs()); } else { @@ -1132,11 +1127,11 @@ Route::apply_some_plugin_counts (list& iclist) for (i = iclist.begin(); i != iclist.end(); ++i) { - if ((*i).insert.configure_io ((*i).cnt, (*i).in, (*i).out)) { + if ((*i).insert->configure_io ((*i).cnt, (*i).in, (*i).out)) { return -1; } /* make sure that however many we have, they are all active */ - (*i).insert.activate (); + (*i).insert->activate (); } return 0; @@ -1149,7 +1144,7 @@ Route::check_some_plugin_counts (list& iclist, int32_t required_inp for (i = iclist.begin(); i != iclist.end(); ++i) { - if (((*i).cnt = (*i).insert.can_support_input_configuration (required_inputs)) < 0) { + if (((*i).cnt = (*i).insert->can_support_input_configuration (required_inputs)) < 0) { if (err_streams) { *err_streams = required_inputs; } @@ -1157,7 +1152,7 @@ Route::check_some_plugin_counts (list& iclist, int32_t required_inp } (*i).in = required_inputs; - (*i).out = (*i).insert.compute_output_streams ((*i).cnt); + (*i).out = (*i).insert->compute_output_streams ((*i).cnt); required_inputs = (*i).out; } @@ -1201,7 +1196,7 @@ Route::copy_redirects (const Route& other, Placement placement, uint32_t* err_st for (RedirectList::const_iterator i = other._redirects.begin(); i != other._redirects.end(); ++i) { if ((*i)->placement() == placement) { - _redirects.push_back (Redirect::clone (**i)); + _redirects.push_back (Redirect::clone (*i)); } } @@ -1219,7 +1214,6 @@ Route::copy_redirects (const Route& other, Placement placement, uint32_t* err_st ++tmp; if ((*i)->placement() == placement) { - delete *i; _redirects.erase (i); } @@ -1238,10 +1232,7 @@ Route::copy_redirects (const Route& other, Placement placement, uint32_t* err_st } else { /* SUCCESSFUL COPY ATTEMPT: delete the redirects we removed pre-copy */ - - for (RedirectList::iterator i = to_be_deleted.begin(); i != to_be_deleted.end(); ++i) { - delete *i; - } + to_be_deleted.clear (); } } @@ -1284,7 +1275,7 @@ Route::all_redirects_active (bool state) } struct RedirectSorter { - bool operator() (const Redirect *a, const Redirect *b) { + bool operator() (boost::shared_ptr a, boost::shared_ptr b) { return a->sort_key() < b->sort_key(); } }; @@ -1447,13 +1438,13 @@ void Route::add_redirect_from_xml (const XMLNode& node) { const XMLProperty *prop; - Insert *insert = 0; - Send *send = 0; if (node.name() == "Send") { + try { - send = new Send (_session, node); + boost::shared_ptr send (new Send (_session, node)); + add_redirect (send, this); } catch (failed_constructor &err) { @@ -1461,21 +1452,21 @@ Route::add_redirect_from_xml (const XMLNode& node) return; } - add_redirect (send, this); - } else if (node.name() == "Insert") { try { if ((prop = node.property ("type")) != 0) { + boost::shared_ptr insert; + if (prop->value() == "ladspa" || prop->value() == "Ladspa" || prop->value() == "vst") { - insert = new PluginInsert(_session, node); + insert.reset (new PluginInsert(_session, node)); } else if (prop->value() == "port") { - insert = new PortInsert (_session, node); + insert.reset (new PortInsert (_session, node)); } else { @@ -1725,8 +1716,8 @@ Route::silence (jack_nframes_t nframes, jack_nframes_t offset) if (lm.locked()) { for (RedirectList::iterator i = _redirects.begin(); i != _redirects.end(); ++i) { - PluginInsert* pi; - if (!_active && (pi = dynamic_cast (*i)) != 0) { + boost::shared_ptr pi; + if (!_active && (pi = boost::dynamic_pointer_cast (*i)) != 0) { // skip plugins, they don't need anything when we're not active continue; } @@ -1837,18 +1828,17 @@ Route::set_comment (string cmt, void *src) } bool -Route::feeds (Route *o) +Route::feeds (boost::shared_ptr other) { uint32_t i, j; - IO& other = *o; IO& self = *this; uint32_t no = self.n_outputs(); - uint32_t ni = other.n_inputs (); + uint32_t ni = other->n_inputs (); for (i = 0; i < no; ++i) { for (j = 0; j < ni; ++j) { - if (self.output(i)->connected_to (other.input(j)->name())) { + if (self.output(i)->connected_to (other->input(j)->name())) { return true; } } @@ -1862,7 +1852,7 @@ Route::feeds (Route *o) for (i = 0; i < no; ++i) { for (j = 0; j < ni; ++j) { - if ((*r)->output(i)->connected_to (other.input (j)->name())) { + if ((*r)->output(i)->connected_to (other->input (j)->name())) { return true; } } @@ -1877,7 +1867,7 @@ Route::feeds (Route *o) for (i = 0; i < no; ++i) { for (j = 0; j < ni; ++j) { - if (_control_outs->output(i)->connected_to (other.input (j)->name())) { + if (_control_outs->output(i)->connected_to (other->input (j)->name())) { return true; } } @@ -2128,10 +2118,10 @@ Route::toggle_monitor_input () bool Route::has_external_redirects () const { - const PortInsert* pi; + boost::shared_ptr pi; for (RedirectList::const_iterator i = _redirects.begin(); i != _redirects.end(); ++i) { - if ((pi = dynamic_cast(*i)) != 0) { + if ((pi = boost::dynamic_pointer_cast(*i)) != 0) { uint32_t no = pi->n_outputs(); @@ -2300,8 +2290,8 @@ Route::protect_automation () } for (RedirectList::iterator i = _redirects.begin(); i != _redirects.end(); ++i) { - PluginInsert* pi; - if ((pi = dynamic_cast (*i)) != 0) { + boost::shared_ptr pi; + if ((pi = boost::dynamic_pointer_cast (*i)) != 0) { pi->protect_automation (); } } diff --git a/libs/ardour/session.cc b/libs/ardour/session.cc index 0bdff5bd5c..fec674b671 100644 --- a/libs/ardour/session.cc +++ b/libs/ardour/session.cc @@ -79,6 +79,7 @@ using namespace std; using namespace ARDOUR; using namespace PBD; +using boost::shared_ptr; const char* Session::_template_suffix = X_(".template"); const char* Session::_statefile_suffix = X_(".ardour"); @@ -260,6 +261,9 @@ Session::Session (AudioEngine &eng, pending_events (2048), //midi_requests (128), // the size of this should match the midi request pool size _send_smpte_update (false), + routes (new RouteList), + auditioner ((Auditioner*) 0), + _click_io ((IO*) 0), main_outs (0) { bool new_session; @@ -308,6 +312,7 @@ Session::Session (AudioEngine &eng, pending_events (2048), //midi_requests (16), _send_smpte_update (false), + routes (new RouteList), main_outs (0) { @@ -325,15 +330,13 @@ Session::Session (AudioEngine &eng, } if (control_out_channels) { - Route* r; - r = new Route (*this, _("monitor"), -1, control_out_channels, -1, control_out_channels, Route::ControlOut); + shared_ptr r (new Route (*this, _("monitor"), -1, control_out_channels, -1, control_out_channels, Route::ControlOut)); add_route (r); _control_out = r; } if (master_out_channels) { - Route* r; - r = new Route (*this, _("master"), -1, master_out_channels, -1, master_out_channels, Route::MasterOut); + shared_ptr r (new Route (*this, _("master"), -1, master_out_channels, -1, master_out_channels, Route::MasterOut)); add_route (r); _master_out = r; } else { @@ -385,15 +388,6 @@ Session::~Session () clear_clicks (); - if (_click_io) { - delete _click_io; - } - - - if (auditioner) { - delete auditioner; - } - for (vector::iterator i = _passthru_buffers.begin(); i != _passthru_buffers.end(); ++i) { free(*i); } @@ -452,17 +446,6 @@ Session::~Session () i = tmp; } -#ifdef TRACK_DESTRUCTION - cerr << "delete routes\n"; -#endif /* TRACK_DESTRUCTION */ - for (RouteList::iterator i = routes.begin(); i != routes.end(); ) { - RouteList::iterator tmp; - tmp = i; - ++tmp; - delete *i; - i = tmp; - } - #ifdef TRACK_DESTRUCTION cerr << "delete diskstreams\n"; #endif /* TRACK_DESTRUCTION */ @@ -553,7 +536,7 @@ Session::~Session () } void -Session::set_worst_io_latencies (bool take_lock) +Session::set_worst_io_latencies () { _worst_output_latency = 0; _worst_input_latency = 0; @@ -562,18 +545,12 @@ Session::set_worst_io_latencies (bool take_lock) return; } - if (take_lock) { - route_lock.reader_lock (); - } + boost::shared_ptr r = routes.reader (); - for (RouteList::iterator i = routes.begin(); i != routes.end(); ++i) { + for (RouteList::iterator i = r->begin(); i != r->end(); ++i) { _worst_output_latency = max (_worst_output_latency, (*i)->output_latency()); _worst_input_latency = max (_worst_input_latency, (*i)->input_latency()); } - - if (take_lock) { - route_lock.reader_unlock (); - } } void @@ -590,7 +567,7 @@ Session::when_engine_running () /* every time we reconnect, recompute worst case output latencies */ - _engine.Running.connect (sigc::bind (mem_fun (*this, &Session::set_worst_io_latencies), true)); + _engine.Running.connect (mem_fun (*this, &Session::set_worst_io_latencies)); if (synced_to_jack()) { _engine.transport_stop (); @@ -605,7 +582,7 @@ Session::when_engine_running () try { XMLNode* child = 0; - _click_io = new ClickIO (*this, "click", 0, 0, -1, -1); + _click_io.reset (new ClickIO (*this, "click", 0, 0, -1, -1)); if (state_tree && (child = find_named_node (*state_tree->root(), "Click")) != 0) { @@ -646,7 +623,7 @@ Session::when_engine_running () error << _("cannot setup Click I/O") << endmsg; } - set_worst_io_latencies (true); + set_worst_io_latencies (); if (_clicking) { ControlChanged (Clicking); /* EMIT SIGNAL */ @@ -661,7 +638,7 @@ Session::when_engine_running () */ try { - auditioner = new Auditioner (*this); + auditioner.reset (new Auditioner (*this)); } catch (failed_constructor& err) { @@ -1468,7 +1445,6 @@ Session::set_block_size (jack_nframes_t nframes) */ { - Glib::RWLock::ReaderLock lm (route_lock); Glib::RWLock::ReaderLock dsm (diskstream_lock); vector::iterator i; uint32_t np; @@ -1510,7 +1486,9 @@ Session::set_block_size (jack_nframes_t nframes) allocate_pan_automation_buffers (nframes, _npan_buffers, true); - for (RouteList::iterator i = routes.begin(); i != routes.end(); ++i) { + boost::shared_ptr r = routes.reader (); + + for (RouteList::iterator i = r->begin(); i != r->end(); ++i) { (*i)->set_block_size (nframes); } @@ -1518,7 +1496,7 @@ Session::set_block_size (jack_nframes_t nframes) (*i)->set_block_size (nframes); } - set_worst_io_latencies (false); + set_worst_io_latencies (); } } @@ -1560,7 +1538,7 @@ Session::set_default_fade (float steepness, float fade_msecs) } struct RouteSorter { - bool operator() (Route* r1, Route* r2) { + bool operator() (boost::shared_ptr r1, boost::shared_ptr r2) { if (r1->fed_by.find (r2) != r1->fed_by.end()) { return false; } else if (r2->fed_by.find (r1) != r2->fed_by.end()) { @@ -1582,9 +1560,9 @@ struct RouteSorter { }; static void -trace_terminal (Route* r1, Route* rbase) +trace_terminal (shared_ptr r1, shared_ptr rbase) { - Route* r2; + shared_ptr r2; if ((r1->fed_by.find (rbase) != r1->fed_by.end()) && (rbase->fed_by.find (r1) != rbase->fed_by.end())) { info << string_compose(_("feedback loop setup between %1 and %2"), r1->name(), rbase->name()) << endmsg; @@ -1593,13 +1571,13 @@ trace_terminal (Route* r1, Route* rbase) /* make a copy of the existing list of routes that feed r1 */ - set existing = r1->fed_by; + set > existing = r1->fed_by; /* for each route that feeds r1, recurse, marking it as feeding rbase as well. */ - for (set::iterator i = existing.begin(); i != existing.end(); ++i) { + for (set >::iterator i = existing.begin(); i != existing.end(); ++i) { r2 =* i; /* r2 is a route that feeds r1 which somehow feeds base. mark @@ -1629,7 +1607,7 @@ trace_terminal (Route* r1, Route* rbase) } void -Session::resort_routes (void* src) +Session::resort_routes () { /* don't do anything here with signals emitted by Routes while we are being destroyed. @@ -1639,54 +1617,64 @@ Session::resort_routes (void* src) return; } - /* Caller MUST hold the route_lock */ - RouteList::iterator i, j; + { - for (i = routes.begin(); i != routes.end(); ++i) { + RCUWriter writer (routes); + shared_ptr r = writer.get_copy (); + resort_routes_using (r); + /* writer goes out of scope and forces update */ + } +} +void +Session::resort_routes_using (shared_ptr r) +{ + RouteList::iterator i, j; + + for (i = r->begin(); i != r->end(); ++i) { + (*i)->fed_by.clear (); - for (j = routes.begin(); j != routes.end(); ++j) { - + for (j = r->begin(); j != r->end(); ++j) { + /* although routes can feed themselves, it will cause an endless recursive descent if we detect it. so don't bother checking for self-feeding. */ - + if (*j == *i) { continue; } - + if ((*j)->feeds (*i)) { (*i)->fed_by.insert (*j); } } } - for (i = routes.begin(); i != routes.end(); ++i) { + for (i = r->begin(); i != r->end(); ++i) { trace_terminal (*i, *i); } - + RouteSorter cmp; - routes.sort (cmp); - + r->sort (cmp); + #if 0 cerr << "finished route resort\n"; - for (i = routes.begin(); i != routes.end(); ++i) { + for (RouteList::iterator i = r->begin(); i != r->end(); ++i) { cerr << " " << (*i)->name() << " signal order = " << (*i)->order_key ("signal") << endl; } cerr << endl; #endif - + } -MidiTrack* +boost::shared_ptr Session::new_midi_track (TrackMode mode) { - MidiTrack *track; char track_name[32]; uint32_t n = 0; uint32_t channels_used = 0; @@ -1695,9 +1683,10 @@ Session::new_midi_track (TrackMode mode) /* count existing midi tracks */ { - Glib::RWLock::ReaderLock lm (route_lock); - for (RouteList::iterator i = routes.begin(); i != routes.end(); ++i) { - if (dynamic_cast(*i) != 0) { + shared_ptr r = routes.reader (); + + for (RouteList::iterator i = r->begin(); i != r->end(); ++i) { + if (dynamic_cast((*i).get()) != 0) { if (!(*i)->hidden()) { n++; channels_used += (*i)->n_inputs(); @@ -1722,7 +1711,7 @@ Session::new_midi_track (TrackMode mode) } while (n < (UINT_MAX-1)); try { - track = new MidiTrack (*this, track_name, Route::Flag (0), mode); + shared_ptr track (new MidiTrack (*this, track_name, Route::Flag (0), mode)); if (track->ensure_io (1, 1, false, this)) { error << string_compose (_("cannot configure %1 in/%2 out configuration for new midi track"), track_name) @@ -1772,36 +1761,34 @@ Session::new_midi_track (TrackMode mode) track->set_control_outs (cports); } #endif - track->DiskstreamChanged.connect (mem_fun (this, &Session::resort_routes)); + track->DiskstreamChanged.connect (mem_fun (this, &Session::resort_routes_proxy)); add_route (track); track->set_remote_control_id (ntracks()); + return track; } catch (failed_constructor &err) { error << _("Session: could not create new midi track.") << endmsg; - return 0; + return shared_ptr ((MidiTrack*) 0); } - - return track; } -Route* +boost::shared_ptr Session::new_midi_route () { - Route *bus; char bus_name[32]; uint32_t n = 0; string port; /* count existing midi busses */ - { - Glib::RWLock::ReaderLock lm (route_lock); - for (RouteList::iterator i = routes.begin(); i != routes.end(); ++i) { - if (dynamic_cast(*i) == 0) { + shared_ptr r = routes.reader (); + + for (RouteList::iterator i = r->begin(); i != r->end(); ++i) { + if (dynamic_cast((*i).get()) == 0) { if (!(*i)->hidden()) { n++; } @@ -1819,7 +1806,7 @@ Session::new_midi_route () } while (n < (UINT_MAX-1)); try { - bus = new Route (*this, bus_name, -1, -1, -1, -1, Route::Flag(0), Buffer::MIDI); + shared_ptr bus (new Route (*this, bus_name, -1, -1, -1, -1, Route::Flag(0), Buffer::MIDI)); if (bus->ensure_io (1, 1, false, this)) { error << (_("cannot configure 1 in/1 out configuration for new midi track")) @@ -1868,21 +1855,19 @@ Session::new_midi_route () } */ add_route (bus); + return bus; } catch (failed_constructor &err) { error << _("Session: could not create new MIDI route.") << endmsg; - return 0; + return shared_ptr ((Route*) 0); } - - return bus; } -AudioTrack* +shared_ptr Session::new_audio_track (int input_channels, int output_channels, TrackMode mode) { - AudioTrack *track; char track_name[32]; uint32_t n = 0; uint32_t channels_used = 0; @@ -1893,9 +1878,10 @@ Session::new_audio_track (int input_channels, int output_channels, TrackMode mod /* count existing audio tracks */ { - Glib::RWLock::ReaderLock lm (route_lock); - for (RouteList::iterator i = routes.begin(); i != routes.end(); ++i) { - if (dynamic_cast(*i) != 0) { + shared_ptr r = routes.reader (); + + for (RouteList::iterator i = r->begin(); i != r->end(); ++i) { + if (dynamic_cast((*i).get()) != 0) { if (!(*i)->hidden()) { n++; channels_used += (*i)->n_inputs(); @@ -1932,7 +1918,7 @@ Session::new_audio_track (int input_channels, int output_channels, TrackMode mod } try { - track = new AudioTrack (*this, track_name, Route::Flag (0), mode); + shared_ptr track (new AudioTrack (*this, track_name, Route::Flag (0), mode)); if (track->ensure_io (input_channels, output_channels, false, this)) { error << string_compose (_("cannot configure %1 in/%2 out configuration for new audio track"), @@ -1983,25 +1969,23 @@ Session::new_audio_track (int input_channels, int output_channels, TrackMode mod track->set_control_outs (cports); } - track->DiskstreamChanged.connect (mem_fun (this, &Session::resort_routes)); + track->DiskstreamChanged.connect (mem_fun (this, &Session::resort_routes_proxy)); add_route (track); track->set_remote_control_id (ntracks()); + return track; } catch (failed_constructor &err) { error << _("Session: could not create new audio track.") << endmsg; - return 0; + return shared_ptr ((AudioTrack*) 0); } - - return track; } -Route* +shared_ptr Session::new_audio_route (int input_channels, int output_channels) { - Route *bus; char bus_name[32]; uint32_t n = 0; string port; @@ -2009,9 +1993,10 @@ Session::new_audio_route (int input_channels, int output_channels) /* count existing audio busses */ { - Glib::RWLock::ReaderLock lm (route_lock); - for (RouteList::iterator i = routes.begin(); i != routes.end(); ++i) { - if (dynamic_cast(*i) == 0) { + shared_ptr r = routes.reader (); + + for (RouteList::iterator i = r->begin(); i != r->end(); ++i) { + if (dynamic_cast((*i).get()) == 0) { if (!(*i)->hidden()) { n++; } @@ -2029,7 +2014,7 @@ Session::new_audio_route (int input_channels, int output_channels) } while (n < (UINT_MAX-1)); try { - bus = new Route (*this, bus_name, -1, -1, -1, -1, Route::Flag(0), Buffer::AUDIO); + shared_ptr bus (new Route (*this, bus_name, -1, -1, -1, -1, Route::Flag(0), Buffer::AUDIO)); if (bus->ensure_io (input_channels, output_channels, false, this)) { error << string_compose (_("cannot configure %1 in/%2 out configuration for new audio track"), @@ -2078,23 +2063,23 @@ Session::new_audio_route (int input_channels, int output_channels) } add_route (bus); + return bus; } catch (failed_constructor &err) { error << _("Session: could not create new audio route.") << endmsg; - return 0; + return shared_ptr ((Route*) 0); } - - return bus; } void -Session::add_route (Route* route) +Session::add_route (shared_ptr route) { { - Glib::RWLock::WriterLock lm (route_lock); - routes.push_front (route); - resort_routes(0); + RCUWriter writer (routes); + shared_ptr r = writer.get_copy (); + r->push_front (route); + resort_routes_using (r); } route->solo_changed.connect (sigc::bind (mem_fun (*this, &Session::route_solo_changed), route)); @@ -2148,40 +2133,43 @@ Session::add_diskstream (Diskstream* dstream) } void -Session::remove_route (Route& route) +Session::remove_route (shared_ptr route) { { - Glib::RWLock::WriterLock lm (route_lock); - routes.remove (&route); + RCUWriter writer (routes); + shared_ptr rs = writer.get_copy (); + rs->remove (route); /* deleting the master out seems like a dumb idea, but its more of a UI policy issue than our concern. */ - if (&route == _master_out) { - _master_out = 0; + if (route == _master_out) { + _master_out = shared_ptr ((Route*) 0); } - if (&route == _control_out) { - _control_out = 0; + if (route == _control_out) { + _control_out = shared_ptr ((Route*) 0); /* cancel control outs for all routes */ vector empty; - for (RouteList::iterator r = routes.begin(); r != routes.end(); ++r) { + for (RouteList::iterator r = rs->begin(); r != rs->end(); ++r) { (*r)->set_control_outs (empty); } } update_route_solo_state (); + + /* writer goes out of scope, forces route list update */ } AudioTrack* at; AudioDiskstream* ds = 0; - if ((at = dynamic_cast(&route)) != 0) { + if ((at = dynamic_cast(route.get())) != 0) { ds = &at->audio_diskstream(); } @@ -2204,7 +2192,7 @@ Session::remove_route (Route& route) save_state (_current_snapshot_name); - delete &route; + /* all shared ptrs to route should go out of scope here */ } void @@ -2214,19 +2202,20 @@ Session::route_mute_changed (void* src) } void -Session::route_solo_changed (void* src, Route* route) +Session::route_solo_changed (void* src, shared_ptr route) { if (solo_update_disabled) { // We know already return; } - Glib::RWLock::ReaderLock lm (route_lock); bool is_track; - is_track = (dynamic_cast(route) != 0); + is_track = (dynamic_cast(route.get()) != 0); - for (RouteList::iterator i = routes.begin(); i != routes.end(); ++i) { + shared_ptr r = routes.reader (); + + for (RouteList::iterator i = r->begin(); i != r->end(); ++i) { /* soloing a track mutes all other tracks, soloing a bus mutes all other busses */ @@ -2234,7 +2223,7 @@ Session::route_solo_changed (void* src, Route* route) /* don't mess with busses */ - if (dynamic_cast(*i) == 0) { + if (dynamic_cast((*i).get()) == 0) { continue; } @@ -2242,7 +2231,7 @@ Session::route_solo_changed (void* src, Route* route) /* don't mess with tracks */ - if (dynamic_cast(*i) != 0) { + if (dynamic_cast((*i).get()) != 0) { continue; } } @@ -2275,10 +2264,10 @@ Session::route_solo_changed (void* src, Route* route) bool same_thing_soloed = false; bool signal = false; - for (RouteList::iterator i = routes.begin(); i != routes.end(); ++i) { + for (RouteList::iterator i = r->begin(); i != r->end(); ++i) { if ((*i)->soloed()) { something_soloed = true; - if (dynamic_cast(*i)) { + if (dynamic_cast((*i).get())) { if (is_track) { same_thing_soloed = true; break; @@ -2329,11 +2318,13 @@ Session::update_route_solo_state () /* this is where we actually implement solo by changing the solo mute setting of each track. */ - - for (RouteList::iterator i = routes.begin(); i != routes.end(); ++i) { + + shared_ptr r = routes.reader (); + + for (RouteList::iterator i = r->begin(); i != r->end(); ++i) { if ((*i)->soloed()) { mute = true; - if (dynamic_cast(*i)) { + if (dynamic_cast((*i).get())) { is_track = true; } break; @@ -2349,7 +2340,7 @@ Session::update_route_solo_state () /* nothing is soloed */ - for (RouteList::iterator i = routes.begin(); i != routes.end(); ++i) { + for (RouteList::iterator i = r->begin(); i != r->end(); ++i) { (*i)->set_solo_mute (false); } @@ -2370,13 +2361,15 @@ Session::update_route_solo_state () void Session::modify_solo_mute (bool is_track, bool mute) { - for (RouteList::iterator i = routes.begin(); i != routes.end(); ++i) { + shared_ptr r = routes.reader (); + + for (RouteList::iterator i = r->begin(); i != r->end(); ++i) { if (is_track) { /* only alter track solo mute */ - if (dynamic_cast(*i)) { + if (dynamic_cast((*i).get())) { if ((*i)->soloed()) { (*i)->set_solo_mute (!mute); } else { @@ -2388,7 +2381,7 @@ Session::modify_solo_mute (bool is_track, bool mute) /* only alter bus solo mute */ - if (!dynamic_cast(*i)) { + if (!dynamic_cast((*i).get())) { if ((*i)->soloed()) { @@ -2420,36 +2413,35 @@ Session::catch_up_on_solo () basis, but needs the global overview that only the session has. */ - Glib::RWLock::ReaderLock lm (route_lock); update_route_solo_state(); } -Route * +shared_ptr Session::route_by_name (string name) { - Glib::RWLock::ReaderLock lm (route_lock); + shared_ptr r = routes.reader (); - for (RouteList::iterator i = routes.begin(); i != routes.end(); ++i) { + for (RouteList::iterator i = r->begin(); i != r->end(); ++i) { if ((*i)->name() == name) { - return* i; + return *i; } } - return 0; + return shared_ptr ((Route*) 0); } -Route * +shared_ptr Session::route_by_remote_id (uint32_t id) { - Glib::RWLock::ReaderLock lm (route_lock); + shared_ptr r = routes.reader (); - for (RouteList::iterator i = routes.begin(); i != routes.end(); ++i) { + for (RouteList::iterator i = r->begin(); i != r->end(); ++i) { if ((*i)->remote_control_id() == id) { - return* i; + return *i; } } - return 0; + return shared_ptr ((Route*) 0); } void @@ -3282,7 +3274,7 @@ Session::cancel_audition () } bool -Session::RoutePublicOrderSorter::operator() (Route* a, Route* b) +Session::RoutePublicOrderSorter::operator() (boost::shared_ptr a, boost::shared_ptr b) { return a->order_key(N_("signal")) < b->order_key(N_("signal")); } @@ -3328,13 +3320,11 @@ Session::is_auditioning () const void Session::set_all_solo (bool yn) { - { - Glib::RWLock::ReaderLock lm (route_lock); - - for (RouteList::iterator i = routes.begin(); i != routes.end(); ++i) { - if (!(*i)->hidden()) { - (*i)->set_solo (yn, this); - } + shared_ptr r = routes.reader (); + + for (RouteList::iterator i = r->begin(); i != r->end(); ++i) { + if (!(*i)->hidden()) { + (*i)->set_solo (yn, this); } } @@ -3344,13 +3334,11 @@ Session::set_all_solo (bool yn) void Session::set_all_mute (bool yn) { - { - Glib::RWLock::ReaderLock lm (route_lock); - - for (RouteList::iterator i = routes.begin(); i != routes.end(); ++i) { - if (!(*i)->hidden()) { - (*i)->set_mute (yn, this); - } + shared_ptr r = routes.reader (); + + for (RouteList::iterator i = r->begin(); i != r->end(); ++i) { + if (!(*i)->hidden()) { + (*i)->set_mute (yn, this); } } @@ -3394,10 +3382,9 @@ Session::graph_reordered () return; } - Glib::RWLock::WriterLock lm1 (route_lock); Glib::RWLock::ReaderLock lm2 (diskstream_lock); - resort_routes (0); + resort_routes (); /* force all diskstreams to update their capture offset values to reflect any changes in latencies within the graph. @@ -3423,12 +3410,12 @@ Session::record_enable_all () void Session::record_enable_change_all (bool yn) { - Glib::RWLock::ReaderLock lm1 (route_lock); + shared_ptr r = routes.reader (); - for (RouteList::iterator i = routes.begin(); i != routes.end(); ++i) { + for (RouteList::iterator i = r->begin(); i != r->end(); ++i) { AudioTrack* at; - if ((at = dynamic_cast(*i)) != 0) { + if ((at = dynamic_cast((*i).get())) != 0) { at->set_record_enable (yn, this); } } @@ -3694,9 +3681,9 @@ Session::reset_native_file_format () bool Session::route_name_unique (string n) const { - Glib::RWLock::ReaderLock lm (route_lock); + shared_ptr r = routes.reader (); - for (RouteList::const_iterator i = routes.begin(); i != routes.end(); ++i) { + for (RouteList::const_iterator i = r->begin(); i != r->end(); ++i) { if ((*i)->name() == n) { return false; } @@ -3753,23 +3740,16 @@ Session::allocate_pan_automation_buffers (jack_nframes_t nframes, uint32_t howma _npan_buffers = howmany; } -void -Session::add_instant_xml (XMLNode& node, const std::string& dir) -{ - Stateful::add_instant_xml (node, dir); - Config->add_instant_xml (node, get_user_ardour_path()); -} - int Session::freeze (InterThreadInfo& itt) { - Glib::RWLock::ReaderLock lm (route_lock); + shared_ptr r = routes.reader (); - for (RouteList::iterator i = routes.begin(); i != routes.end(); ++i) { + for (RouteList::iterator i = r->begin(); i != r->end(); ++i) { AudioTrack *at; - if ((at = dynamic_cast(*i)) != 0) { + if ((at = dynamic_cast((*i).get())) != 0) { /* XXX this is wrong because itt.progress will keep returning to zero at the start of every track. */ @@ -3958,10 +3938,10 @@ uint32_t Session::ntracks () const { uint32_t n = 0; - Glib::RWLock::ReaderLock lm (route_lock); + shared_ptr r = routes.reader (); - for (RouteList::const_iterator i = routes.begin(); i != routes.end(); ++i) { - if (dynamic_cast (*i)) { + for (RouteList::const_iterator i = r->begin(); i != r->end(); ++i) { + if (dynamic_cast ((*i).get())) { ++n; } } @@ -3973,10 +3953,10 @@ uint32_t Session::nbusses () const { uint32_t n = 0; - Glib::RWLock::ReaderLock lm (route_lock); + shared_ptr r = routes.reader (); - for (RouteList::const_iterator i = routes.begin(); i != routes.end(); ++i) { - if (dynamic_cast (*i) == 0) { + for (RouteList::const_iterator i = r->begin(); i != r->end(); ++i) { + if (dynamic_cast ((*i).get()) == 0) { ++n; } } diff --git a/libs/ardour/session_export.cc b/libs/ardour/session_export.cc index 37365c8403..b39c4f2218 100644 --- a/libs/ardour/session_export.cc +++ b/libs/ardour/session_export.cc @@ -485,8 +485,9 @@ Session::prepare_to_export (AudioExportSpecification& spec) /* take everyone out of awrite to avoid disasters */ { - Glib::RWLock::ReaderLock lm (route_lock); - for (RouteList::iterator i = routes.begin(); i != routes.end(); ++i) { + boost::shared_ptr r = routes.reader (); + + for (RouteList::iterator i = r->begin(); i != r->end(); ++i) { (*i)->protect_automation (); } } diff --git a/libs/ardour/session_midi.cc b/libs/ardour/session_midi.cc index f7f1d79bbe..d7cdd94b2b 100644 --- a/libs/ardour/session_midi.cc +++ b/libs/ardour/session_midi.cc @@ -786,12 +786,12 @@ Session::mmc_record_enable (MIDI::MachineControl &mmc, size_t trk, bool enabled) if (mmc_control) { RouteList::iterator i; - Glib::RWLock::ReaderLock guard (route_lock); + boost::shared_ptr r = routes.reader(); - for (i = routes.begin(); i != routes.end(); ++i) { + for (i = r->begin(); i != r->end(); ++i) { AudioTrack *at; - if ((at = dynamic_cast(*i)) != 0) { + if ((at = dynamic_cast((*i).get())) != 0) { if (trk == at->remote_control_id()) { at->set_record_enable (enabled, &mmc); break; diff --git a/libs/ardour/session_process.cc b/libs/ardour/session_process.cc index b8929d3eca..a45397b03a 100644 --- a/libs/ardour/session_process.cc +++ b/libs/ardour/session_process.cc @@ -83,23 +83,20 @@ Session::no_roll (jack_nframes_t nframes, jack_nframes_t offset) jack_nframes_t end_frame = _transport_frame + nframes; int ret = 0; bool declick = get_transport_declick_required(); + boost::shared_ptr r = routes.reader (); if (_click_io) { _click_io->silence (nframes, offset); } - /* XXX we're supposed to have the route_lock while doing this. - this is really bad ... - */ - if (g_atomic_int_get (&processing_prohibited)) { - for (RouteList::iterator i = routes.begin(); i != routes.end(); ++i) { + for (RouteList::iterator i = r->begin(); i != r->end(); ++i) { (*i)->silence (nframes, offset); } return 0; } - for (RouteList::iterator i = routes.begin(); i != routes.end(); ++i) { + for (RouteList::iterator i = r->begin(); i != r->end(); ++i) { if ((*i)->hidden()) { continue; @@ -124,6 +121,7 @@ Session::process_routes (jack_nframes_t nframes, jack_nframes_t offset) bool record_active; int declick = get_transport_declick_required(); bool rec_monitors = get_rec_monitors_input(); + boost::shared_ptr r = routes.reader (); if (transport_sub_state & StopPendingCapture) { /* force a declick out */ @@ -132,7 +130,7 @@ Session::process_routes (jack_nframes_t nframes, jack_nframes_t offset) record_active = actively_recording(); // || (get_record_enabled() && get_punch_in()); - for (RouteList::iterator i = routes.begin(); i != routes.end(); ++i) { + for (RouteList::iterator i = r->begin(); i != r->end(); ++i) { int ret; @@ -167,13 +165,14 @@ Session::silent_process_routes (jack_nframes_t nframes, jack_nframes_t offset) bool record_active = actively_recording(); int declick = get_transport_declick_required(); bool rec_monitors = get_rec_monitors_input(); + boost::shared_ptr r = routes.reader (); if (transport_sub_state & StopPendingCapture) { /* force a declick out */ declick = -1; } - for (RouteList::iterator i = routes.begin(); i != routes.end(); ++i) { + for (RouteList::iterator i = r->begin(); i != r->end(); ++i) { int ret; @@ -256,10 +255,14 @@ Session::process_with_events (jack_nframes_t nframes) long frames_moved; bool session_needs_butler = false; + /* make sure the auditioner is silent */ + if (auditioner) { auditioner->silence (nframes, 0); } + /* handle any pending events */ + while (pending_events.read (&ev, 1) == 1) { merge_event (ev); } @@ -296,13 +299,12 @@ Session::process_with_events (jack_nframes_t nframes) end_frame = _transport_frame + nframes; { - Glib::RWLock::ReaderLock rm (route_lock, Glib::TRY_LOCK); Glib::RWLock::ReaderLock dsm (diskstream_lock, Glib::TRY_LOCK); Event* this_event; Events::iterator the_next_one; - - if (!rm.locked() || !dsm.locked() || (post_transport_work & (PostTransportLocate|PostTransportStop))) { + + if (!dsm.locked() || (post_transport_work & (PostTransportLocate|PostTransportStop))) { no_roll (nframes, 0); return; } @@ -703,7 +705,7 @@ Session::follow_slave (jack_nframes_t nframes, jack_nframes_t offset) summon_butler (); } - jack_nframes_t frames_moved = (long) floor (_transport_speed * nframes); + int32_t frames_moved = (int32_t) floor (_transport_speed * nframes); if (frames_moved < 0) { decrement_transport_position (-frames_moved); @@ -740,10 +742,9 @@ Session::process_without_events (jack_nframes_t nframes) long frames_moved; { - Glib::RWLock::ReaderLock rm (route_lock, Glib::TRY_LOCK); Glib::RWLock::ReaderLock dsm (diskstream_lock, Glib::TRY_LOCK); - if (!rm.locked() || !dsm.locked() || (post_transport_work & (PostTransportLocate|PostTransportStop))) { + if (!dsm.locked() || (post_transport_work & (PostTransportLocate|PostTransportStop))) { no_roll (nframes, 0); return; } @@ -807,21 +808,23 @@ Session::process_without_events (jack_nframes_t nframes) void Session::process_audition (jack_nframes_t nframes) { - Glib::RWLock::ReaderLock rm (route_lock, Glib::TRY_LOCK); Event* ev; + boost::shared_ptr r = routes.reader (); - if (rm.locked()) { - for (RouteList::iterator i = routes.begin(); i != routes.end(); ++i) { - if (!(*i)->hidden()) { - (*i)->silence (nframes, 0); - } + for (RouteList::iterator i = r->begin(); i != r->end(); ++i) { + if (!(*i)->hidden()) { + (*i)->silence (nframes, 0); } } + + /* run the auditioner, and if it says we need butler service, ask for it */ if (auditioner->play_audition (nframes) > 0) { summon_butler (); } + /* handle pending events */ + while (pending_events.read (&ev, 1) == 1) { merge_event (ev); } diff --git a/libs/ardour/session_state.cc b/libs/ardour/session_state.cc index 78d8aa6ac7..73ba391873 100644 --- a/libs/ardour/session_state.cc +++ b/libs/ardour/session_state.cc @@ -167,7 +167,6 @@ Session::first_stage_init (string fullpath, string snapshot_name) _slave_type = None; butler_mixdown_buffer = 0; butler_gain_buffer = 0; - auditioner = 0; mmc_control = false; midi_control = true; mmc = 0; @@ -182,8 +181,6 @@ Session::first_stage_init (string fullpath, string snapshot_name) _edit_mode = Slide; pending_edit_mode = _edit_mode; _play_range = false; - _control_out = 0; - _master_out = 0; input_auto_connect = AutoConnectOption (0); output_auto_connect = AutoConnectOption (0); waiting_to_start = false; @@ -218,7 +215,6 @@ Session::first_stage_init (string fullpath, string snapshot_name) waveforms for clicks. */ - _click_io = 0; _clicking = false; click_requested = false; click_data = 0; @@ -1417,10 +1413,10 @@ Session::state(bool full_state) child = node->add_child ("Routes"); { - Glib::RWLock::ReaderLock lm (route_lock); + boost::shared_ptr r = routes.reader (); RoutePublicOrderSorter cmp; - RouteList public_order(routes); + RouteList public_order (*r); public_order.sort (cmp); for (RouteList::iterator i = public_order.begin(); i != public_order.end(); ++i) { @@ -1716,7 +1712,6 @@ Session::load_routes (const XMLNode& node) { XMLNodeList nlist; XMLNodeConstIterator niter; - Route *route; nlist = node.children(); @@ -1724,7 +1719,9 @@ Session::load_routes (const XMLNode& node) for (niter = nlist.begin(); niter != nlist.end(); ++niter) { - if ((route = XMLRouteFactory (**niter)) == 0) { + boost::shared_ptr route (XMLRouteFactory (**niter)); + + if (route == 0) { error << _("Session: cannot create Route from XML description.") << endmsg; return -1; } @@ -1735,11 +1732,11 @@ Session::load_routes (const XMLNode& node) return 0; } -Route * +boost::shared_ptr Session::XMLRouteFactory (const XMLNode& node) { if (node.name() != "Route") { - return 0; + return boost::shared_ptr ((Route*) 0); } bool has_diskstream = (node.property ("diskstream") != 0 || node.property ("diskstream-id") != 0); @@ -1752,12 +1749,16 @@ Session::XMLRouteFactory (const XMLNode& node) assert(type != Buffer::NIL); if (has_diskstream) { - if (type == Buffer::AUDIO) - return new AudioTrack (*this, node); - else - return new MidiTrack (*this, node); + if (type == Buffer::AUDIO) { + boost::shared_ptr ret (new AudioTrack (*this, node)); + return ret; + } else { + boost::shared_ptr ret (new MidiTrack (*this, node)); + return ret; + } } else { - return new Route (*this, node); + boost::shared_ptr ret (new Route (*this, node)); + return ret; } } @@ -2441,23 +2442,6 @@ Session::load_route_groups (const XMLNode& node, bool edit) return 0; } -void -Session::swap_configuration(Configuration** new_config) -{ - Glib::RWLock::WriterLock lm (route_lock); // jlc - WHY? - Configuration* tmp = *new_config; - *new_config = Config; - Config = tmp; - set_dirty(); -} - -void -Session::copy_configuration(Configuration* new_config) -{ - Glib::RWLock::WriterLock lm (route_lock); - new_config = new Configuration(*Config); -} - static bool state_file_filter (const string &str, void *arg) { @@ -2481,7 +2465,7 @@ remove_end(string* state) statename = statename.substr (start+1); } - if ((end = statename.rfind(".ardour")) < 0) { + if ((end = statename.rfind(".ardour")) == string::npos) { end = statename.length(); } @@ -2633,14 +2617,15 @@ Session::GlobalRouteBooleanState Session::get_global_route_boolean (bool (Route::*method)(void) const) { GlobalRouteBooleanState s; - Glib::RWLock::ReaderLock lm (route_lock); + boost::shared_ptr r = routes.reader (); - for (RouteList::iterator i = routes.begin(); i != routes.end(); ++i) { + for (RouteList::iterator i = r->begin(); i != r->end(); ++i) { if (!(*i)->hidden()) { RouteBooleanState v; v.first =* i; - v.second = ((*i)->*method)(); + Route* r = (*i).get(); + v.second = (r->*method)(); s.push_back (v); } @@ -2653,9 +2638,9 @@ Session::GlobalRouteMeterState Session::get_global_route_metering () { GlobalRouteMeterState s; - Glib::RWLock::ReaderLock lm (route_lock); + boost::shared_ptr r = routes.reader (); - for (RouteList::iterator i = routes.begin(); i != routes.end(); ++i) { + for (RouteList::iterator i = r->begin(); i != r->end(); ++i) { if (!(*i)->hidden()) { RouteMeterState v; @@ -2681,7 +2666,8 @@ void Session::set_global_route_boolean (GlobalRouteBooleanState s, void (Route::*method)(bool, void*), void* arg) { for (GlobalRouteBooleanState::iterator i = s.begin(); i != s.end(); ++i) { - (i->first->*method) (i->second, arg); + Route* r = i->first.get(); + (r->*method) (i->second, arg); } } @@ -3285,6 +3271,10 @@ Session::add_controllable (Controllable* c) void Session::remove_controllable (Controllable* c) { + if (_state_of_the_state | Deletion) { + return; + } + Glib::Mutex::Lock lm (controllables_lock); controllables.remove (c); } @@ -3302,3 +3292,10 @@ Session::controllable_by_id (const PBD::ID& id) return 0; } + +void +Session::add_instant_xml (XMLNode& node, const std::string& dir) +{ + Stateful::add_instant_xml (node, dir); + Config->add_instant_xml (node, get_user_ardour_path()); +} diff --git a/libs/ardour/session_transport.cc b/libs/ardour/session_transport.cc index 6a92d71d1c..bff8ae5955 100644 --- a/libs/ardour/session_transport.cc +++ b/libs/ardour/session_transport.cc @@ -196,11 +196,11 @@ Session::realtime_stop (bool abort) void Session::butler_transport_work () { - Glib::RWLock::ReaderLock rm (route_lock); Glib::RWLock::ReaderLock dsm (diskstream_lock); - + boost::shared_ptr r = routes.reader (); + if (post_transport_work & PostTransportCurveRealloc) { - for (RouteList::iterator i = routes.begin(); i != routes.end(); ++i) { + for (RouteList::iterator i = r->begin(); i != r->end(); ++i) { (*i)->curve_reallocate(); } } @@ -337,7 +337,9 @@ Session::non_realtime_stop (bool abort) (*i)->transport_stopped (*now, xnow, abort); } - for (RouteList::iterator i = routes.begin(); i != routes.end(); ++i) { + boost::shared_ptr r = routes.reader (); + + for (RouteList::iterator i = r->begin(); i != r->end(); ++i) { if (!(*i)->hidden()) { (*i)->set_pending_declick (0); } @@ -546,7 +548,9 @@ Session::set_auto_loop (bool yn) void Session::flush_all_redirects () { - for (RouteList::iterator i = routes.begin(); i != routes.end(); ++i) { + boost::shared_ptr r = routes.reader (); + + for (RouteList::iterator i = r->begin(); i != r->end(); ++i) { (*i)->flush_redirects (); } } @@ -1205,11 +1209,12 @@ Session::update_latency_compensation (bool with_stop, bool abort) return; } - Glib::RWLock::ReaderLock lm (route_lock); Glib::RWLock::ReaderLock lm2 (diskstream_lock); _worst_track_latency = 0; - for (RouteList::iterator i = routes.begin(); i != routes.end(); ++i) { + boost::shared_ptr r = routes.reader (); + + for (RouteList::iterator i = r->begin(); i != r->end(); ++i) { if (with_stop) { (*i)->handle_transport_stopped (abort, (post_transport_work & PostTransportLocate), (!(post_transport_work & PostTransportLocate) || pending_locate_flush)); @@ -1227,7 +1232,7 @@ Session::update_latency_compensation (bool with_stop, bool abort) } } - for (RouteList::iterator i = routes.begin(); i != routes.end(); ++i) { + for (RouteList::iterator i = r->begin(); i != r->end(); ++i) { (*i)->set_latency_delay (_worst_track_latency); } @@ -1237,7 +1242,7 @@ Session::update_latency_compensation (bool with_stop, bool abort) _engine.update_total_latencies (); } - set_worst_io_latencies (false); + set_worst_io_latencies (); /* reflect any changes in latencies into capture offsets */ -- cgit v1.2.3