#include <pbd/error.h>
#include <pbd/undo.h>
#include <pbd/pool.h>
+#include <pbd/rcu.h>
#include <midi++/types.h>
#include <midi++/mmc.h>
+#include <pbd/stateful.h>
+
#include <ardour/ardour.h>
#include <ardour/configuration.h>
#include <ardour/location.h>
-#include <ardour/stateful.h>
#include <ardour/gain.h>
#include <ardour/io.h>
class Port;
}
+namespace PBD {
+ class Controllable;
+}
+
namespace ARDOUR {
class Port;
class AudioEngine;
class Slave;
-class DiskStream;
+class Diskstream;
class Route;
class AuxInput;
class Source;
-class FileSource;
+class AudioSource;
+class BufferSet;
+
+class Diskstream;
+class AudioDiskstream;
+class MidiDiskstream;
+class AudioFileSource;
+class MidiSource;
class Auditioner;
class Insert;
class Send;
class AudioTrack;
class NamedSelection;
class AudioRegion;
+
class Region;
class Playlist;
class VSTPlugin;
class ControlProtocolManager;
+//class MidiDiskstream;
+class MidiSource;
+class MidiTrack;
+class MidiRegion;
+class SMFSource;
+
struct AudioExportSpecification;
struct RouteGroup;
{
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:
enum SlaveSource {
None = 0,
MTC,
- JACK,
+ JACK
};
enum AutoConnectOption {
*/
StopOnce,
- AutoLoop,
+ AutoLoop
};
enum Action {
Replace,
Clear
};
-
- Type type;
- Action action;
- jack_nframes_t action_frame;
- jack_nframes_t target_frame;
- float speed;
+
+ Type type;
+ Action action;
+ jack_nframes_t action_frame;
+ jack_nframes_t target_frame;
+ float speed;
union {
- void* ptr;
- bool yes_or_no;
- Session::SlaveSource slave;
+ void* ptr;
+ bool yes_or_no;
+ Session::SlaveSource slave;
+ Route* route;
};
list<AudioRange> audio_range;
static string change_audio_path_by_name (string oldpath, string oldname, string newname, bool destructive);
static string peak_path_from_audio_path (string);
string audio_path_from_name (string, uint32_t nchans, uint32_t chan, bool destructive);
+ string midi_path_from_name (string);
void process (jack_nframes_t nframes);
- vector<Sample*>& get_passthru_buffers() { return _passthru_buffers; }
- vector<Sample*>& get_silent_buffers (uint32_t howmany);
- vector<Sample*>& get_send_buffers () { return _send_buffers; }
-
- DiskStream *diskstream_by_id (id_t id);
- DiskStream *diskstream_by_name (string name);
+ BufferSet& get_silent_buffers (ChanCount count = ChanCount::ZERO);
+ BufferSet& get_scratch_buffers (ChanCount count = ChanCount::ZERO);
+ BufferSet& get_send_buffers (ChanCount count = ChanCount::ZERO);
+
+ void add_diskstream (boost::shared_ptr<Diskstream>);
+ boost::shared_ptr<Diskstream> diskstream_by_id (const PBD::ID& id);
+ boost::shared_ptr<Diskstream> diskstream_by_name (string name);
bool have_captured() const { return _have_captured; }
void refill_all_diskstream_buffers ();
uint32_t diskstream_buffer_size() const { return dstream_buffer_size; }
+
uint32_t get_next_diskstream_id() const { return n_diskstreams(); }
uint32_t n_diskstreams() const;
- typedef list<DiskStream *> DiskStreamList;
-
- Session::DiskStreamList disk_streams() const {
- Glib::RWLock::ReaderLock lm (diskstream_lock);
- return diskstreams; /* XXX yes, force a copy */
- }
-
- void foreach_diskstream (void (DiskStream::*func)(void));
- template<class T> void foreach_diskstream (T *obj, void (T::*func)(DiskStream&));
-
- typedef list<Route *> RouteList;
-
- RouteList get_routes() const {
- Glib::RWLock::ReaderLock rlock (route_lock);
- return routes; /* XXX yes, force a copy */
+ typedef std::list<boost::shared_ptr<Diskstream> > DiskstreamList;
+ typedef std::list<boost::shared_ptr<Route> > RouteList;
+
+ 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_id (PBD::ID);
+ boost::shared_ptr<Route> route_by_remote_id (uint32_t id);
bool route_name_unique (string) const;
/* Record status signals */
- sigc::signal<void> RecordStateChanged;
+ sigc::signal<void> RecordStateChanged;
/* Transport mechanism signals */
sigc::signal<void> DurationChanged;
sigc::signal<void> HaltOnXrun;
- sigc::signal<void,Route*> RouteAdded;
- sigc::signal<void,DiskStream*> DiskStreamAdded;
+ sigc::signal<void,RouteList&> RouteAdded;
void request_roll ();
void request_bounded_roll (jack_nframes_t start, jack_nframes_t end);
void goto_start () { request_locate (start_location->start(), false); }
void use_rf_shuttle_speed ();
void request_transport_speed (float speed);
- void request_overwrite_buffer (DiskStream*);
- void request_diskstream_speed (DiskStream&, float speed);
+ void request_overwrite_buffer (Diskstream*);
+ void request_diskstream_speed (Diskstream&, float speed);
void request_input_change_handling ();
bool locate_pending() const { return static_cast<bool>(post_transport_work&PostTransportLocate); }
bool transport_locked () const;
int wipe ();
- int wipe_diskstream (DiskStream *);
+ //int wipe_diskstream (AudioDiskstream *);
int remove_region_from_region_list (Region&);
int save_state (string snapshot_name, bool pending = false);
int restore_state (string snapshot_name);
int save_template (string template_name);
+ int save_history (string snapshot_name = "");
+ int restore_history (string snapshot_name);
static int rename_template (string old_name, string new_name);
static vector<string*>* possible_states(string path);
XMLNode& get_state();
- int set_state(const XMLNode& node);
+ int set_state(const XMLNode& node); // not idempotent
XMLNode& get_template();
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,
/* fundamental operations. duh. */
+ std::list<boost::shared_ptr<AudioTrack> > new_audio_track (int input_channels, int output_channels, TrackMode mode = Normal, uint32_t how_many = 1);
+ RouteList new_audio_route (int input_channels, int output_channels, uint32_t how_many);
+
+ std::list<boost::shared_ptr<MidiTrack> > new_midi_track (TrackMode mode = Normal, uint32_t how_many = 1);
+ //boost::shared_ptr<Route> new_midi_route (uint32_t how_many = 1);
- AudioTrack *new_audio_track (int input_channels, int output_channels, TrackMode mode = Normal);
-
- Route *new_audio_route (int input_channels, int output_channels);
-
- void remove_route (Route&);
- void resort_routes (void *src);
-
+ void remove_route (boost::shared_ptr<Route>);
+ void resort_routes ();
+ void resort_routes_using (boost::shared_ptr<RouteList>);
+
AudioEngine &engine() { return _engine; };
/* configuration. there should really be accessors/mutators
int set_smpte_type (float fps, bool drop_frames);
void bbt_time (jack_nframes_t when, BBT_Time&);
-
void smpte_to_sample( SMPTE::Time& smpte, jack_nframes_t& sample, bool use_offset, bool use_subframes ) const;
void sample_to_smpte( jack_nframes_t sample, SMPTE::Time& smpte, bool use_offset, bool use_subframes ) const;
void smpte_time (SMPTE::Time &);
jack_nframes_t convert_to_frames_at (jack_nframes_t position, AnyTime&);
- sigc::signal<void> SMPTEOffsetChanged;
+ static sigc::signal<void> SMPTEOffsetChanged;
sigc::signal<void> SMPTETypeChanged;
void request_slave_source (SlaveSource, jack_nframes_t pos = 0);
/* region info */
- sigc::signal<void,AudioRegion *> AudioRegionAdded;
- sigc::signal<void,AudioRegion *> AudioRegionRemoved;
+ sigc::signal<void,Region *> RegionAdded;
+ sigc::signal<void,Region *> RegionRemoved;
int region_name (string& result, string base = string(""), bool newlevel = false) const;
string new_region_name (string);
string path_from_region_name (string name, string identifier);
- AudioRegion* find_whole_file_parent (AudioRegion&);
- void find_equivalent_playlist_regions (AudioRegion&, std::vector<AudioRegion*>& result);
+ Region* find_whole_file_parent (Region& child);
+ void find_equivalent_playlist_regions (Region&, std::vector<Region*>& result);
- AudioRegion *XMLRegionFactory (const XMLNode&, bool full);
+ Region* XMLRegionFactory (const XMLNode&, bool full);
+ AudioRegion* XMLAudioRegionFactory (const XMLNode&, bool full);
+ MidiRegion* XMLMidiRegionFactory (const XMLNode&, bool full);
- template<class T> void foreach_audio_region (T *obj, void (T::*func)(AudioRegion *));
+ template<class T> void foreach_region (T *obj, void (T::*func)(Region *));
/* source management */
string pathname;
/* result */
- std::vector<AudioRegion*> new_regions;
+ std::vector<Region*> new_regions;
};
int stop_audio_export (ARDOUR::AudioExportSpecification&);
void add_source (Source *);
- int remove_file_source (FileSource&);
+ void remove_source (Source *);
+ int cleanup_audio_file_source (AudioFileSource&);
struct cleanup_report {
vector<string> paths;
sigc::signal<void,Source *> SourceAdded;
sigc::signal<void,Source *> SourceRemoved;
- FileSource *create_file_source (ARDOUR::DiskStream&, int32_t chan, bool destructive);
- Source *get_source (ARDOUR::id_t);
+ AudioFileSource *create_audio_source_for_session (ARDOUR::AudioDiskstream&, uint32_t which_channel, bool destructive);
+
+ MidiSource *create_midi_source_for_session (ARDOUR::MidiDiskstream&);
+
+ Source *source_by_id (const PBD::ID&);
/* playlist management */
sigc::signal<void,Playlist*> PlaylistAdded;
sigc::signal<void,Playlist*> PlaylistRemoved;
- Playlist *get_playlist (string name);
-
uint32_t n_playlists() const;
template<class T> void foreach_playlist (T *obj, void (T::*func)(Playlist *));
sigc::signal<void> NamedSelectionAdded;
sigc::signal<void> NamedSelectionRemoved;
+ /* Curves and AutomationLists (TODO when they go away) */
+ void add_curve(Curve*);
+ void add_automation_list(AutomationList*);
+
/* fade curves */
float get_default_fade_length () const { return default_fade_msecs; }
/* auditioning */
- Auditioner& the_auditioner() { return *auditioner; }
+ boost::shared_ptr<Auditioner> the_auditioner() { return auditioner; }
void audition_playlist ();
- void audition_region (AudioRegion&);
+ void audition_region (Region&);
void cancel_audition ();
bool is_auditioning () const;
/* flattening stuff */
- int write_one_track (AudioTrack&, jack_nframes_t start, jack_nframes_t cnt, bool overwrite, vector<Source*>&,
- InterThreadInfo& wot);
+ int write_one_audio_track (AudioTrack&, jack_nframes_t start, jack_nframes_t cnt, bool overwrite, vector<Source*>&, InterThreadInfo& wot);
int freeze (InterThreadInfo&);
/* session-wide solo/mute/rec-enable */
/* 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 */
string next_undo() const { return history.next_undo(); }
string next_redo() const { return history.next_redo(); }
- void begin_reversible_command (string cmd_name, UndoAction *private_undo = 0);
- void commit_reversible_command (UndoAction* private_redo = 0);
+ void begin_reversible_command (string cmd_name);
+ void commit_reversible_command (Command* cmd = 0);
- void add_undo (const UndoAction& ua) {
- current_cmd.add_undo (ua);
- }
- void add_redo (const UndoAction& ua) {
- current_cmd.add_redo (ua);
- }
- void add_redo_no_execute (const UndoAction& ua) {
- current_cmd.add_redo_no_execute (ua);
+ void add_command (Command *const cmd) {
+ current_trans.add_command (cmd);
}
- UndoAction global_solo_memento (void *src);
- UndoAction global_mute_memento (void *src);
- UndoAction global_record_enable_memento (void *src);
- UndoAction global_metering_memento (void *src);
+ // these commands are implemented in libs/ardour/session_command.cc
+ Command *memento_command_factory(XMLNode *n);
+ void register_with_memento_command_factory(PBD::ID, Stateful *);
+ class GlobalSoloStateCommand : public Command
+ {
+ GlobalRouteBooleanState before, after;
+ Session &sess;
+ void *src;
+ public:
+ GlobalSoloStateCommand(Session &, void *src);
+ void operator()();
+ void undo();
+ XMLNode &get_state();
+ void mark();
+ };
+
+ class GlobalMuteStateCommand : public Command
+ {
+ GlobalRouteBooleanState before, after;
+ Session &sess;
+ void *src;
+ public:
+ GlobalMuteStateCommand(Session &, void *src);
+ void operator()();
+ void undo();
+ XMLNode &get_state();
+ void mark();
+ };
+
+ class GlobalRecordEnableStateCommand : public Command
+ {
+ GlobalRouteBooleanState before, after;
+ Session &sess;
+ void *src;
+ public:
+ GlobalRecordEnableStateCommand(Session &, void *src);
+ void operator()();
+ void undo();
+ XMLNode &get_state();
+ void mark();
+ };
+
+ class GlobalMeteringStateCommand : public Command
+ {
+ GlobalRouteMeterState before, after;
+ Session &sess;
+ void *src;
+ public:
+ GlobalMeteringStateCommand(Session &, void *src);
+ void operator()();
+ void undo();
+ XMLNode &get_state();
+ void mark();
+ };
/* edit mode */
/* 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;
/* buffers for gain and pan */
gain_t* gain_automation_buffer () const { return _gain_automation_buffer; }
- pan_t** pan_automation_buffer() const { return _pan_automation_buffer; }
+ pan_t** pan_automation_buffer () const { return _pan_automation_buffer; }
/* buffers for conversion */
enum RunContext {
ExportContext
};
- char * conversion_buffer(RunContext context) { return _conversion_buffers[context]; }
-
/* VST support */
static long vst_callback (AEffect* effect,
static apply_gain_to_buffer_t apply_gain_to_buffer;
static mix_buffers_with_gain_t mix_buffers_with_gain;
static mix_buffers_no_gain_t mix_buffers_no_gain;
-
+
+ static sigc::signal<void> SendFeedback;
+
+ /* Controllables */
+
+ PBD::Controllable* controllable_by_id (const PBD::ID&);
+
protected:
friend class AudioEngine;
void set_block_size (jack_nframes_t nframes);
void set_frame_rate (jack_nframes_t nframes);
protected:
- friend class DiskStream;
+ friend class Diskstream;
void stop_butler ();
void wait_till_butler_finished();
jack_nframes_t _last_slave_transport_frame;
jack_nframes_t maximum_output_latency;
jack_nframes_t last_stop_frame;
- vector<Sample *> _passthru_buffers;
- vector<Sample *> _silent_buffers;
- vector<Sample *> _send_buffers;
- map<RunContext,char*> _conversion_buffers;
+ BufferSet* _scratch_buffers;
+ BufferSet* _silent_buffers;
+ BufferSet* _send_buffers;
jack_nframes_t current_block_size;
jack_nframes_t _worst_output_latency;
jack_nframes_t _worst_input_latency;
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);
- void ensure_passthru_buffers (uint32_t howmany);
+ void ensure_buffers (ChanCount howmany);
void process_scrub (jack_nframes_t);
void process_without_events (jack_nframes_t);
jack_nframes_t last_smpte_when;
SMPTE::Time last_smpte;
- bool _send_smpte_update; ///< Send a full MTC timecode this cycle
+ bool _send_smpte_update; ///< Flag to send a full frame (SMPTE) MTC message this cycle
int send_full_time_code(jack_nframes_t nframes);
int send_midi_time_code_for_cycle(jack_nframes_t nframes);
bool waiting_to_start;
void set_auto_loop (bool yn);
- void overwrite_some_buffers (DiskStream*);
+ void overwrite_some_buffers (Diskstream*);
void flush_all_redirects ();
void locate (jack_nframes_t, bool with_roll, bool with_flush, bool with_loop=false);
void start_locate (jack_nframes_t, bool with_roll, bool with_flush, bool with_loop=false);
void force_locate (jack_nframes_t frame, bool with_roll = false);
- void set_diskstream_speed (DiskStream*, float speed);
+ void set_diskstream_speed (Diskstream*, float speed);
void set_transport_speed (float speed, bool abort = false);
void stop_transport (bool abort = false);
void start_transport ();
/* disk-streams */
- DiskStreamList diskstreams;
- mutable Glib::RWLock diskstream_lock;
+ SerializedRCUManager<DiskstreamList> diskstreams;
+
uint32_t dstream_buffer_size;
- void add_diskstream (DiskStream*);
int load_diskstreams (const XMLNode&);
/* routes stuff */
- RouteList routes;
- mutable Glib::RWLock route_lock;
- void add_route (Route*);
+ SerializedRCUManager<RouteList> routes;
+
+ void add_routes (RouteList&, bool save = true);
uint32_t destructive_index;
int load_routes (const XMLNode&);
- Route* XMLRouteFactory (const XMLNode&);
+ boost::shared_ptr<Route> XMLRouteFactory (const XMLNode&);
/* mixer stuff */
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);
/* REGION MANAGEMENT */
mutable Glib::Mutex region_lock;
- typedef map<ARDOUR::id_t,AudioRegion *> AudioRegionList;
- AudioRegionList audio_regions;
+ typedef map<PBD::ID,Region *> RegionList;
+ RegionList regions;
void region_renamed (Region *);
void region_changed (Change, Region *);
/* SOURCES */
mutable Glib::Mutex source_lock;
- typedef std::map<id_t, Source *> SourceList;
+ typedef std::map<PBD::ID,Source *> SourceList;
SourceList sources;
int load_sources (const XMLNode& node);
XMLNode& get_sources_as_xml ();
- void remove_source (Source *);
-
Source *XMLSourceFactory (const XMLNode&);
/* PLAYLISTS */
Playlist *XMLPlaylistFactory (const XMLNode&);
void playlist_length_changed (Playlist *);
- void diskstream_playlist_changed (DiskStream *);
+ void diskstream_playlist_changed (boost::shared_ptr<Diskstream>);
/* NAMED SELECTIONS */
NamedSelection *named_selection_factory (string name);
NamedSelection *XMLNamedSelectionFactory (const XMLNode&);
+ /* CURVES and AUTOMATION LISTS */
+ std::map<PBD::ID, Curve*> curves;
+ std::map<PBD::ID, AutomationList*> automation_lists;
+
/* DEFAULT FADE CURVES */
float default_fade_steepness;
/* AUDITIONING */
- Auditioner *auditioner;
+ boost::shared_ptr<Auditioner> auditioner;
void set_audition (AudioRegion*);
void non_realtime_set_audition ();
AudioRegion *pending_audition_region;
void reverse_diskstream_buffers ();
UndoHistory history;
- UndoCommand current_cmd;
+ UndoTransaction current_trans;
GlobalRouteBooleanState get_global_route_boolean (bool (Route::*method)(void) const);
GlobalRouteMeterState get_global_route_metering ();
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;
/* 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;
LayerModel layer_model;
CrossfadeModel xfade_model;
+
+ typedef std::list<PBD::Controllable*> Controllables;
+ Glib::Mutex controllables_lock;
+ Controllables controllables;
+
+ void add_controllable (PBD::Controllable*);
+ void remove_controllable (PBD::Controllable*);
};
-}; /* namespace ARDOUR */
+} // namespace ARDOUR
#endif /* __ardour_session_h__ */