diff options
author | David Robillard <d@drobilla.net> | 2006-07-28 01:08:57 +0000 |
---|---|---|
committer | David Robillard <d@drobilla.net> | 2006-07-28 01:08:57 +0000 |
commit | 8277d134b9733aee344782891c99f07114384d9e (patch) | |
tree | 4472cc8608cf59272b127e1c5c722e0530aaac58 /libs | |
parent | 60454cc8dc1ca5e1819b853b55916d52497d495c (diff) |
Merged with trunk R708
git-svn-id: svn://localhost/ardour2/branches/midi@712 d708f5d6-7413-0410-9779-e7cbd77b26cf
Diffstat (limited to 'libs')
76 files changed, 1087 insertions, 1527 deletions
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<Plugin>, 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> 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<Plugin*> _plugins; + vector<boost::shared_ptr<Plugin> > _plugins; void automation_run (vector<Sample *>& bufs, uint32_t nbufs, jack_nframes_t nframes, jack_nframes_t offset); void connect_and_run (vector<Sample *>& 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> plugin_factory (boost::shared_ptr<Plugin>); }; -}; /* 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<StreamPanner*>, 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 <boost/shared_ptr.hpp> #include <sigc++/signal.h> #include <pbd/stateful.h> @@ -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<Plugin> 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 <map> #include <string> +#include <boost/shared_ptr.hpp> + #include <ardour/types.h> 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<Plugin> 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 <vector> #include <set> #include <map> +#include <boost/shared_ptr.hpp> #include <sigc++/signal.h> #include <glibmm/thread.h> @@ -64,7 +65,7 @@ class Redirect : public IO Redirect (const Redirect&); virtual ~Redirect (); - static Redirect *clone (const Redirect&); + static boost::shared_ptr<Redirect> clone (boost::shared_ptr<const Redirect>); 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 <map> #include <string> +#include <boost/shared_ptr.hpp> + #include <pbd/fastlog.h> #include <glibmm/thread.h> #include <pbd/xml++.h> @@ -57,13 +59,13 @@ class Route : public IO { protected: - typedef list<Redirect *> RedirectList; + typedef list<boost::shared_ptr<Redirect> > RedirectList; public: enum Flag { Hidden = 0x1, MasterOut = 0x2, - ControlOut = 0x4, + ControlOut = 0x4 }; @@ -141,19 +143,19 @@ class Route : public IO void flush_redirects (); - template<class T> void foreach_redirect (T *obj, void (T::*func)(Redirect *)) { + template<class T> void foreach_redirect (T *obj, void (T::*func)(boost::shared_ptr<Redirect>)) { 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<Redirect> 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<Redirect> (); } 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<Redirect>, 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<Redirect>, 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<std::string>& ports); IO* control_outs() { return _control_outs; } - bool feeds (Route *); - set<Route *> fed_by; + bool feeds (boost::shared_ptr<Route>); + set<boost::shared_ptr<Route> > 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<ARDOUR::Insert> insert; int32_t cnt; int32_t in; int32_t out; - InsertCount (ARDOUR::Insert& ins) : insert (ins), cnt (-1) {} + InsertCount (boost::shared_ptr<ARDOUR::Insert> ins) : insert (ins), cnt (-1) {} }; int32_t apply_some_plugin_counts (std::list<InsertCount>& 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 <pbd/error.h> #include <pbd/undo.h> #include <pbd/pool.h> +#include <pbd/rcu.h> #include <midi++/types.h> #include <midi++/mmc.h> @@ -112,9 +113,9 @@ class Session : public sigc::trackable, public Stateful { private: - typedef std::pair<Route*,bool> RouteBooleanState; + typedef std::pair<boost::shared_ptr<Route>,bool> RouteBooleanState; typedef vector<RouteBooleanState> GlobalRouteBooleanState; - typedef std::pair<Route*,MeterPoint> RouteMeterState; + typedef std::pair<boost::shared_ptr<Route>,MeterPoint> RouteMeterState; typedef vector<RouteMeterState> 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<AudioRange> audio_range; @@ -292,27 +294,26 @@ class Session : public sigc::trackable, public Stateful typedef list<Diskstream *> DiskstreamList; - typedef list<Route *> RouteList; + typedef std::list<boost::shared_ptr<Route> > RouteList; - RouteList get_routes() const { - Glib::RWLock::ReaderLock rlock (route_lock); - return routes; /* XXX yes, force a copy */ + boost::shared_ptr<RouteList> 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<Route>, boost::shared_ptr<Route> b); }; template<class T> void foreach_route (T *obj, void (T::*func)(Route&)); - template<class T> void foreach_route (T *obj, void (T::*func)(Route*)); + template<class T> void foreach_route (T *obj, void (T::*func)(boost::shared_ptr<Route>)); template<class T, class A> 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> route_by_name (string); + boost::shared_ptr<Route> 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<void> DurationChanged; sigc::signal<void> HaltOnXrun; - sigc::signal<void,Route*> RouteAdded; + sigc::signal<void,boost::shared_ptr<Route> > RouteAdded; sigc::signal<void,Diskstream*> 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<AudioTrack> new_audio_track (int input_channels, int output_channels, TrackMode mode = Normal); + boost::shared_ptr<Route> new_audio_route (int input_channels, int output_channels); + + boost::shared_ptr<MidiTrack> new_midi_track (TrackMode mode = Normal); + boost::shared_ptr<Route> new_midi_route (); + + void remove_route (boost::shared_ptr<Route>); + void resort_routes (); + void resort_routes_using (boost::shared_ptr<RouteList>); + 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<Auditioner> 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<IO> control_out() const { return _control_out; } + boost::shared_ptr<IO> 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<IO> 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<RouteList> routes; + + void add_route (boost::shared_ptr<Route>); uint32_t destructive_index; int load_routes (const XMLNode&); - Route* XMLRouteFactory (const XMLNode&); + boost::shared_ptr<Route> 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<Route>); 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> 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<IO> _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<IO> _master_out; + boost::shared_ptr<IO> _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<class T> 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<RouteList> 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<class T> void -Session::foreach_route (T *obj, void (T::*func)(Route*)) +Session::foreach_route (T *obj, void (T::*func)(boost::shared_ptr<Route>)) { - RouteList public_order; - - { - Glib::RWLock::ReaderLock lm (route_lock); - public_order = routes; - } - + boost::shared_ptr<RouteList> 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<class T, class A> 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<RouteList> 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<Insert> ins) + : state (st), insert (ins) {} - XMLNode state; - Insert* insert; - PBD::ID id; - UndoAction memento; + XMLNode state; + boost::shared_ptr<Insert> 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<string> paths) { sfdb_paths = paths; + + scan_paths (); } vector<string> @@ -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<Insert>()); frii->id = prop->value (); _freeze_record.insert_info.push_back (frii); } @@ -740,9 +740,9 @@ AudioTrack::export_stuff (vector<Sample*>& buffers, char * workbuf, uint32_t nbu */ for (i = _redirects.begin(); i != _redirects.end(); ++i) { - Insert *insert; + boost::shared_ptr<Insert> insert; - if ((insert = dynamic_cast<Insert*>(*i)) != 0) { + if ((insert = boost::dynamic_pointer_cast<Insert>(*i)) != 0) { switch (insert->placement()) { case PreFader: insert->run (buffers, nbufs, nframes, 0); @@ -778,9 +778,9 @@ AudioTrack::export_stuff (vector<Sample*>& buffers, char * workbuf, uint32_t nbu if (post_fader_work) { for (i = _redirects.begin(); i != _redirects.end(); ++i) { - PluginInsert *insert; + boost::shared_ptr<PluginInsert> insert; - if ((insert = dynamic_cast<PluginInsert*>(*i)) != 0) { + if ((insert = boost::dynamic_pointer_cast<PluginInsert>(*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<AudioSource*> 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<Insert*>(*r)) != 0) { + boost::shared_ptr<Insert> insert; + + if ((insert = boost::dynamic_pointer_cast<Insert>(*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 <pbd/xml++.h> #include <ardour/ardour.h> +#include <ardour/audio_library.h> #include <ardour/configuration.h> #include <ardour/audio_diskstream.h> #include <ardour/destructive_filesource.h> @@ -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,19 +70,25 @@ 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]; _capture_start = false; 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<Plugin> 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<Plugin*>::iterator i = _plugins.begin(); + vector<boost::shared_ptr<Plugin> >::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<Plugin*>::iterator i = _plugins.begin(); i != _plugins.end(); ++i) { + for (vector<boost::shared_ptr<Plugin> >::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<Plugin*>::iterator i = _plugins.begin(); i != _plugins.end(); ++i) { + for (vector<boost::shared_ptr<Plugin> >::iterator i = _plugins.begin(); i != _plugins.end(); ++i) { (*i)->activate (); } } @@ -271,7 +263,7 @@ PluginInsert::activate () void PluginInsert::deactivate () { - for (vector<Plugin*>::iterator i = _plugins.begin(); i != _plugins.end(); ++i) { + for (vector<boost::shared_ptr<Plugin> >::iterator i = _plugins.begin(); i != _plugins.end(); ++i) { (*i)->deactivate (); } } @@ -309,7 +301,7 @@ PluginInsert::connect_and_run (vector<Sample*>& bufs, uint32_t nbufs, jack_nfram } } - for (vector<Plugin*>::iterator i = _plugins.begin(); i != _plugins.end(); ++i) { + for (vector<boost::shared_ptr<Plugin> >::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<Plugin*>::iterator i = _plugins.begin(); i != _plugins.end(); ++i) { + for (vector<boost::shared_ptr<Plugin> >::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<Plugin> +PluginInsert::plugin_factory (boost::shared_ptr<Plugin> other) { - LadspaPlugin* lp; + boost::shared_ptr<LadspaPlugin> lp; #ifdef VST_SUPPORT - VSTPlugin* vp; + boost::shared_ptr<VSTPlugin> vp; #endif - if ((lp = dynamic_cast<LadspaPlugin*> (&other)) != 0) { - return new LadspaPlugin (*lp); + if ((lp = boost::dynamic_pointer_cast<LadspaPlugin> (other)) != 0) { + return boost::shared_ptr<Plugin> (new LadspaPlugin (*lp)); #ifdef VST_SUPPORT - } else if ((vp = dynamic_cast<VSTPlugin*> (&other)) != 0) { - return new VSTPlugin (*vp); + } else if ((vp = boost::dynamic_pointer_cast<VSTPlugin> (other)) != 0) { + return boost::shared_ptr<Plugin> (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> ((Plugin*) 0); } int32_t @@ -666,7 +658,7 @@ PluginInsert::set_state(const XMLNode& node) return -1; } - Plugin* plugin; + boost::shared_ptr<Plugin> 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<Plugin*>::iterator i = _plugins.begin(); i != _plugins.end(); ++i) { + for (vector<boost::shared_ptr<Plugin> >::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<Insert>()); 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<Sample*>& 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<unsigned char*>& 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<Sample*>::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<Insert*>(*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<PluginInsert*>(*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<MidiSource*> 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 ("<F%2>%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<Insert*>(*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<MidiPlaylist*>(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<FreezeRecordInsertInfo*>::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<FreezeRecordInsertInfo*>::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<Plugin> PluginManager::load (Session& session, PluginInfo *info) { void *module; - Plugin *plugin = 0; try { + boost::shared_ptr<Plugin> 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> ((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> ((Plugin*) 0); } - - return plugin; } -Plugin * +boost::shared_ptr<Plugin> 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> ((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> ((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> +Redirect::clone (boost::shared_ptr<const Redirect> other) { - const Send *send; - const PortInsert *port_insert; - const PluginInsert *plugin_insert; - - if ((send = dynamic_cast<const Send*>(&other)) != 0) { - return new Send (*send); - } else if ((port_insert = dynamic_cast<const PortInsert*>(&other)) != 0) { - return new PortInsert (*port_insert); - } else if ((plugin_insert = dynamic_cast<const PluginInsert*>(&other)) != 0) { - return new PluginInsert (*plugin_insert); + boost::shared_ptr<const Send> send; + boost::shared_ptr<const PortInsert> port_insert; + boost::shared_ptr<const PluginInsert> plugin_insert; + + if ((send = boost::dynamic_pointer_cast<const Send>(other)) != 0) { + return boost::shared_ptr<Redirect> (new Send (*send)); + } else if ((port_insert = boost::dynamic_pointer_cast<const PortInsert>(other)) != 0) { + return boost::shared_ptr<Redirect> (new PortInsert (*port_insert)); + } else if ((plugin_insert = boost::dynamic_pointer_cast<const PluginInsert>(other)) != 0) { + return boost::shared_ptr<Redirect> (new PluginInsert (*plugin_insert)); } else { fatal << _("programming error: unknown Redirect type in Redirect::Clone!\n") << endmsg; /*NOTREACHED*/ } - return 0; + return boost::shared_ptr<Redirect>(); } 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> 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<PluginInsert> pi; + boost::shared_ptr<PortInsert> porti; uint32_t potential_max_streams = 0; - if ((pi = dynamic_cast<PluginInsert*>(redirect)) != 0) { + if ((pi = boost::dynamic_pointer_cast<PluginInsert>(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<PortInsert*>(redirect)) != 0) { + + } else if ((porti = boost::dynamic_pointer_cast<PortInsert>(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<PluginInsert> pi; - if ((pi = dynamic_cast<PluginInsert*>(*i)) != 0) { + if ((pi = boost::dynamic_pointer_cast<PluginInsert>(*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> 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> send; + boost::shared_ptr<PortInsert> port_insert; - if ((send = dynamic_cast<Send*> (*i)) != 0) { + if ((send = boost::dynamic_pointer_cast<Send> (*i)) != 0) { send->disconnect_inputs (this); send->disconnect_outputs (this); - } else if ((port_insert = dynamic_cast<PortInsert*> (*i)) != 0) { + } else if ((port_insert = boost::dynamic_pointer_cast<PortInsert> (*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<PluginInsert*>(*i)) != 0) { + boost::shared_ptr<PluginInsert> pi; + + if ((pi = boost::dynamic_pointer_cast<PluginInsert>(*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> 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<Insert*>(*r)) != 0) { + if ((insert = boost::dynamic_pointer_cast<Insert>(*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<PluginInsert> pi; - if ((pi = dynamic_cast<PluginInsert*>(insert)) != 0) { + if ((pi = boost::dynamic_pointer_cast<PluginInsert>(insert)) != 0) { pi->set_count (1); } - } else if (dynamic_cast<Send*> (*r) != 0) { + } else if (boost::dynamic_pointer_cast<Send> (*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<Send> s; - if ((s = dynamic_cast<Send*> (*r)) != 0) { + if ((s = boost::dynamic_pointer_cast<Send> (*r)) != 0) { if (r == _redirects.begin()) { s->expect_inputs (n_inputs()); } else { @@ -1132,11 +1127,11 @@ Route::apply_some_plugin_counts (list<InsertCount>& 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<InsertCount>& 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<InsertCount>& 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<const Redirect> a, boost::shared_ptr<const Redirect> 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> 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> 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<PluginInsert*> (*i)) != 0) { + boost::shared_ptr<PluginInsert> pi; + if (!_active && (pi = boost::dynamic_pointer_cast<PluginInsert> (*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<Route> 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<const PortInsert> pi; for (RedirectList::const_iterator i = _redirects.begin(); i != _redirects.end(); ++i) { - if ((pi = dynamic_cast<const PortInsert*>(*i)) != 0) { + if ((pi = boost::dynamic_pointer_cast<const PortInsert>(*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<PluginInsert*> (*i)) != 0) { + boost::shared_ptr<PluginInsert> pi; + if ((pi = boost::dynamic_pointer_cast<PluginInsert> (*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<Route> 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<Route> 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<Sample*>::iterator i = _passthru_buffers.begin(); i != _passthru_buffers.end(); ++i) { free(*i); } @@ -453,17 +447,6 @@ Session::~Session () } #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 */ for (DiskstreamList::iterator i = diskstreams.begin(); i != diskstreams.end(); ) { @@ -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<RouteList> 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<Sample*>::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<RouteList> 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<Route> r1, boost::shared_ptr<Route> 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<Route> r1, shared_ptr<Route> rbase) { - Route* r2; + shared_ptr<Route> 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<Route *> existing = r1->fed_by; + set<shared_ptr<Route> > existing = r1->fed_by; /* for each route that feeds r1, recurse, marking it as feeding rbase as well. */ - for (set<Route *>::iterator i = existing.begin(); i != existing.end(); ++i) { + for (set<shared_ptr<Route> >::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<RouteList> writer (routes); + shared_ptr<RouteList> r = writer.get_copy (); + resort_routes_using (r); + /* writer goes out of scope and forces update */ + } +} +void +Session::resort_routes_using (shared_ptr<RouteList> 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<MidiTrack> 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<MidiTrack*>(*i) != 0) { + shared_ptr<RouteList> r = routes.reader (); + + for (RouteList::iterator i = r->begin(); i != r->end(); ++i) { + if (dynamic_cast<MidiTrack*>((*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<MidiTrack> 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> ((MidiTrack*) 0); } - - return track; } -Route* +boost::shared_ptr<Route> 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<MidiTrack*>(*i) == 0) { + shared_ptr<RouteList> r = routes.reader (); + + for (RouteList::iterator i = r->begin(); i != r->end(); ++i) { + if (dynamic_cast<MidiTrack*>((*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<Route> 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> ((Route*) 0); } - - return bus; } -AudioTrack* +shared_ptr<AudioTrack> 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<AudioTrack*>(*i) != 0) { + shared_ptr<RouteList> r = routes.reader (); + + for (RouteList::iterator i = r->begin(); i != r->end(); ++i) { + if (dynamic_cast<AudioTrack*>((*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<AudioTrack> 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> ((AudioTrack*) 0); } - - return track; } -Route* +shared_ptr<Route> 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<AudioTrack*>(*i) == 0) { + shared_ptr<RouteList> r = routes.reader (); + + for (RouteList::iterator i = r->begin(); i != r->end(); ++i) { + if (dynamic_cast<AudioTrack*>((*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<Route> 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> ((Route*) 0); } - - return bus; } void -Session::add_route (Route* route) +Session::add_route (shared_ptr<Route> route) { { - Glib::RWLock::WriterLock lm (route_lock); - routes.push_front (route); - resort_routes(0); + RCUWriter<RouteList> writer (routes); + shared_ptr<RouteList> 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> route) { { - Glib::RWLock::WriterLock lm (route_lock); - routes.remove (&route); + RCUWriter<RouteList> writer (routes); + shared_ptr<RouteList> 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> ((Route*) 0); } - if (&route == _control_out) { - _control_out = 0; + if (route == _control_out) { + _control_out = shared_ptr<Route> ((Route*) 0); /* cancel control outs for all routes */ vector<string> 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<AudioTrack*>(&route)) != 0) { + if ((at = dynamic_cast<AudioTrack*>(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> route) { if (solo_update_disabled) { // We know already return; } - Glib::RWLock::ReaderLock lm (route_lock); bool is_track; - is_track = (dynamic_cast<AudioTrack*>(route) != 0); + is_track = (dynamic_cast<AudioTrack*>(route.get()) != 0); - for (RouteList::iterator i = routes.begin(); i != routes.end(); ++i) { + shared_ptr<RouteList> 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<AudioTrack*>(*i) == 0) { + if (dynamic_cast<AudioTrack*>((*i).get()) == 0) { continue; } @@ -2242,7 +2231,7 @@ Session::route_solo_changed (void* src, Route* route) /* don't mess with tracks */ - if (dynamic_cast<AudioTrack*>(*i) != 0) { + if (dynamic_cast<AudioTrack*>((*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<AudioTrack*>(*i)) { + if (dynamic_cast<AudioTrack*>((*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<RouteList> r = routes.reader (); + + for (RouteList::iterator i = r->begin(); i != r->end(); ++i) { if ((*i)->soloed()) { mute = true; - if (dynamic_cast<AudioTrack*>(*i)) { + if (dynamic_cast<AudioTrack*>((*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<RouteList> r = routes.reader (); + + for (RouteList::iterator i = r->begin(); i != r->end(); ++i) { if (is_track) { /* only alter track solo mute */ - if (dynamic_cast<AudioTrack*>(*i)) { + if (dynamic_cast<AudioTrack*>((*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<AudioTrack*>(*i)) { + if (!dynamic_cast<AudioTrack*>((*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<Route> Session::route_by_name (string name) { - Glib::RWLock::ReaderLock lm (route_lock); + shared_ptr<RouteList> 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> ((Route*) 0); } -Route * +shared_ptr<Route> Session::route_by_remote_id (uint32_t id) { - Glib::RWLock::ReaderLock lm (route_lock); + shared_ptr<RouteList> 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> ((Route*) 0); } void @@ -3282,7 +3274,7 @@ Session::cancel_audition () } bool -Session::RoutePublicOrderSorter::operator() (Route* a, Route* b) +Session::RoutePublicOrderSorter::operator() (boost::shared_ptr<Route> a, boost::shared_ptr<Route> 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<RouteList> 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<RouteList> 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<RouteList> 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<AudioTrack*>(*i)) != 0) { + if ((at = dynamic_cast<AudioTrack*>((*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<RouteList> 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<RouteList> 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<AudioTrack*>(*i)) != 0) { + if ((at = dynamic_cast<AudioTrack*>((*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<RouteList> r = routes.reader (); - for (RouteList::const_iterator i = routes.begin(); i != routes.end(); ++i) { - if (dynamic_cast<AudioTrack*> (*i)) { + for (RouteList::const_iterator i = r->begin(); i != r->end(); ++i) { + if (dynamic_cast<AudioTrack*> ((*i).get())) { ++n; } } @@ -3973,10 +3953,10 @@ uint32_t Session::nbusses () const { uint32_t n = 0; - Glib::RWLock::ReaderLock lm (route_lock); + shared_ptr<RouteList> r = routes.reader (); - for (RouteList::const_iterator i = routes.begin(); i != routes.end(); ++i) { - if (dynamic_cast<AudioTrack*> (*i) == 0) { + for (RouteList::const_iterator i = r->begin(); i != r->end(); ++i) { + if (dynamic_cast<AudioTrack*> ((*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<RouteList> 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<RouteList> 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<AudioTrack*>(*i)) != 0) { + if ((at = dynamic_cast<AudioTrack*>((*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<RouteList> 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<RouteList> 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<RouteList> 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<RouteList> 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<RouteList> 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> 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<Route> Session::XMLRouteFactory (const XMLNode& node) { if (node.name() != "Route") { - return 0; + return boost::shared_ptr<Route> ((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<Route> ret (new AudioTrack (*this, node)); + return ret; + } else { + boost::shared_ptr<Route> ret (new MidiTrack (*this, node)); + return ret; + } } else { - return new Route (*this, node); + boost::shared_ptr<Route> 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<RouteList> 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<RouteList> 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<RouteList> 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<RouteList> 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<RouteList> 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<RouteList> 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 */ diff --git a/libs/gtkmm2ext/SConscript b/libs/gtkmm2ext/SConscript index bb28945641..cf513eb5a1 100644 --- a/libs/gtkmm2ext/SConscript +++ b/libs/gtkmm2ext/SConscript @@ -24,10 +24,10 @@ gtkmm2ext.Merge ([ domain = 'libgtkmm2ext' -gtkmm2ext.Append(DOMAIN=domain,MAJOR=0,MINOR=8,MICRO=2) +gtkmm2ext.Append(DOMAIN=domain,MAJOR=0,MINOR=8,MICRO=3) gtkmm2ext.Append(CXXFLAGS="-DPACKAGE=\\\"" + domain + "\\\"") gtkmm2ext.Append(CXXFLAGS="-DLIBSIGC_DISABLE_DEPRECATED") -gtkmm2ext.Append(CPPPATH='#libs/surfaces/control_protocol') +#gtkmm2ext.Append(CPPPATH='#libs/surfaces/control_protocol') gtkmm2ext.Append(PACKAGE=domain) gtkmm2ext.Append(POTFILE=domain + '.pot') @@ -42,6 +42,7 @@ fastmeter.cc gtk_ui.cc hexentry.cc idle_adjustment.cc +pathlist.cc pixscroller.cc popup.cc prompter.cc diff --git a/libs/gtkmm2ext/gtkmm2ext/pathlist.h b/libs/gtkmm2ext/gtkmm2ext/pathlist.h new file mode 100644 index 0000000000..f4a5973d5a --- /dev/null +++ b/libs/gtkmm2ext/gtkmm2ext/pathlist.h @@ -0,0 +1,63 @@ +/* + Copyright (C) 2006 Paul Davis + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + +*/ + +#ifndef __gtkmm2ext_pathlist_h__ +#define __gtkmm2ext_pathlist_h__ + +#include <vector> +#include <string> + +#include <gtkmm.h> + +namespace Gtkmm2ext { + +class PathList : public Gtk::VBox +{ + public: + PathList (); + ~PathList () {}; + + std::vector<std::string> get_paths (); + void set_paths (std::vector<std::string> paths); + + sigc::signal<void> PathsUpdated; + + protected: + Gtk::Button add_btn; + Gtk::Button subtract_btn; + + void add_btn_clicked (); + void subtract_btn_clicked (); + + private: + struct PathColumns : public Gtk::TreeModel::ColumnRecord { + PathColumns() { add (paths); } + Gtk::TreeModelColumn<std::string> paths; + }; + PathColumns path_columns; + + Glib::RefPtr<Gtk::ListStore> _store; + Gtk::TreeView _view; + + void selection_changed (); +}; + +} // namespace Gtkmm2ext + +#endif // __gtkmm2ext_pathlist_h__ diff --git a/libs/gtkmm2ext/pathlist.cc b/libs/gtkmm2ext/pathlist.cc new file mode 100644 index 0000000000..7b3448ed5f --- /dev/null +++ b/libs/gtkmm2ext/pathlist.cc @@ -0,0 +1,124 @@ +/* + Copyright (C) 2006 Paul Davis + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + +*/ + +#include <gtkmm2ext/pathlist.h> + +#include "i18n.h" + +using namespace std; +using namespace Gtkmm2ext; + +PathList::PathList () + : + add_btn(_("+")), + subtract_btn(_("-")), + path_columns(), + _store(Gtk::ListStore::create(path_columns)), + _view(_store) +{ + _view.append_column(_("Paths"), path_columns.paths); + _view.set_size_request(-1, 100); + _view.set_headers_visible (false); + + Gtk::ScrolledWindow* scroll = manage(new Gtk::ScrolledWindow); + scroll->set_policy (Gtk::POLICY_AUTOMATIC, Gtk::POLICY_AUTOMATIC); + scroll->add(_view); + + add (*scroll); + + Gtk::HBox* btn_box = manage(new Gtk::HBox); + btn_box->add(add_btn); + btn_box->add(subtract_btn); + + add (*btn_box); + + add_btn.signal_clicked().connect (mem_fun(*this, &PathList::add_btn_clicked)); + subtract_btn.signal_clicked().connect (mem_fun(*this, &PathList::subtract_btn_clicked)); + _view.get_selection()->signal_changed().connect (mem_fun(*this, &PathList::selection_changed)); +} + +vector<string> +PathList::get_paths () +{ + vector<string> paths; + + Gtk::TreeModel::Children children(_store->children()); + + for (Gtk::TreeIter iter = children.begin(); iter != children.end(); ++iter) { + Gtk::ListStore::Row row = *iter; + + paths.push_back(row[path_columns.paths]); + } + + return paths; +} + +void +PathList::set_paths (vector<string> paths) +{ + _store->clear(); + + for (vector<string>::iterator i = paths.begin(); i != paths.end(); ++i) { + Gtk::ListStore::iterator iter = _store->append(); + Gtk::ListStore::Row row = *iter; + row[path_columns.paths] = *i; + } +} + +void +PathList::add_btn_clicked () +{ + Gtk::FileChooserDialog path_chooser (_("Path Chooser"), Gtk::FILE_CHOOSER_ACTION_SELECT_FOLDER); + + path_chooser.add_button (Gtk::Stock::ADD, Gtk::RESPONSE_OK); + path_chooser.add_button (Gtk::Stock::CANCEL, Gtk::RESPONSE_CANCEL); + + int result = path_chooser.run (); + + if (result == Gtk::RESPONSE_OK) { + string pathname = path_chooser.get_filename(); + + if (pathname.length ()) { + Gtk::ListStore::iterator iter = _store->append (); + Gtk::ListStore::Row row = *iter; + row[path_columns.paths] = pathname; + + PathsUpdated (); // EMIT_SIGNAL + } + } +} + +void +PathList::subtract_btn_clicked () +{ + Gtk::ListStore::iterator iter = _view.get_selection()->get_selected(); + _store->erase (iter); + + PathsUpdated (); // EMIT_SIGNAL +} + +void +PathList::selection_changed () +{ + if (_view.get_selection()->count_selected_rows ()) { + subtract_btn.set_sensitive (true); + } else { + subtract_btn.set_sensitive (false); + } +} diff --git a/libs/midi++2/SConscript b/libs/midi++2/SConscript index e0df59c7da..65d0882dce 100644 --- a/libs/midi++2/SConscript +++ b/libs/midi++2/SConscript @@ -18,7 +18,6 @@ fd_midiport.cc fifomidi.cc midi.cc midichannel.cc -midicontrollable.cc midifactory.cc midimanager.cc midiparser.cc diff --git a/libs/midi++2/midi++/channel.h b/libs/midi++2/midi++/channel.h index 0d24bf8bbe..e1ffb954a5 100644 --- a/libs/midi++2/midi++/channel.h +++ b/libs/midi++2/midi++/channel.h @@ -155,7 +155,7 @@ class Channel : public sigc::trackable { void process_reset (Parser &); }; -}; /* namespace MIDI */ +} // namespace MIDI #endif // __midichannel_h__ diff --git a/libs/midi++2/midi++/controllable.h b/libs/midi++2/midi++/controllable.h deleted file mode 100644 index 44249cfa4f..0000000000 --- a/libs/midi++2/midi++/controllable.h +++ /dev/null @@ -1,92 +0,0 @@ -/* - Copyright (C) 1998-99 Paul Barton-Davis - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - - $Id$ -*/ - -#ifndef __qm_midicontrollable_h__ -#define __qm_midicontrollable_h__ - -#include <string> - -#include <sigc++/sigc++.h> - -#include <midi++/types.h> - -namespace MIDI { - -class Channel; -class Port; -class Parser; - -class Controllable : public sigc::trackable -{ - public: - Controllable (Port *, bool bistate = false); - virtual ~Controllable (); - - void midi_rebind (Port *, channel_t channel=-1); - void midi_forget (); - void learn_about_external_control (); - void stop_learning (); - void drop_external_control (); - - virtual void set_value (float) = 0; - - sigc::signal<void> learning_started; - sigc::signal<void> learning_stopped; - - bool get_control_info (channel_t&, eventType&, byte&); - void set_control_type (channel_t, eventType, byte); - - bool get_midi_feedback () { return feedback; } - void set_midi_feedback (bool val) { feedback = val; } - - Port * get_port() { return port; } - - std::string control_description() const { return _control_description; } - - void send_midi_feedback (float val, timestamp_t timestamp); - - private: - bool bistate; - int midi_msg_id; /* controller ID or note number */ - sigc::connection midi_sense_connection[2]; - sigc::connection midi_learn_connection; - size_t connections; - Port* port; - eventType control_type; - byte control_additional; - channel_t control_channel; - std::string _control_description; - bool feedback; - - void midi_receiver (Parser &p, byte *, size_t); - void midi_sense_note (Parser &, EventTwoBytes *, bool is_on); - void midi_sense_note_on (Parser &p, EventTwoBytes *tb); - void midi_sense_note_off (Parser &p, EventTwoBytes *tb); - void midi_sense_controller (Parser &, EventTwoBytes *); - void midi_sense_program_change (Parser &, byte); - void midi_sense_pitchbend (Parser &, pitchbend_t); - - void bind_midi (channel_t, eventType, byte); -}; - -}; /* namespace MIDI */ - -#endif // __qm_midicontrollable_h__ - diff --git a/libs/midi++2/midi++/coremidi_midiport.h b/libs/midi++2/midi++/coremidi_midiport.h index 046b170bce..30e07e01a5 100644 --- a/libs/midi++2/midi++/coremidi_midiport.h +++ b/libs/midi++2/midi++/coremidi_midiport.h @@ -62,6 +62,6 @@ class CoreMidi_MidiPort:public Port { bool firstrecv; }; -}; /* namespace MIDI */ +} // namespace MIDI #endif // __coremidi_midiport_h__ diff --git a/libs/midi++2/midi++/factory.h b/libs/midi++2/midi++/factory.h index 3fa57b6676..e29d7543f8 100644 --- a/libs/midi++2/midi++/factory.h +++ b/libs/midi++2/midi++/factory.h @@ -35,6 +35,6 @@ class PortFactory { const std::string &reqstr); }; -}; /* namespace MIDI */ +} // namespace MIDI #endif // __midi_factory_h__ diff --git a/libs/midi++2/midi++/fd_midiport.h b/libs/midi++2/midi++/fd_midiport.h index e84dc47794..3ff05b21c8 100644 --- a/libs/midi++2/midi++/fd_midiport.h +++ b/libs/midi++2/midi++/fd_midiport.h @@ -93,6 +93,6 @@ class FD_MidiPort : public Port int do_slow_write (byte *msg, unsigned int msglen); }; -}; /*namespace MIDI */ +} // namespace MIDI #endif // __fd_midiport_h__ diff --git a/libs/midi++2/midi++/fifomidi.h b/libs/midi++2/midi++/fifomidi.h index eb8778d4d5..200d90eda8 100644 --- a/libs/midi++2/midi++/fifomidi.h +++ b/libs/midi++2/midi++/fifomidi.h @@ -42,6 +42,6 @@ class FIFO_MidiPort : public MIDI::FD_MidiPort void open (PortRequest &req); }; -}; /* namespace MIDI */ +} // namespace MIDI #endif // __fifomidi_h__ diff --git a/libs/midi++2/midi++/manager.h b/libs/midi++2/midi++/manager.h index ddf5c0f8cd..d5a49eb0a3 100644 --- a/libs/midi++2/midi++/manager.h +++ b/libs/midi++2/midi++/manager.h @@ -88,6 +88,6 @@ class Manager { void close_ports (); }; -}; /* namespace MIDI */ +} // namespace MIDI #endif // __midi_manager_h__ diff --git a/libs/midi++2/midi++/mmc.h b/libs/midi++2/midi++/mmc.h index 7b51b33a72..2d569f122c 100644 --- a/libs/midi++2/midi++/mmc.h +++ b/libs/midi++2/midi++/mmc.h @@ -82,7 +82,7 @@ class MachineControl : public sigc::trackable cmdRecordStrobeVariable = 0x55, cmdWait = 0x7C, - cmdResume = 0x7F, + cmdResume = 0x7F }; MachineControl (Port &port, @@ -256,6 +256,6 @@ class MachineControl : public sigc::trackable void write_track_record_ready (byte *, size_t len); }; -}; /* namespace MIDI */ +} // namespace MIDI #endif /* __midipp_mmc_h_h__ */ diff --git a/libs/midi++2/midi++/nullmidi.h b/libs/midi++2/midi++/nullmidi.h index 04c7d438bf..75445facb7 100644 --- a/libs/midi++2/midi++/nullmidi.h +++ b/libs/midi++2/midi++/nullmidi.h @@ -58,6 +58,6 @@ class Null_MidiPort : public Port virtual int selectable() const { return -1; } }; -}; /* namespace MIDI */ +} // namespace MIDI #endif // __nullmidi_h__ diff --git a/libs/midi++2/midi++/parser.h b/libs/midi++2/midi++/parser.h index 4ac07cc15d..36d19f3da9 100644 --- a/libs/midi++2/midi++/parser.h +++ b/libs/midi++2/midi++/parser.h @@ -183,7 +183,7 @@ class Parser : public sigc::trackable { void process_mtc_quarter_frame (byte *msg); }; -}; /* namespace MIDI */ +} // namespace MIDI #endif // __midi_parse_h__ diff --git a/libs/midi++2/midi++/port.h b/libs/midi++2/midi++/port.h index 919afb3755..a706127eff 100644 --- a/libs/midi++2/midi++/port.h +++ b/libs/midi++2/midi++/port.h @@ -42,7 +42,7 @@ class Port : public sigc::trackable { ALSA_Sequencer, CoreMidi_MidiPort, Null, - FIFO, + FIFO }; Port (PortRequest &); @@ -152,7 +152,6 @@ class Port : public sigc::trackable { static size_t nports; }; -}; /* namespace MIDI */ +} // namespace MIDI #endif // __libmidi_port_h__ - diff --git a/libs/midi++2/midi++/port_request.h b/libs/midi++2/midi++/port_request.h index 28a0d1d70b..86838dd04d 100644 --- a/libs/midi++2/midi++/port_request.h +++ b/libs/midi++2/midi++/port_request.h @@ -54,7 +54,7 @@ struct PortRequest { const std::string &xtype); }; -}; /* namespace MIDI */ +} // namespace MIDI #endif // __midi_port_request_h__ diff --git a/libs/midi++2/midi++/types.h b/libs/midi++2/midi++/types.h index dc70381d5b..797c50a31b 100644 --- a/libs/midi++2/midi++/types.h +++ b/libs/midi++2/midi++/types.h @@ -59,10 +59,10 @@ namespace MIDI { enum MTC_Status { MTC_Stopped = 0, MTC_Forward, - MTC_Backward, + MTC_Backward }; -}; /* namespace MIDI */ +} // namespace MIDI #endif // __midi_types_h__ diff --git a/libs/midi++2/midicontrollable.cc b/libs/midi++2/midicontrollable.cc deleted file mode 100644 index bb98678854..0000000000 --- a/libs/midi++2/midicontrollable.cc +++ /dev/null @@ -1,326 +0,0 @@ -/* - Copyright (C) 1998-99 Paul Barton-Davis - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - - $Id$ -*/ - -#include <cstdio> /* for sprintf, sigh */ -#include <pbd/error.h> -#include <midi++/port.h> -#include <midi++/channel.h> -#include <midi++/controllable.h> - -using namespace sigc; -using namespace MIDI; -using namespace PBD; - -Controllable::Controllable (Port *p, bool is_bistate) -{ - control_type = none; - _control_description = "MIDI Control: none"; - control_additional = (byte) -1; - bistate = is_bistate; - connections = 0; - feedback = true; // for now - - /* use channel 0 ("1") as the initial channel */ - - midi_rebind (p, 0); -} - -Controllable::~Controllable () -{ - drop_external_control (); -} - -void -Controllable::midi_forget () -{ - /* stop listening for incoming messages, but retain - our existing event + type information. - */ - - if (connections > 0) { - midi_sense_connection[0].disconnect (); - } - - if (connections > 1) { - midi_sense_connection[1].disconnect (); - } - - connections = 0; - midi_learn_connection.disconnect (); - -} - -void -Controllable::midi_rebind (Port *p, channel_t c) -{ - if ((port = p) == 0) { - midi_forget (); - } else { - if (c >= 0) { - bind_midi (c, control_type, control_additional); - } else { - midi_forget (); - } - } -} - -void -Controllable::learn_about_external_control () -{ - drop_external_control (); - - if (port) { - midi_learn_connection = port->input()->any.connect (mem_fun (*this, &Controllable::midi_receiver)); - learning_started (); - - } else { - info << "No MIDI port specified - external control disabled" << endmsg; - } -} - -void -Controllable::stop_learning () -{ - midi_learn_connection.disconnect (); -} - -void -Controllable::drop_external_control () -{ - if (connections > 0) { - midi_sense_connection[0].disconnect (); - } - if (connections > 1) { - midi_sense_connection[1].disconnect (); - } - - connections = 0; - midi_learn_connection.disconnect (); - - control_type = none; - control_additional = (byte) -1; -} - -void -Controllable::midi_sense_note_on (Parser &p, EventTwoBytes *tb) -{ - midi_sense_note (p, tb, true); -} - -void -Controllable::midi_sense_note_off (Parser &p, EventTwoBytes *tb) -{ - midi_sense_note (p, tb, false); -} - -void -Controllable::midi_sense_note (Parser &p, EventTwoBytes *msg, bool is_on) -{ - if (!bistate) { - set_value (msg->note_number/127.0); - } else { - - /* Note: parser handles the use of zero velocity to - mean note off. if we get called with is_on=true, then we - got a *real* note on. - */ - - if (msg->note_number == control_additional) { - set_value (is_on ? 1 : 0); - } - } -} - -void -Controllable::midi_sense_controller (Parser &, EventTwoBytes *msg) -{ - if (control_additional == msg->controller_number) { - if (!bistate) { - set_value (msg->value/127.0); - } else { - if (msg->value > 64.0) { - set_value (1); - } else { - set_value (0); - } - } - } -} - -void -Controllable::midi_sense_program_change (Parser &p, byte msg) -{ - /* XXX program change messages make no sense for bistates */ - - if (!bistate) { - set_value (msg/127.0); - } -} - -void -Controllable::midi_sense_pitchbend (Parser &p, pitchbend_t pb) -{ - /* pitchbend messages make no sense for bistates */ - - /* XXX gack - get rid of assumption about typeof pitchbend_t */ - - set_value ((pb/(float) SHRT_MAX)); -} - -void -Controllable::midi_receiver (Parser &p, byte *msg, size_t len) -{ - /* we only respond to channel messages */ - - if ((msg[0] & 0xF0) < 0x80 || (msg[0] & 0xF0) > 0xE0) { - return; - } - - /* if the our port doesn't do input anymore, forget it ... */ - - if (!port->input()) { - return; - } - - bind_midi ((channel_t) (msg[0] & 0xf), eventType (msg[0] & 0xF0), msg[1]); - - learning_stopped (); -} - -void -Controllable::bind_midi (channel_t chn, eventType ev, MIDI::byte additional) -{ - char buf[64]; - - drop_external_control (); - - control_type = ev; - control_channel = chn; - control_additional = additional; - - if (port == 0 || port->input() == 0) { - return; - } - - Parser& p = *port->input(); - - int chn_i = chn; - switch (ev) { - case MIDI::off: - midi_sense_connection[0] = p.channel_note_off[chn_i].connect - (mem_fun (*this, &Controllable::midi_sense_note_off)); - - /* if this is a bistate, connect to noteOn as well, - and we'll toggle back and forth between the two. - */ - - if (bistate) { - midi_sense_connection[1] = p.channel_note_on[chn_i].connect - (mem_fun (*this, &Controllable::midi_sense_note_on)); - connections = 2; - } else { - connections = 1; - } - _control_description = "MIDI control: NoteOff"; - break; - - case MIDI::on: - midi_sense_connection[0] = p.channel_note_on[chn_i].connect - (mem_fun (*this, &Controllable::midi_sense_note_on)); - if (bistate) { - midi_sense_connection[1] = p.channel_note_off[chn_i].connect - (mem_fun (*this, &Controllable::midi_sense_note_off)); - connections = 2; - } else { - connections = 1; - } - _control_description = "MIDI control: NoteOn"; - break; - - case MIDI::controller: - midi_sense_connection[0] = p.channel_controller[chn_i].connect - (mem_fun (*this, &Controllable::midi_sense_controller)); - connections = 1; - snprintf (buf, sizeof (buf), "MIDI control: Controller %d", control_additional); - _control_description = buf; - break; - - case MIDI::program: - if (!bistate) { - midi_sense_connection[0] = p.channel_program_change[chn_i].connect - (mem_fun (*this, - &Controllable::midi_sense_program_change)); - connections = 1; - _control_description = "MIDI control: ProgramChange"; - } - break; - - case MIDI::pitchbend: - if (!bistate) { - midi_sense_connection[0] = p.channel_pitchbend[chn_i].connect - (mem_fun (*this, &Controllable::midi_sense_pitchbend)); - connections = 1; - _control_description = "MIDI control: Pitchbend"; - } - break; - - default: - break; - } -} - -void -Controllable::set_control_type (channel_t chn, eventType ev, MIDI::byte additional) -{ - bind_midi (chn, ev, additional); -} - -bool -Controllable::get_control_info (channel_t& chn, eventType& ev, byte& additional) -{ - if (control_type == none) { - chn = -1; - return false; - } - - ev = control_type; - chn = control_channel; - additional = control_additional; - - return true; -} - - -void -Controllable::send_midi_feedback (float val, timestamp_t timestamp) -{ - byte msg[3]; - - if (port == 0 || control_type == none) { - return; - } - - msg[0] = (control_type & 0xF0) | (control_channel & 0xF); - msg[1] = control_additional; - msg[2] = (byte) (val * 127.0f); - - port->write (msg, 3, timestamp); -} - diff --git a/libs/midi++2/midiparser.cc b/libs/midi++2/midiparser.cc index 975a77a2c5..7c29478413 100644 --- a/libs/midi++2/midiparser.cc +++ b/libs/midi++2/midiparser.cc @@ -101,7 +101,7 @@ Parser::midi_event_type_name (eventType t) default: return "unknow MIDI event type"; } -}; +} Parser::Parser (Port &p) : _port (p) diff --git a/libs/pbd/pbd/basename.h b/libs/pbd/pbd/basename.h index 35aebe166c..a7e36acff0 100644 --- a/libs/pbd/pbd/basename.h +++ b/libs/pbd/pbd/basename.h @@ -8,6 +8,6 @@ namespace PBD extern std::string basename_nosuffix (const std::string&); -}; +} // namespace PBD #endif // __stupid_basename_h__ diff --git a/libs/pbd/pbd/rcu.h b/libs/pbd/pbd/rcu.h new file mode 100644 index 0000000000..6d9586cb3c --- /dev/null +++ b/libs/pbd/pbd/rcu.h @@ -0,0 +1,120 @@ +#ifndef __pbd_rcu_h__ +#define __pbd_rcu_h__ + +#include "boost/shared_ptr.hpp" +#include "glibmm/thread.h" + +#include <list> + +template<class T> +class RCUManager +{ +public: + + RCUManager (T* new_rcu_value) + : m_rcu_value(new_rcu_value) + { + + } + + virtual ~RCUManager() { } + + boost::shared_ptr<T> reader () const { return m_rcu_value; } + + // should be private + virtual boost::shared_ptr<T> write_copy () = 0; + + // should be private + virtual void update (boost::shared_ptr<T> new_value) = 0; + +protected: + + boost::shared_ptr<T> m_rcu_value; + + +}; + + +template<class T> +class SerializedRCUManager : public RCUManager<T> +{ +public: + + SerializedRCUManager(T* new_rcu_value) + : RCUManager<T>(new_rcu_value) + { + + } + + virtual boost::shared_ptr<T> write_copy () + { + m_lock.lock(); + + // I hope this is doing what I think it is doing :) + boost::shared_ptr<T> new_copy(new T(*RCUManager<T>::m_rcu_value)); + + // XXX todo remove old copies with only 1 reference from the list. + + return new_copy; + } + + virtual void update (boost::shared_ptr<T> new_value) + { + // So a current reader doesn't hold the only reference to + // the existing value when we assign it a new value which + // should ensure that deletion of old values doesn't + // occur in a reader thread. + boost::shared_ptr<T> old_copy = RCUManager<T>::m_rcu_value; + + // we hold the lock at this point effectively blocking + // other writers. + RCUManager<T>::m_rcu_value = new_value; + + + // XXX add the old value to the list of old copies. + + m_lock.unlock(); + } + +private: + Glib::Mutex m_lock; + + std::list<boost::shared_ptr<T> > m_old_values; +}; + +template<class T> +class RCUWriter +{ +public: + + RCUWriter(RCUManager<T>& manager) + : m_manager(manager) + { + m_copy = m_manager.write_copy(); + } + + ~RCUWriter() + { + // we can check here that the refcount of m_copy is 1 + + if(m_copy.use_count() == 1) { + m_manager.update(m_copy); + } else { + + // critical error. + } + + } + + // or operator boost::shared_ptr<T> (); + boost::shared_ptr<T> get_copy() { return m_copy; } + +private: + + RCUManager<T>& m_manager; + + // preferably this holds a pointer to T + boost::shared_ptr<T> m_copy; +}; + +#endif /* __pbd_rcu_h__ */ diff --git a/libs/pbd/pbd/xml++.h b/libs/pbd/pbd/xml++.h index afb896e1d5..5dcb4f084a 100644 --- a/libs/pbd/pbd/xml++.h +++ b/libs/pbd/pbd/xml++.h @@ -37,7 +37,6 @@ private: string _filename; XMLNode *_root; int _compression; - bool _initialized; public: XMLTree(); @@ -45,9 +44,8 @@ public: XMLTree(const XMLTree *); ~XMLTree(); - bool initialized() const { return _initialized; }; XMLNode *root() const { return _root; }; - XMLNode *set_root(XMLNode *n) { _initialized = true; return _root = n; }; + XMLNode *set_root(XMLNode *n) { return _root = n; }; const string & filename() const { return _filename; }; const string & set_filename(const string &fn) { return _filename = fn; }; @@ -69,7 +67,6 @@ public: class XMLNode { private: - bool _initialized; string _name; bool _is_content; string _content; @@ -83,18 +80,17 @@ public: XMLNode(const XMLNode&); ~XMLNode(); - bool initialized() const { return _initialized; }; const string name() const { return _name; }; bool is_content() const { return _is_content; }; const string & content() const { return _content; }; - const string & set_content(const string &); + const string & set_content (const string &); XMLNode *add_content(const string & = string()); - const XMLNodeList & children(const string & = string()) const; - XMLNode *add_child(const char *); - XMLNode *add_child_copy(const XMLNode&); - void add_child_nocopy (XMLNode&); + const XMLNodeList & children (const string & = string()) const; + XMLNode *add_child (const char *); + XMLNode *add_child_copy (const XMLNode&); + void add_child_nocopy (XMLNode&); const XMLPropertyList & properties() const { return _proplist; }; XMLProperty *property(const char * ); diff --git a/libs/pbd/pool.cc b/libs/pbd/pool.cc index 089766482d..be8032b7b6 100644 --- a/libs/pbd/pool.cc +++ b/libs/pbd/pool.cc @@ -70,7 +70,7 @@ Pool::alloc () } else { return ptr; } -}; +} void Pool::release (void *ptr) diff --git a/libs/pbd/stateful.cc b/libs/pbd/stateful.cc index 16aa528f59..786410e817 100644 --- a/libs/pbd/stateful.cc +++ b/libs/pbd/stateful.cc @@ -134,4 +134,3 @@ Stateful::instant_xml (const string& str, const string& dir) return 0; } - diff --git a/libs/pbd/whitespace.cc b/libs/pbd/whitespace.cc index 7f74940457..e35a8a8c0e 100644 --- a/libs/pbd/whitespace.cc +++ b/libs/pbd/whitespace.cc @@ -7,9 +7,11 @@ strip_whitespace_edges (string& str) { string::size_type i; string::size_type len; - string::size_type s; + string::size_type s; len = str.length(); + + /* strip front */ for (i = 0; i < len; ++i) { if (isgraph (str[i])) { @@ -17,14 +19,26 @@ strip_whitespace_edges (string& str) } } - s = i; + /* strip back */ + + if (len > 1) { + + s = i; + i = len - 1; + + do { + if (isgraph (str[i]) || i == 0) { + break; + } - for (i = len - 1; i >= 0; --i) { - if (isgraph (str[i])) { - break; - } - } + --i; + + } while (true); + + str = str.substr (s, (i - s) + 1); - str = str.substr (s, (i - s) + 1); + } else { + str = str.substr (s); + } } diff --git a/libs/pbd/xml++.cc b/libs/pbd/xml++.cc index e496d8b2fd..03fa116279 100644 --- a/libs/pbd/xml++.cc +++ b/libs/pbd/xml++.cc @@ -12,117 +12,112 @@ static void writenode(xmlDocPtr, XMLNode *, xmlNodePtr, int); XMLTree::XMLTree() : _filename(), - _root(), - _compression(0), - _initialized(false) + _root(0), + _compression(0) { } XMLTree::XMLTree(const string &fn) : _filename(fn), _root(0), - _compression(0), - _initialized(false) + _compression(0) { read(); } XMLTree::XMLTree(const XMLTree * from) { - _filename = from->filename(); - _root = new XMLNode(*from->root()); - _compression = from->compression(); - _initialized = true; + _filename = from->filename(); + _root = new XMLNode(*from->root()); + _compression = from->compression(); } XMLTree::~XMLTree() { - if (_initialized && _root) + if (_root) { delete _root; + } } int XMLTree::set_compression(int c) { - if (c > 9) - c = 9; - - if (c < 0) - c = 0; - - _compression = c; - - return _compression; + if (c > 9) { + c = 9; + } else if (c < 0) { + c = 0; + } + + _compression = c; + + return _compression; } bool XMLTree::read(void) { - xmlDocPtr doc; - - if (_root) { + xmlDocPtr doc; + + if (_root) { delete _root; _root = 0; - } - - xmlKeepBlanksDefault(0); - - doc = xmlParseFile(_filename.c_str()); - if (!doc) { - _initialized = false; - return false; - } - - _root = readnode(xmlDocGetRootElement(doc)); - xmlFreeDoc(doc); - _initialized = true; - - return true; + } + + xmlKeepBlanksDefault(0); + + doc = xmlParseFile(_filename.c_str()); + if (!doc) { + return false; + } + + _root = readnode(xmlDocGetRootElement(doc)); + xmlFreeDoc(doc); + + return true; } bool XMLTree::read_buffer(const string & buffer) { - xmlDocPtr doc; - - _filename = ""; - - if (_root) { + xmlDocPtr doc; + + _filename = ""; + + if (_root) { delete _root; _root = 0; - } - - doc = xmlParseMemory((char *) buffer.c_str(), buffer.length()); - if (!doc) { - _initialized = false; + } + + doc = xmlParseMemory((char *) buffer.c_str(), buffer.length()); + if (!doc) { return false; - } - - _root = readnode(xmlDocGetRootElement(doc)); - xmlFreeDoc(doc); - _initialized = true; - - return true; + } + + _root = readnode(xmlDocGetRootElement(doc)); + xmlFreeDoc(doc); + + return true; } bool XMLTree::write(void) const { - xmlDocPtr doc; - XMLNodeList children; - int result; - - xmlKeepBlanksDefault(0); - doc = xmlNewDoc((xmlChar *) "1.0"); - xmlSetDocCompressMode(doc, _compression); - writenode(doc, _root, doc->children, 1); - result = xmlSaveFormatFile(_filename.c_str(), doc, 1); - xmlFreeDoc(doc); - - if (result == -1) + xmlDocPtr doc; + XMLNodeList children; + int result; + + xmlKeepBlanksDefault(0); + doc = xmlNewDoc((xmlChar *) "1.0"); + xmlSetDocCompressMode(doc, _compression); + writenode(doc, _root, doc->children, 1); + result = xmlSaveFormatFile(_filename.c_str(), doc, 1); + xmlFreeDoc(doc); + + if (result == -1) { return false; - - return true; + } + + return true; } void @@ -142,105 +137,104 @@ XMLTree::debug(FILE* out) const const string & XMLTree::write_buffer(void) const { - static string retval; - char *ptr; - int len; - xmlDocPtr doc; - XMLNodeList children; - - xmlKeepBlanksDefault(0); - doc = xmlNewDoc((xmlChar *) "1.0"); - xmlSetDocCompressMode(doc, _compression); - writenode(doc, _root, doc->children, 1); - xmlDocDumpMemory(doc, (xmlChar **) & ptr, &len); - xmlFreeDoc(doc); - - retval = ptr; - - free(ptr); - - return retval; + static string retval; + char *ptr; + int len; + xmlDocPtr doc; + XMLNodeList children; + + xmlKeepBlanksDefault(0); + doc = xmlNewDoc((xmlChar *) "1.0"); + xmlSetDocCompressMode(doc, _compression); + writenode(doc, _root, doc->children, 1); + xmlDocDumpMemory(doc, (xmlChar **) & ptr, &len); + xmlFreeDoc(doc); + + retval = ptr; + + free(ptr); + + return retval; } XMLNode::XMLNode(const string & n) : _name(n), _is_content(false), _content(string()) { - - if (_name.empty()) - _initialized = false; - else - _initialized = true; } XMLNode::XMLNode(const string & n, const string & c) - :_name(string()), _is_content(true), _content(c) + :_name(n), _is_content(true), _content(c) { - _initialized = true; } XMLNode::XMLNode(const XMLNode& from) - : _initialized(false) { - XMLPropertyList props; - XMLPropertyIterator curprop; - XMLNodeList nodes; - XMLNodeIterator curnode; - - _name = from.name(); - set_content(from.content()); - - props = from.properties(); - for (curprop = props.begin(); curprop != props.end(); curprop++) - add_property((*curprop)->name().c_str(), (*curprop)->value()); - - nodes = from.children(); - for (curnode = nodes.begin(); curnode != nodes.end(); curnode++) + XMLPropertyList props; + XMLPropertyIterator curprop; + XMLNodeList nodes; + XMLNodeIterator curnode; + + _name = from.name(); + set_content(from.content()); + + props = from.properties(); + for (curprop = props.begin(); curprop != props.end(); ++curprop) { + add_property((*curprop)->name().c_str(), (*curprop)->value()); + } + + nodes = from.children(); + for (curnode = nodes.begin(); curnode != nodes.end(); ++curnode) { add_child_copy(**curnode); + } } XMLNode::~XMLNode() { - XMLNodeIterator curchild; - XMLPropertyIterator curprop; - - for (curchild = _children.begin(); curchild != _children.end(); - curchild++) + XMLNodeIterator curchild; + XMLPropertyIterator curprop; + + for (curchild = _children.begin(); curchild != _children.end(); ++curchild) { delete *curchild; - - for (curprop = _proplist.begin(); curprop != _proplist.end(); - curprop++) + } + + for (curprop = _proplist.begin(); curprop != _proplist.end(); ++curprop) { delete *curprop; + } } const string & XMLNode::set_content(const string & c) { - if (c.empty()) + if (c.empty()) { _is_content = false; - else + } else { _is_content = true; - - _content = c; - - return _content; + } + + _content = c; + + return _content; } const XMLNodeList & XMLNode::children(const string & n) const { - static XMLNodeList retval; - XMLNodeConstIterator cur; - - if (n.length() == 0) + static XMLNodeList retval; + XMLNodeConstIterator cur; + + if (n.length() == 0) { return _children; - - retval.erase(retval.begin(), retval.end()); - - for (cur = _children.begin(); cur != _children.end(); cur++) - if ((*cur)->name() == n) - retval.insert(retval.end(), *cur); - - return retval; + } + + retval.erase(retval.begin(), retval.end()); + + for (cur = _children.begin(); cur != _children.end(); ++cur) { + if ((*cur)->name() == n) { + retval.insert(retval.end(), *cur); + } + } + + return retval; } XMLNode * @@ -273,8 +267,10 @@ XMLProperty * XMLNode::property(const char * n) { string ns(n); - if (_propmap.find(ns) == _propmap.end()) + if (_propmap.find(ns) == _propmap.end()) { return 0; + } + return _propmap[ns]; } @@ -288,8 +284,9 @@ XMLNode::add_property(const char * n, const string & v) XMLProperty *tmp = new XMLProperty(ns, v); - if (!tmp) + if (!tmp) { return 0; + } _propmap[tmp->name()] = tmp; _proplist.insert(_proplist.end(), tmp); @@ -307,43 +304,43 @@ XMLNode::add_property(const char * n, const char * v) void XMLNode::remove_property(const string & n) { - if (_propmap.find(n) != _propmap.end()) { + if (_propmap.find(n) != _propmap.end()) { _proplist.remove(_propmap[n]); _propmap.erase(n); - } + } } void XMLNode::remove_nodes(const string & n) { - XMLNodeIterator i = _children.begin(); - XMLNodeIterator tmp; - - while (i != _children.end()) { - tmp = i; - ++tmp; - if ((*i)->name() == n) { - _children.erase (i); - } - i = tmp; - } + XMLNodeIterator i = _children.begin(); + XMLNodeIterator tmp; + + while (i != _children.end()) { + tmp = i; + ++tmp; + if ((*i)->name() == n) { + _children.erase (i); + } + i = tmp; + } } void XMLNode::remove_nodes_and_delete(const string & n) { - XMLNodeIterator i = _children.begin(); - XMLNodeIterator tmp; - - while (i != _children.end()) { - tmp = i; - ++tmp; - if ((*i)->name() == n) { - delete *i; - _children.erase (i); - } - i = tmp; - } + XMLNodeIterator i = _children.begin(); + XMLNodeIterator tmp; + + while (i != _children.end()) { + tmp = i; + ++tmp; + if ((*i)->name() == n) { + delete *i; + _children.erase (i); + } + i = tmp; + } } XMLProperty::XMLProperty(const string &n, const string &v) @@ -359,64 +356,65 @@ XMLProperty::~XMLProperty() static XMLNode * readnode(xmlNodePtr node) { - string name, content; - xmlNodePtr child; - XMLNode *tmp; - xmlAttrPtr attr; - - if (node->name) + string name, content; + xmlNodePtr child; + XMLNode *tmp; + xmlAttrPtr attr; + + if (node->name) { name = (char *) node->name; - - tmp = new XMLNode(name); - - for (attr = node->properties; attr; attr = attr->next) { + } + + tmp = new XMLNode(name); + + for (attr = node->properties; attr; attr = attr->next) { content = ""; - if (attr->children) - content = (char *) attr->children->content; + if (attr->children) { + content = (char *) attr->children->content; + } tmp->add_property((char *) attr->name, content); - } - - if (node->content) + } + + if (node->content) { tmp->set_content((char *) node->content); - else + } else { tmp->set_content(string()); - - for (child = node->children; child; child = child->next) - tmp->add_child_nocopy (*readnode(child)); - - return tmp; + } + + for (child = node->children; child; child = child->next) { + tmp->add_child_nocopy (*readnode(child)); + } + + return tmp; } static void -writenode(xmlDocPtr doc, XMLNode * n, xmlNodePtr p, int root = - 0) +writenode(xmlDocPtr doc, XMLNode * n, xmlNodePtr p, int root = 0) { - XMLPropertyList props; - XMLPropertyIterator curprop; - XMLNodeList children; - XMLNodeIterator curchild; - xmlNodePtr node; - - if (root) - node = doc->children = - xmlNewDocNode(doc, 0, (xmlChar *) n->name().c_str(), 0); - - else + XMLPropertyList props; + XMLPropertyIterator curprop; + XMLNodeList children; + XMLNodeIterator curchild; + xmlNodePtr node; + + if (root) { + node = doc->children = xmlNewDocNode(doc, 0, (xmlChar *) n->name().c_str(), 0); + } else { node = xmlNewChild(p, 0, (xmlChar *) n->name().c_str(), 0); - - if (n->is_content()) { + } + + if (n->is_content()) { node->type = XML_TEXT_NODE; - xmlNodeSetContentLen(node, (const xmlChar *) n->content().c_str(), - n->content().length()); - } - - props = n->properties(); - for (curprop = props.begin(); curprop != props.end(); curprop++) - xmlSetProp(node, (xmlChar *) (*curprop)->name().c_str(), - (xmlChar *) (*curprop)->value().c_str()); - - children = n->children(); - for (curchild = children.begin(); curchild != children.end(); - curchild++) + xmlNodeSetContentLen(node, (const xmlChar *) n->content().c_str(), n->content().length()); + } + + props = n->properties(); + for (curprop = props.begin(); curprop != props.end(); ++curprop) { + xmlSetProp(node, (xmlChar *) (*curprop)->name().c_str(), (xmlChar *) (*curprop)->value().c_str()); + } + + children = n->children(); + for (curchild = children.begin(); curchild != children.end(); ++curchild) { writenode(doc, *curchild, node); + } } diff --git a/libs/soundtouch/STTypes.h b/libs/soundtouch/STTypes.h index dc6a97001a..c404675ecd 100644 --- a/libs/soundtouch/STTypes.h +++ b/libs/soundtouch/STTypes.h @@ -105,6 +105,6 @@ namespace soundtouch #endif #endif // INTEGER_SAMPLES -}; +} #endif diff --git a/libs/surfaces/control_protocol/control_protocol.cc b/libs/surfaces/control_protocol/control_protocol.cc index 10295bc698..dd9adc206e 100644 --- a/libs/surfaces/control_protocol/control_protocol.cc +++ b/libs/surfaces/control_protocol/control_protocol.cc @@ -49,7 +49,7 @@ void ControlProtocol::next_track (uint32_t initial_id) { uint32_t limit = session->nroutes(); - Route* cr = route_table[0]; + boost::shared_ptr<Route> cr = route_table[0]; uint32_t id; if (cr) { @@ -88,7 +88,7 @@ void ControlProtocol::prev_track (uint32_t initial_id) { uint32_t limit = session->nroutes() - 1; - Route* cr = route_table[0]; + boost::shared_ptr<Route> cr = route_table[0]; uint32_t id; if (cr) { @@ -128,29 +128,32 @@ void ControlProtocol::set_route_table_size (uint32_t size) { while (route_table.size() < size) { - route_table.push_back (0); + route_table.push_back (boost::shared_ptr<Route> ((Route*) 0)); } } void -ControlProtocol::set_route_table (uint32_t table_index, ARDOUR::Route*) +ControlProtocol::set_route_table (uint32_t table_index, boost::shared_ptr<ARDOUR::Route> r) { + if (table_index >= route_table.size()) { + return; + } + + route_table[table_index] = r; + + // XXX SHAREDPTR need to handle r->GoingAway } bool ControlProtocol::set_route_table (uint32_t table_index, uint32_t remote_control_id) { - if (table_index >= route_table.size()) { - return false; - } - - Route* r = session->route_by_remote_id (remote_control_id); + boost::shared_ptr<Route> r = session->route_by_remote_id (remote_control_id); if (!r) { return false; } - - route_table[table_index] = r; + + set_route_table (table_index, r); return true; } @@ -162,9 +165,9 @@ ControlProtocol::route_set_rec_enable (uint32_t table_index, bool yn) return; } - Route* r = route_table[table_index]; + boost::shared_ptr<Route> r = route_table[table_index]; - AudioTrack* at = dynamic_cast<AudioTrack*>(r); + boost::shared_ptr<AudioTrack> at = boost::dynamic_pointer_cast<AudioTrack>(r); if (at) { at->set_record_enable (yn, this); @@ -178,9 +181,9 @@ ControlProtocol::route_get_rec_enable (uint32_t table_index) return false; } - Route* r = route_table[table_index]; + boost::shared_ptr<Route> r = route_table[table_index]; - AudioTrack* at = dynamic_cast<AudioTrack*>(r); + boost::shared_ptr<AudioTrack> at = boost::dynamic_pointer_cast<AudioTrack>(r); if (at) { return at->record_enabled (); @@ -197,7 +200,7 @@ ControlProtocol::route_get_gain (uint32_t table_index) return 0.0f; } - Route* r = route_table[table_index]; + boost::shared_ptr<Route> r = route_table[table_index]; if (r == 0) { return 0.0f; @@ -213,7 +216,7 @@ ControlProtocol::route_set_gain (uint32_t table_index, float gain) return; } - Route* r = route_table[table_index]; + boost::shared_ptr<Route> r = route_table[table_index]; if (r != 0) { r->set_gain (gain, this); @@ -227,7 +230,7 @@ ControlProtocol::route_get_effective_gain (uint32_t table_index) return 0.0f; } - Route* r = route_table[table_index]; + boost::shared_ptr<Route> r = route_table[table_index]; if (r == 0) { return 0.0f; @@ -244,7 +247,7 @@ ControlProtocol::route_get_peak_input_power (uint32_t table_index, uint32_t whic return 0.0f; } - Route* r = route_table[table_index]; + boost::shared_ptr<Route> r = route_table[table_index]; if (r == 0) { return 0.0f; @@ -261,7 +264,7 @@ ControlProtocol::route_get_muted (uint32_t table_index) return false; } - Route* r = route_table[table_index]; + boost::shared_ptr<Route> r = route_table[table_index]; if (r == 0) { return false; @@ -277,7 +280,7 @@ ControlProtocol::route_set_muted (uint32_t table_index, bool yn) return; } - Route* r = route_table[table_index]; + boost::shared_ptr<Route> r = route_table[table_index]; if (r != 0) { r->set_mute (yn, this); @@ -292,7 +295,7 @@ ControlProtocol::route_get_soloed (uint32_t table_index) return false; } - Route* r = route_table[table_index]; + boost::shared_ptr<Route> r = route_table[table_index]; if (r == 0) { return false; @@ -308,7 +311,7 @@ ControlProtocol::route_set_soloed (uint32_t table_index, bool yn) return; } - Route* r = route_table[table_index]; + boost::shared_ptr<Route> r = route_table[table_index]; if (r != 0) { r->set_solo (yn, this); @@ -322,7 +325,7 @@ ControlProtocol:: route_get_name (uint32_t table_index) return ""; } - Route* r = route_table[table_index]; + boost::shared_ptr<Route> r = route_table[table_index]; if (r == 0) { return ""; diff --git a/libs/surfaces/control_protocol/control_protocol/control_protocol.h b/libs/surfaces/control_protocol/control_protocol/control_protocol.h index 2bd23f5b48..8be652b9df 100644 --- a/libs/surfaces/control_protocol/control_protocol/control_protocol.h +++ b/libs/surfaces/control_protocol/control_protocol/control_protocol.h @@ -25,6 +25,7 @@ #include <string> #include <vector> #include <list> +#include <boost/shared_ptr.hpp> #include <sigc++/sigc++.h> #include <pbd/stateful.h> #include <control_protocol/basic_ui.h> @@ -73,7 +74,7 @@ class ControlProtocol : public sigc::trackable, public Stateful, public BasicUI */ void set_route_table_size (uint32_t size); - void set_route_table (uint32_t table_index, ARDOUR::Route*); + void set_route_table (uint32_t table_index, boost::shared_ptr<ARDOUR::Route>); bool set_route_table (uint32_t table_index, uint32_t remote_control_id); void route_set_rec_enable (uint32_t table_index, bool yn); @@ -94,7 +95,7 @@ class ControlProtocol : public sigc::trackable, public Stateful, public BasicUI std::string route_get_name (uint32_t table_index); protected: - std::vector<ARDOUR::Route*> route_table; + std::vector<boost::shared_ptr<ARDOUR::Route> > route_table; std::string _name; bool _active; |