Merged with trunk R708
git-svn-id: svn://localhost/ardour2/branches/midi@712 d708f5d6-7413-0410-9779-e7cbd77b26cf
This commit is contained in:
@@ -74,7 +74,7 @@ namespace ARDOUR {
|
||||
const char* old;
|
||||
};
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
/* how do we make these be within the Ardour namespace? */
|
||||
|
||||
|
||||
@@ -305,6 +305,6 @@ class AudioDiskstream : public Diskstream
|
||||
void disengage_record_enable (void* src);
|
||||
};
|
||||
|
||||
}; /* namespace ARDOUR */
|
||||
} // namespace ARDOUR
|
||||
|
||||
#endif /* __ardour_audio_diskstream_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&);
|
||||
|
||||
|
||||
@@ -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__ */
|
||||
|
||||
@@ -244,6 +244,6 @@ class AudioEngine : public sigc::trackable
|
||||
mutable gint m_meter_exit;
|
||||
};
|
||||
|
||||
}; /* namespace ARDOUR */
|
||||
} // namespace ARDOUR
|
||||
|
||||
#endif /* __ardour_audioengine_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__ */
|
||||
|
||||
|
||||
@@ -123,8 +123,7 @@ class AudioRegion : public Region
|
||||
Fast,
|
||||
Slow,
|
||||
LogA,
|
||||
LogB,
|
||||
|
||||
LogB
|
||||
};
|
||||
|
||||
void set_fade_in_active (bool yn);
|
||||
|
||||
@@ -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__ */
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
};
|
||||
|
||||
@@ -83,6 +83,6 @@ namespace ARDOUR
|
||||
int status;
|
||||
|
||||
};
|
||||
};
|
||||
} // namespace ARDOUR
|
||||
|
||||
#endif /* __ardour_export_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__ */
|
||||
|
||||
@@ -393,6 +393,6 @@ public:
|
||||
int32_t find_output_port_hole ();
|
||||
};
|
||||
|
||||
}; /* namespace ARDOUR */
|
||||
} // namespace ARDOUR
|
||||
|
||||
#endif /*__ardour_io_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__ */
|
||||
|
||||
@@ -126,7 +126,7 @@ class LogCurveOut : public LogCurve
|
||||
|
||||
};
|
||||
|
||||
}; /* namespace ARDOUR */
|
||||
} // namespace ARDOUR
|
||||
|
||||
#endif /* __ardour_logcurve_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__ */
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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; }
|
||||
|
||||
|
||||
@@ -207,6 +207,6 @@ class Port : public sigc::trackable {
|
||||
static jack_nframes_t _short_over_length;
|
||||
};
|
||||
|
||||
}; /* namespace ARDOUR */
|
||||
} // namespace ARDOUR
|
||||
|
||||
#endif /* __ardour_port_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__ */
|
||||
|
||||
@@ -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__ */
|
||||
|
||||
@@ -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));
|
||||
|
||||
@@ -58,6 +58,6 @@ class Send : public Redirect {
|
||||
uint32_t expected_inputs;
|
||||
};
|
||||
|
||||
}; /* namespace ARDOUR */
|
||||
} // namespace ARDOUR
|
||||
|
||||
#endif /* __ardour_send_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);
|
||||
|
||||
MidiTrack *new_midi_track (TrackMode mode = Normal);
|
||||
Route *new_midi_route ();
|
||||
|
||||
void remove_route (Route&);
|
||||
void resort_routes (void *src);
|
||||
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 ();
|
||||
}
|
||||
|
||||
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__ */
|
||||
|
||||
@@ -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++) {
|
||||
|
||||
@@ -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__ */
|
||||
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -70,18 +70,24 @@ jack_nframes_t DestructiveFileSource::xfade_frames = 64;
|
||||
DestructiveFileSource::DestructiveFileSource (string path, SampleFormat samp_format, HeaderFormat hdr_format, jack_nframes_t rate, Flag flags)
|
||||
: SndFileSource (path, samp_format, hdr_format, rate, flags)
|
||||
{
|
||||
xfade_buf = new Sample[xfade_frames];
|
||||
init ();
|
||||
}
|
||||
|
||||
_capture_start = false;
|
||||
_capture_end = false;
|
||||
file_pos = 0;
|
||||
|
||||
timeline_position = header_position_offset;
|
||||
AudioFileSource::HeaderPositionOffsetChanged.connect (mem_fun (*this, &DestructiveFileSource::handle_header_position_change));
|
||||
DestructiveFileSource::DestructiveFileSource (string path, Flag flags)
|
||||
: SndFileSource (path, flags)
|
||||
{
|
||||
init ();
|
||||
}
|
||||
|
||||
DestructiveFileSource::DestructiveFileSource (const XMLNode& node)
|
||||
: SndFileSource (node)
|
||||
{
|
||||
init ();
|
||||
}
|
||||
|
||||
void
|
||||
DestructiveFileSource::init ()
|
||||
{
|
||||
xfade_buf = new Sample[xfade_frames];
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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 */
|
||||
}
|
||||
|
||||
@@ -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&
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
boost::shared_ptr<const Send> send;
|
||||
boost::shared_ptr<const PortInsert> port_insert;
|
||||
boost::shared_ptr<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);
|
||||
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
|
||||
|
||||
@@ -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 ();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
@@ -452,17 +446,6 @@ Session::~Session ()
|
||||
i = tmp;
|
||||
}
|
||||
|
||||
#ifdef TRACK_DESTRUCTION
|
||||
cerr << "delete routes\n";
|
||||
#endif /* TRACK_DESTRUCTION */
|
||||
for (RouteList::iterator i = routes.begin(); i != routes.end(); ) {
|
||||
RouteList::iterator tmp;
|
||||
tmp = i;
|
||||
++tmp;
|
||||
delete *i;
|
||||
i = tmp;
|
||||
}
|
||||
|
||||
#ifdef TRACK_DESTRUCTION
|
||||
cerr << "delete diskstreams\n";
|
||||
#endif /* TRACK_DESTRUCTION */
|
||||
@@ -553,7 +536,7 @@ Session::~Session ()
|
||||
}
|
||||
|
||||
void
|
||||
Session::set_worst_io_latencies (bool take_lock)
|
||||
Session::set_worst_io_latencies ()
|
||||
{
|
||||
_worst_output_latency = 0;
|
||||
_worst_input_latency = 0;
|
||||
@@ -562,18 +545,12 @@ Session::set_worst_io_latencies (bool take_lock)
|
||||
return;
|
||||
}
|
||||
|
||||
if (take_lock) {
|
||||
route_lock.reader_lock ();
|
||||
}
|
||||
boost::shared_ptr<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 */
|
||||
|
||||
{
|
||||
|
||||
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 = routes.begin(); i != routes.end(); ++i) {
|
||||
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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 ();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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());
|
||||
}
|
||||
|
||||
@@ -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
|
||||
*/
|
||||
|
||||
@@ -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
|
||||
|
||||
63
libs/gtkmm2ext/gtkmm2ext/pathlist.h
Normal file
63
libs/gtkmm2ext/gtkmm2ext/pathlist.h
Normal file
@@ -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__
|
||||
124
libs/gtkmm2ext/pathlist.cc
Normal file
124
libs/gtkmm2ext/pathlist.cc
Normal file
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -18,7 +18,6 @@ fd_midiport.cc
|
||||
fifomidi.cc
|
||||
midi.cc
|
||||
midichannel.cc
|
||||
midicontrollable.cc
|
||||
midifactory.cc
|
||||
midimanager.cc
|
||||
midiparser.cc
|
||||
|
||||
@@ -155,7 +155,7 @@ class Channel : public sigc::trackable {
|
||||
void process_reset (Parser &);
|
||||
};
|
||||
|
||||
}; /* namespace MIDI */
|
||||
} // namespace MIDI
|
||||
|
||||
#endif // __midichannel_h__
|
||||
|
||||
|
||||
@@ -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__
|
||||
|
||||
@@ -62,6 +62,6 @@ class CoreMidi_MidiPort:public Port {
|
||||
bool firstrecv;
|
||||
};
|
||||
|
||||
}; /* namespace MIDI */
|
||||
} // namespace MIDI
|
||||
|
||||
#endif // __coremidi_midiport_h__
|
||||
|
||||
@@ -35,6 +35,6 @@ class PortFactory {
|
||||
const std::string &reqstr);
|
||||
};
|
||||
|
||||
}; /* namespace MIDI */
|
||||
} // namespace MIDI
|
||||
|
||||
#endif // __midi_factory_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__
|
||||
|
||||
@@ -42,6 +42,6 @@ class FIFO_MidiPort : public MIDI::FD_MidiPort
|
||||
void open (PortRequest &req);
|
||||
};
|
||||
|
||||
}; /* namespace MIDI */
|
||||
} // namespace MIDI
|
||||
|
||||
#endif // __fifomidi_h__
|
||||
|
||||
@@ -88,6 +88,6 @@ class Manager {
|
||||
void close_ports ();
|
||||
};
|
||||
|
||||
}; /* namespace MIDI */
|
||||
} // namespace MIDI
|
||||
|
||||
#endif // __midi_manager_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__ */
|
||||
|
||||
@@ -58,6 +58,6 @@ class Null_MidiPort : public Port
|
||||
virtual int selectable() const { return -1; }
|
||||
};
|
||||
|
||||
}; /* namespace MIDI */
|
||||
} // namespace MIDI
|
||||
|
||||
#endif // __nullmidi_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__
|
||||
|
||||
|
||||
@@ -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__
|
||||
|
||||
|
||||
@@ -54,7 +54,7 @@ struct PortRequest {
|
||||
const std::string &xtype);
|
||||
};
|
||||
|
||||
}; /* namespace MIDI */
|
||||
} // namespace MIDI
|
||||
|
||||
#endif // __midi_port_request_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__
|
||||
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -101,7 +101,7 @@ Parser::midi_event_type_name (eventType t)
|
||||
default:
|
||||
return "unknow MIDI event type";
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
Parser::Parser (Port &p)
|
||||
: _port (p)
|
||||
|
||||
@@ -8,6 +8,6 @@ namespace PBD
|
||||
|
||||
extern std::string basename_nosuffix (const std::string&);
|
||||
|
||||
};
|
||||
} // namespace PBD
|
||||
|
||||
#endif // __stupid_basename_h__
|
||||
|
||||
120
libs/pbd/pbd/rcu.h
Normal file
120
libs/pbd/pbd/rcu.h
Normal file
@@ -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__ */
|
||||
@@ -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 * );
|
||||
|
||||
@@ -70,7 +70,7 @@ Pool::alloc ()
|
||||
} else {
|
||||
return ptr;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
void
|
||||
Pool::release (void *ptr)
|
||||
|
||||
@@ -134,4 +134,3 @@ Stateful::instant_xml (const string& str, const string& dir)
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
} else {
|
||||
str = str.substr (s);
|
||||
}
|
||||
|
||||
str = str.substr (s, (i - s) + 1);
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -105,6 +105,6 @@ namespace soundtouch
|
||||
#endif
|
||||
|
||||
#endif // INTEGER_SAMPLES
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -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 "";
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user