#include "pbd/error.h"
#include "pbd/rcu.h"
#include "pbd/statefuldestructible.h"
+#include "pbd/signals.h"
#include "pbd/undo.h"
-#include "midi++/mmc.h"
#include "midi++/types.h"
-#include "pbd/destructible.h"
-#include "pbd/stateful.h"
-
#include "ardour/ardour.h"
#include "ardour/click.h"
#include "ardour/chan_count.h"
#include "ardour/timecode.h"
#include "ardour/interpolation.h"
+#ifdef HAVE_JACK_SESSION
+#include <jack/session.h>
+#endif
+
class XMLTree;
class XMLNode;
class AEffect;
namespace MIDI {
class Port;
+ class MachineControl;
+ class Parser;
}
namespace PBD {
class Controllable;
+ class ControllableDescriptor;
}
namespace Evoral {
namespace ARDOUR {
-class AudioDiskstream;
class AudioEngine;
class AudioFileSource;
class AudioRegion;
class IO;
class IOProcessor;
class ImportStatus;
-class MidiDiskstream;
class MidiRegion;
class MidiSource;
class MidiTrack;
+class MidiControlUI;
class NamedSelection;
class Playlist;
class PluginInsert;
class Port;
class PortInsert;
+class ProcessThread;
class Processor;
class Region;
class Return;
class Source;
class TempoMap;
class VSTPlugin;
+class Graph;
+class Track;
extern void setup_enum_writer ();
-class Session : public PBD::StatefulDestructible, public SessionEventManager, public boost::noncopyable
+class Session : public PBD::StatefulDestructible, public PBD::ScopedConnectionList, public SessionEventManager
{
- private:
- typedef std::pair<boost::weak_ptr<Route>,bool> RouteBooleanState;
- typedef std::vector<RouteBooleanState> GlobalRouteBooleanState;
- typedef std::pair<boost::weak_ptr<Route>,MeterPoint> RouteMeterState;
- typedef std::vector<RouteMeterState> GlobalRouteMeterState;
-
public:
- enum RecordState {
+ enum RecordState {
Disabled = 0,
Enabled = 1,
Recording = 2
};
- /* creating from an XML file */
+ /* a new session might have non-empty mix_template, an existing session should always have an empty one.
+ the bus profile can be null if no master out bus is required.
+ */
Session (AudioEngine&,
- const std::string& fullpath,
- const std::string& snapshot_name,
- std::string mix_template = "");
-
- /* creating a new Session */
-
- Session (AudioEngine&,
- std::string fullpath,
- std::string snapshot_name,
- AutoConnectOption input_auto_connect,
- AutoConnectOption output_auto_connect,
- uint32_t control_out_channels,
- uint32_t master_out_channels,
- uint32_t n_physical_in,
- uint32_t n_physical_out,
- nframes_t initial_length);
+ const std::string& fullpath,
+ const std::string& snapshot_name,
+ BusProfile* bus_profile = 0,
+ std::string mix_template = "");
virtual ~Session ();
-
+
std::string path() const { return _path; }
std::string name() const { return _name; }
std::string snap_name() const { return _current_snapshot_name; }
void set_deletion_in_progress ();
void clear_deletion_in_progress ();
bool deletion_in_progress() const { return _state_of_the_state & Deletion; }
- sigc::signal<void> DirtyChanged;
+ PBD::Signal0<void> DirtyChanged;
const SessionDirectory& session_directory () const { return *(_session_dir.get()); }
- static sigc::signal<void> AutoBindingOn;
- static sigc::signal<void> AutoBindingOff;
+ static PBD::Signal0<void> AutoBindingOn;
+ static PBD::Signal0<void> AutoBindingOff;
- static sigc::signal<void,std::string> Dialog;
+ static PBD::Signal1<void,std::string> Dialog;
std::string sound_dir (bool with_path = true) const;
std::string peak_dir () const;
Glib::ustring peak_path (Glib::ustring) const;
- static std::string change_source_path_by_name (std::string oldpath, std::string oldname, std::string newname, bool destructive);
+ std::string change_source_path_by_name (std::string oldpath, std::string oldname, std::string newname, bool destructive);
std::string peak_path_from_audio_path (std::string) const;
std::string new_audio_source_name (const std::string&, uint32_t nchans, uint32_t chan, bool destructive);
std::string new_midi_source_name (const std::string&);
- std::string new_source_path_from_name (DataType type, const std::string&);
+ std::string new_source_path_from_name (DataType type, const std::string&, bool as_stub = false);
RouteList new_route_from_template (uint32_t how_many, const std::string& template_path);
void process (nframes_t nframes);
BufferSet& get_scratch_buffers (ChanCount count = ChanCount::ZERO);
BufferSet& get_mix_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 (std::string name);
- bool have_rec_enabled_diskstream () const;
+ bool have_rec_enabled_track () const;
bool have_captured() const { return _have_captured; }
- void refill_all_diskstream_buffers ();
+ void refill_all_track_buffers ();
Butler* butler() { return _butler; }
void butler_transport_work ();
- uint32_t get_next_diskstream_id() const { return n_diskstreams(); }
- uint32_t n_diskstreams() const;
-
void refresh_disk_space ();
- typedef std::list<boost::shared_ptr<Diskstream> > DiskstreamList;
-
- SerializedRCUManager<DiskstreamList>& diskstream_list() { return diskstreams; }
-
+ int load_diskstreams_2X (XMLNode const &, int);
+
int load_routes (const XMLNode&, int);
boost::shared_ptr<RouteList> get_routes() const {
return routes.reader ();
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);
+ bool io_name_is_legal (const std::string&);
boost::shared_ptr<Route> route_by_name (std::string);
boost::shared_ptr<Route> route_by_id (PBD::ID);
boost::shared_ptr<Route> route_by_remote_id (uint32_t id);
void maybe_write_autosave ();
- /* Proxy signal for region hidden changes */
-
- sigc::signal<void,boost::shared_ptr<Region> > RegionHiddenChange;
-
/* Emitted when all i/o connections are complete */
- sigc::signal<void> IOConnectionsComplete;
+ PBD::Signal0<void> IOConnectionsComplete;
/* Record status signals */
- sigc::signal<void> RecordStateChanged;
+ PBD::Signal0<void> RecordStateChanged;
/* Transport mechanism signals */
- sigc::signal<void> TransportStateChange; /* generic */
- sigc::signal<void,nframes64_t> PositionChanged; /* sent after any non-sequential motion */
- sigc::signal<void> DurationChanged;
- sigc::signal<void,nframes64_t> Xrun;
- sigc::signal<void> TransportLooped;
+ PBD::Signal0<void> TransportStateChange; /* generic */
+ PBD::Signal1<void,nframes64_t> PositionChanged; /* sent after any non-sequential motion */
+ PBD::Signal1<void,nframes64_t> Xrun;
+ PBD::Signal0<void> TransportLooped;
/** emitted when a locate has occurred */
- sigc::signal<void> Located;
+ PBD::Signal0<void> Located;
- sigc::signal<void,RouteList&> RouteAdded;
- sigc::signal<void> RouteGroupChanged;
+ PBD::Signal1<void,RouteList&> RouteAdded;
+ /** Emitted when anything about any of our route groups changes */
+ PBD::Signal0<void> RouteGroupChanged;
+
+ void queue_event (SessionEvent*);
void request_roll_at_and_return (nframes_t start, nframes_t return_to);
void request_bounded_roll (nframes_t start, nframes_t end);
bool get_play_loop () const { return play_loop; }
nframes_t last_transport_start() const { return _last_roll_location; }
- void goto_end () { request_locate (end_location->start(), false);}
- void goto_start () { request_locate (start_location->start(), false); }
- void set_session_start (nframes_t start) { start_location->set_start(start); }
- void set_session_end (nframes_t end) { end_location->set_start(end); config.set_end_marker_is_free (false); }
+ void goto_end ();
+ void goto_start ();
+ void set_session_start (nframes_t);
+ void set_session_end (nframes_t);
void use_rf_shuttle_speed ();
void allow_auto_play (bool yn);
void request_transport_speed (double speed);
- void request_overwrite_buffer (Diskstream*);
- void request_diskstream_speed (Diskstream&, double speed);
+ void request_overwrite_buffer (Track *);
+ void adjust_playback_buffering();
+ void adjust_capture_buffering();
+ void request_track_speed (Track *, double speed);
void request_input_change_handling ();
bool locate_pending() const { return static_cast<bool>(post_transport_work()&PostTransportLocate); }
int wipe ();
- int remove_region_from_region_list (boost::shared_ptr<Region>);
-
- /* ask the session to do realtime things, in RT context, then get back to us via a callback (which must be
- cross-thread or RT safe, since it too is called from RT context)
- */
-
- void request_real_time_operation (sigc::slot<void> rt_op, sigc::slot<void,SessionEvent*> callback);
-
- nframes_t get_maximum_extent () const;
- nframes_t current_end_frame() const { return end_location->start(); }
- nframes_t current_start_frame() const { return start_location->start(); }
+ std::pair<nframes_t, nframes_t> get_extent () const;
+ nframes_t current_end_frame () const;
+ nframes_t current_start_frame () const;
/// "actual" sample rate of session, set by current audioengine rate, pullup/down etc.
nframes_t frame_rate() const { return _current_frame_rate; }
/// "native" sample rate of session, regardless of current audioengine rate, pullup/down etc
Locations *locations() { return &_locations; }
- sigc::signal<void,Location*> auto_loop_location_changed;
- sigc::signal<void,Location*> auto_punch_location_changed;
- sigc::signal<void> locations_modified;
+ PBD::Signal1<void,Location*> auto_loop_location_changed;
+ PBD::Signal1<void,Location*> auto_punch_location_changed;
+ PBD::Signal0<void> locations_modified;
void set_auto_punch_location (Location *);
void set_auto_loop_location (Location *);
nframes_t worst_input_latency () const { return _worst_input_latency; }
nframes_t worst_track_latency () const { return _worst_track_latency; }
- int save_state (std::string snapshot_name, bool pending = false);
+#ifdef HAVE_JACK_SESSION
+ void jack_session_event (jack_session_event_t* event);
+#endif
+ int save_state (std::string snapshot_name, bool pending = false, bool switch_to_snapshot = false);
int restore_state (std::string snapshot_name);
int save_template (std::string template_name);
int save_history (std::string snapshot_name = "");
static int rename_template (std::string old_name, std::string new_name);
static int delete_template (std::string name);
- sigc::signal<void,std::string> StateSaved;
- sigc::signal<void> StateReady;
+ PBD::Signal1<void,std::string> StateSaved;
+ PBD::Signal0<void> StateReady;
std::vector<std::string*>* possible_states() const;
static std::vector<std::string*>* possible_states (std::string path);
RouteGroup *route_group_by_name (std::string);
- sigc::signal<void,RouteGroup*> route_group_added;
- sigc::signal<void> route_group_removed;
+ PBD::Signal1<void,RouteGroup*> route_group_added;
+ PBD::Signal0<void> route_group_removed;
- void foreach_route_group (sigc::slot<void,RouteGroup*> sl) {
- for (std::list<RouteGroup *>::iterator i = _route_groups.begin(); i != _route_groups.end(); i++) {
- sl (*i);
+ void foreach_route_group (boost::function<void(RouteGroup*)> f) {
+ for (std::list<RouteGroup *>::iterator i = _route_groups.begin(); i != _route_groups.end(); ++i) {
+ f (*i);
}
}
AudioEngine & engine() { return _engine; }
AudioEngine const & engine () const { return _engine; }
- int32_t max_level;
- int32_t min_level;
-
/* Time */
nframes64_t transport_frame () const {return _transport_frame; }
nframes_t convert_to_frames_at (nframes_t position, AnyTime const &);
- static sigc::signal<void> StartTimeChanged;
- static sigc::signal<void> EndTimeChanged;
- static sigc::signal<void> TimecodeOffsetChanged;
+ static PBD::Signal0<void> StartTimeChanged;
+ static PBD::Signal0<void> EndTimeChanged;
+ static PBD::Signal0<void> TimecodeOffsetChanged;
std::vector<SyncSource> get_available_sync_options() const;
void request_sync_source (Slave*);
TempoMap& tempo_map() { return *_tempo_map; }
/// signals the current transport position in frames, bbt and timecode time (in that order)
- sigc::signal<void, const nframes_t&, const BBT_Time&, const Timecode::Time&> tick;
+ PBD::Signal3<void,const nframes_t&, const BBT_Time&, const Timecode::Time&> tick;
/* region info */
- void add_regions (std::vector<boost::shared_ptr<Region> >&);
-
- sigc::signal<void,boost::weak_ptr<Region> > RegionAdded;
- sigc::signal<void,std::vector<boost::weak_ptr<Region> >& > RegionsAdded;
- sigc::signal<void,boost::weak_ptr<Region> > RegionRemoved;
+ boost::shared_ptr<Region> find_whole_file_parent (boost::shared_ptr<Region const>) const;
- int region_name (std::string& result, std::string base = std::string(""), bool newlevel = false);
- std::string new_region_name (std::string);
std::string path_from_region_name (DataType type, std::string name, std::string identifier);
- boost::shared_ptr<Region> find_whole_file_parent (boost::shared_ptr<Region const>);
-
boost::shared_ptr<Region> XMLRegionFactory (const XMLNode&, bool full);
boost::shared_ptr<AudioRegion> XMLAudioRegionFactory (const XMLNode&, bool full);
boost::shared_ptr<MidiRegion> XMLMidiRegionFactory (const XMLNode&, bool full);
- template<class T> void foreach_region (T *obj, void (T::*func)(boost::shared_ptr<Region>));
-
/* source management */
void import_audiofiles (ImportStatus&);
int start_audio_export (nframes_t position, bool realtime);
- sigc::signal<int, nframes_t> ProcessExport;
- sigc::signal<void> ExportReadFinished;
- static sigc::signal<void, std::string, std::string> Exported;
+ PBD::Signal1<int,nframes_t> ProcessExport;
+ static PBD::Signal2<void,std::string, std::string> Exported;
void add_source (boost::shared_ptr<Source>);
void remove_source (boost::weak_ptr<Source>);
int cleanup_sources (CleanupReport&);
int cleanup_trash_sources (CleanupReport&);
- int destroy_region (boost::shared_ptr<Region>);
- int destroy_regions (std::list<boost::shared_ptr<Region> >);
+ int destroy_sources (std::list<boost::shared_ptr<Source> >);
int remove_last_capture ();
0 for "yes, delete this playlist",
1 for "no, don't delete this playlist".
*/
- sigc::signal<int,boost::shared_ptr<Playlist> > AskAboutPlaylistDeletion;
+ static PBD::Signal1<int,boost::shared_ptr<Playlist> > AskAboutPlaylistDeletion;
/** handlers should return 0 for "ignore the rate mismatch",
!0 for "do not use this session"
*/
- static sigc::signal<int,nframes_t, nframes_t> AskAboutSampleRateMismatch;
+ static PBD::Signal2<int,nframes_t, nframes_t> AskAboutSampleRateMismatch;
/** handlers should return !0 for use pending state, 0 for ignore it.
*/
- static sigc::signal<int> AskAboutPendingState;
+ static PBD::Signal0<int> AskAboutPendingState;
- boost::shared_ptr<AudioFileSource> create_audio_source_for_session (ARDOUR::AudioDiskstream&, uint32_t which_channel, bool destructive);
-
- boost::shared_ptr<MidiSource> create_midi_source_for_session (ARDOUR::MidiDiskstream&);
+ boost::shared_ptr<AudioFileSource> create_audio_source_for_session (size_t, std::string const &, uint32_t,
+ bool destructive, bool as_stub = false);
+
+ boost::shared_ptr<MidiSource> create_midi_source_for_session (Track*, std::string const &, bool as_stub = false);
boost::shared_ptr<Source> source_by_id (const PBD::ID&);
boost::shared_ptr<Source> source_by_path_and_channel (const Glib::ustring&, uint16_t);
/* named selections */
- NamedSelection* named_selection_by_name (std::string name);
- void add_named_selection (NamedSelection *);
- void remove_named_selection (NamedSelection *);
+ boost::shared_ptr<NamedSelection> named_selection_by_name (std::string name);
+ void add_named_selection (boost::shared_ptr<NamedSelection>);
+ void remove_named_selection (boost::shared_ptr<NamedSelection>);
- template<class T> void foreach_named_selection (T& obj, void (T::*func)(NamedSelection&));
- sigc::signal<void> NamedSelectionAdded;
- sigc::signal<void> NamedSelectionRemoved;
+ template<class T> void foreach_named_selection (T& obj, void (T::*func)(boost::shared_ptr<NamedSelection>));
+ PBD::Signal0<void> NamedSelectionAdded;
+ PBD::Signal0<void> NamedSelectionRemoved;
/* Curves and AutomationLists (TODO when they go away) */
void add_automation_list(AutomationList*);
void cancel_audition ();
bool is_auditioning () const;
- sigc::signal<void,bool> AuditionActive;
+ PBD::Signal1<void,bool> AuditionActive;
/* flattening stuff */
boost::shared_ptr<Region> write_one_track (AudioTrack&, nframes_t start, nframes_t end,
bool overwrite, std::vector<boost::shared_ptr<Source> >&, InterThreadInfo& wot,
bool enable_processing = true);
- int freeze (InterThreadInfo&);
+ int freeze_all (InterThreadInfo&);
/* session-wide solo/mute/rec-enable */
bool soloing() const { return _non_soloed_outs_muted; }
bool listening() const { return _listen_cnt > 0; }
+ bool solo_isolated() const { return _solo_isolated_cnt > 0; }
- void set_all_solo (bool);
- void set_all_mute (bool);
- void set_all_listen (bool);
-
- sigc::signal<void,bool> SoloActive;
- sigc::signal<void> SoloChanged;
+ static const SessionEvent::RTeventCallback rt_cleanup;
- void record_disenable_all (sigc::slot<void,SessionEvent*>);
- void record_enable_all (sigc::slot<void,SessionEvent*>);
+ void set_solo (boost::shared_ptr<RouteList>, bool, SessionEvent::RTeventCallback after = rt_cleanup, bool group_override = false);
+ void set_just_one_solo (boost::shared_ptr<Route>, bool, SessionEvent::RTeventCallback after = rt_cleanup);
+ void set_mute (boost::shared_ptr<RouteList>, bool, SessionEvent::RTeventCallback after = rt_cleanup, bool group_override = false);
+ void set_listen (boost::shared_ptr<RouteList>, bool, SessionEvent::RTeventCallback after = rt_cleanup, bool group_override = false);
+ void set_record_enable (boost::shared_ptr<RouteList>, bool, SessionEvent::RTeventCallback after = rt_cleanup, bool group_override = false);
+ void set_solo_isolated (boost::shared_ptr<RouteList>, bool, SessionEvent::RTeventCallback after = rt_cleanup, bool group_override = false);
+ PBD::Signal1<void,bool> SoloActive;
+ PBD::Signal0<void> SoloChanged;
+ PBD::Signal0<void> IsolatedChanged;
+
/* control/master out */
- boost::shared_ptr<Route> control_out() const { return _control_out; }
+ boost::shared_ptr<Route> monitor_out() const { return _monitor_out; }
boost::shared_ptr<Route> master_out() const { return _master_out; }
void globally_add_internal_sends (boost::shared_ptr<Route> dest, Placement p);
void mark_send_id (uint32_t);
void mark_return_id (uint32_t);
void mark_insert_id (uint32_t);
+ void unmark_send_id (uint32_t);
+ void unmark_return_id (uint32_t);
+ void unmark_insert_id (uint32_t);
/* s/w "RAID" management */
void remove_bundle (boost::shared_ptr<Bundle>);
boost::shared_ptr<Bundle> bundle_by_name (std::string) const;
- sigc::signal<void,boost::shared_ptr<Bundle> > BundleAdded;
- sigc::signal<void,boost::shared_ptr<Bundle> > BundleRemoved;
-
- /* MIDI control */
-
- void midi_panic(void);
- int set_mtc_port (std::string port_tag);
- int set_mmc_port (std::string port_tag);
- int set_midi_port (std::string port_tag);
- int set_midi_clock_port (std::string port_tag);
- MIDI::Port *mtc_port() const { return _mtc_port; }
- MIDI::Port *mmc_port() const { return _mmc_port; }
- MIDI::Port *midi_port() const { return _midi_port; }
- MIDI::Port *midi_clock_port() const { return _midi_clock_port; }
-
- sigc::signal<void> MTC_PortChanged;
- sigc::signal<void> MMC_PortChanged;
- sigc::signal<void> MIDI_PortChanged;
- sigc::signal<void> MIDIClock_PortChanged;
-
- void set_trace_midi_input (bool, MIDI::Port* port = 0);
- void set_trace_midi_output (bool, MIDI::Port* port = 0);
+ PBD::Signal1<void,boost::shared_ptr<Bundle> > BundleAdded;
+ PBD::Signal1<void,boost::shared_ptr<Bundle> > BundleRemoved;
- bool get_trace_midi_input(MIDI::Port *port = 0);
- bool get_trace_midi_output(MIDI::Port *port = 0);
-
- void set_mmc_receive_device_id (uint32_t id);
- void set_mmc_send_device_id (uint32_t id);
+ void midi_panic ();
/* Scrubbing */
void stop_scrub ();
void set_scrub_speed (float);
nframes_t scrub_buffer_size() const;
- sigc::signal<void> ScrubReady;
+ PBD::Signal0<void> ScrubReady;
/* History (for editors, mixers, UIs etc.) */
_current_trans.top()->add_command (cmd);
}
- std::map<PBD::ID, PBD::StatefulThingWithGoingAway*> registry;
+ std::map<PBD::ID,PBD::StatefulDestructible*> registry;
// these commands are implemented in libs/ardour/session_command.cc
Command* memento_command_factory(XMLNode* n);
- void register_with_memento_command_factory(PBD::ID, PBD::StatefulThingWithGoingAway*);
-
- Command* global_state_command_factory (const XMLNode& n);
-
- class GlobalRouteStateCommand : public Command
- {
- public:
- GlobalRouteStateCommand (Session&, void*);
- GlobalRouteStateCommand (Session&, const XMLNode& node);
- int set_state (const XMLNode&, int version);
- XMLNode& get_state ();
-
- protected:
- GlobalRouteBooleanState before, after;
- Session& sess;
- void* src;
- };
-
- class GlobalSoloStateCommand : public GlobalRouteStateCommand
- {
- public:
- GlobalSoloStateCommand (Session &, void *src);
- GlobalSoloStateCommand (Session&, const XMLNode&);
- void operator()(); //redo
- void undo();
- XMLNode &get_state();
- void mark();
- };
-
- class GlobalMuteStateCommand : public GlobalRouteStateCommand
- {
- public:
- GlobalMuteStateCommand(Session &, void *src);
- GlobalMuteStateCommand (Session&, const XMLNode&);
- void operator()(); // redo
- void undo();
- XMLNode &get_state();
- void mark();
- };
-
- class GlobalRecordEnableStateCommand : public GlobalRouteStateCommand
- {
- public:
- GlobalRecordEnableStateCommand(Session &, void *src);
- GlobalRecordEnableStateCommand (Session&, const XMLNode&);
- void operator()(); // redo
- void undo();
- XMLNode &get_state();
- void mark();
- };
-
- class GlobalMeteringStateCommand : public Command
- {
- public:
- GlobalMeteringStateCommand(Session &, void *src);
- GlobalMeteringStateCommand (Session&, const XMLNode&);
- void operator()();
- void undo();
- XMLNode &get_state();
- int set_state (const XMLNode&, int version);
- void mark();
-
- protected:
- Session& sess;
- void* src;
- GlobalRouteMeterState before;
- GlobalRouteMeterState after;
- };
+ Command* stateful_diff_command_factory (XMLNode *);
+ void register_with_memento_command_factory(PBD::ID, PBD::StatefulDestructible*);
/* clicking */
uint32_t playback_load ();
uint32_t capture_load ();
- uint32_t playback_load_min ();
- uint32_t capture_load_min ();
-
- void reset_playback_load_min ();
- void reset_capture_load_min ();
/* ranges */
/* 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; }
+ gain_t* gain_automation_buffer () const;
+ pan_t** pan_automation_buffer () const;
void ensure_buffer_set (BufferSet& buffers, const ChanCount& howmany);
void* ptr,
float opt);
- static sigc::signal<void> SendFeedback;
+ static PBD::Signal0<void> SendFeedback;
/* Controllables */
boost::shared_ptr<PBD::Controllable> controllable_by_id (const PBD::ID&);
+ boost::shared_ptr<PBD::Controllable> controllable_by_descriptor (const PBD::ControllableDescriptor&);
void add_controllable (boost::shared_ptr<PBD::Controllable>);
void remove_controllable (PBD::Controllable*);
PostTransportReverse = 0x10000,
PostTransportInputChange = 0x20000,
PostTransportCurveRealloc = 0x40000,
- PostTransportClearSubstate = 0x80000
+ PostTransportClearSubstate = 0x80000,
+ PostTransportAdjustPlaybackBuffering = 0x100000,
+ PostTransportAdjustCaptureBuffering = 0x200000
};
enum SlaveState {
boost::shared_ptr<SessionPlaylists> playlists;
+ void send_mmc_locate (nframes64_t);
+ int send_full_time_code (nframes64_t);
+
+ PBD::Signal0<void> RouteOrderKeyChanged;
+
protected:
friend class AudioEngine;
void set_block_size (nframes_t nframes);
void update_latency_compensation (bool, bool);
private:
- int create (bool& new_session, const std::string& mix_template, nframes_t initial_length);
+ int create (const std::string& mix_template, BusProfile*);
void destroy ();
- nframes_t compute_initial_length ();
-
enum SubState {
PendingDeclickIn = 0x1,
PendingDeclickOut = 0x2,
StopPendingCapture = 0x4,
- AutoReturning = 0x10,
PendingLocate = 0x20,
- PendingSetLoop = 0x40
};
/* stuff used in process() should be close together to
int transport_sub_state;
mutable gint _record_status;
volatile nframes64_t _transport_frame;
- Location* end_location;
- Location* start_location;
+ Location* _session_range_location; ///< session range, or 0 if there is nothing in the session yet
Slave* _slave;
bool _silent;
nframes64_t _last_slave_transport_frame;
nframes_t maximum_output_latency;
volatile nframes64_t _requested_return_frame;
- BufferSet* _scratch_buffers;
- BufferSet* _silent_buffers;
- BufferSet* _mix_buffers;
nframes_t current_block_size;
nframes_t _worst_output_latency;
nframes_t _worst_input_latency;
float _meter_falloff;
bool _non_soloed_outs_muted;
uint32_t _listen_cnt;
+ uint32_t _solo_isolated_cnt;
bool _writable;
bool _was_seamless;
void update_latency_compensation_proxy (void* ignored);
- void ensure_buffers (ChanCount howmany);
+ void ensure_buffers (ChanCount howmany = ChanCount::ZERO);
void process_scrub (nframes_t);
void process_without_events (nframes_t);
void unblock_processing() { g_atomic_int_set (&processing_prohibited, 0); }
bool processing_blocked() const { return g_atomic_int_get (&processing_prohibited); }
+ Glib::Mutex process_thread_lock;
+ std::list<ProcessThread*> process_threads;
+
/* slave tracking */
static const int delta_accumulator_size = 25;
nframes_t post_export_position;
bool _exporting;
- bool _exporting_realtime;
+ bool _export_rolling;
boost::shared_ptr<ExportHandler> export_handler;
boost::shared_ptr<ExportStatus> export_status;
int stop_audio_export ();
void finalize_audio_export ();
- sigc::connection export_freewheel_connection;
+ PBD::ScopedConnection export_freewheel_connection;
- void prepare_diskstreams ();
- void commit_diskstreams (nframes_t, bool& session_requires_butler);
- int process_routes (nframes_t);
- int silent_process_routes (nframes_t);
+ void get_track_statistics ();
+ int process_routes (nframes_t, bool& need_butler);
+ int silent_process_routes (nframes_t, bool& need_butler);
bool get_rec_monitors_input () {
if (actively_recording()) {
void check_declick_out ();
- MIDI::MachineControl* mmc;
- MIDI::Port* _mmc_port;
- MIDI::Port* _mtc_port;
- MIDI::Port* _midi_port;
- MIDI::Port* _midi_clock_port;
std::string _path;
std::string _name;
- bool session_send_mmc;
+ bool _is_new;
bool session_send_mtc;
bool session_midi_feedback;
bool play_loop;
int load_state (std::string snapshot_name);
nframes_t _last_roll_location;
+ nframes_t _last_roll_or_reversal_location;
nframes_t _last_record_location;
bool pending_locate_roll;
void set_post_transport_work (PostTransportWork ptw) { g_atomic_int_set (&_post_transport_work, (gint) ptw); }
void add_post_transport_work (PostTransportWork ptw);
+ void schedule_playback_buffering_adjustment ();
+ void schedule_capture_buffering_adjustment ();
+
uint32_t cumulative_rf_motion;
uint32_t rf_scale;
void locations_added (Location*);
void handle_locations_changed (Locations::LocationList&);
- sigc::connection auto_punch_start_changed_connection;
- sigc::connection auto_punch_end_changed_connection;
- sigc::connection auto_punch_changed_connection;
+ PBD::ScopedConnectionList punch_connections;
void auto_punch_start_changed (Location *);
void auto_punch_end_changed (Location *);
void auto_punch_changed (Location *);
- sigc::connection auto_loop_start_changed_connection;
- sigc::connection auto_loop_end_changed_connection;
- sigc::connection auto_loop_changed_connection;
+ PBD::ScopedConnectionList loop_connections;
void auto_loop_changed (Location *);
void first_stage_init (std::string path, std::string snapshot_name);
- int second_stage_init (bool new_tracks);
- void find_current_end ();
+ int second_stage_init ();
+ void update_session_range_location_marker ();
void remove_empty_sounds ();
void setup_midi_control ();
/* SessionEventManager interface */
- void queue_event (SessionEvent*);
void process_event (SessionEvent*);
void set_next_event ();
void cleanup_event (SessionEvent*,int);
/* MIDI Machine Control */
- void deliver_mmc (MIDI::MachineControl::Command, nframes_t);
-
void spp_start (MIDI::Parser&, nframes_t timestamp);
void spp_continue (MIDI::Parser&, nframes_t timestamp);
void spp_stop (MIDI::Parser&, nframes_t timestamp);
struct timeval last_mmc_step;
double step_speed;
- typedef sigc::slot<bool> MidiTimeoutCallback;
+ typedef boost::function<bool()> MidiTimeoutCallback;
typedef std::list<MidiTimeoutCallback> MidiTimeoutList;
MidiTimeoutList midi_timeouts;
bool mmc_step_timeout ();
- MIDI::byte mmc_buffer[32];
MIDI::byte mtc_msg[16];
MIDI::byte mtc_timecode_bits; /* encoding of SMTPE type for MTC */
MIDI::byte midi_msg[16];
bool _send_timecode_update; ///< Flag to send a full frame (Timecode) MTC message this cycle
- int send_full_time_code(nframes_t nframes);
int send_midi_time_code_for_cycle(nframes_t nframes);
nframes_t adjust_apparent_position (nframes_t frames);
bool non_realtime_work_pending() const { return static_cast<bool>(post_transport_work()); }
bool process_can_proceed() const { return !(post_transport_work() & ProcessCannotProceedMask); }
- struct MIDIRequest {
- enum Type {
- PortChange,
- Quit
- };
- Type type;
- };
-
- Glib::Mutex midi_lock;
- pthread_t midi_thread;
- int midi_request_pipe[2];
- RingBuffer<MIDIRequest*> midi_requests;
+ MidiControlUI* midi_control_ui;
int start_midi_thread ();
void terminate_midi_thread ();
- void poke_midi_thread ();
- static void *_midi_thread_work (void *arg);
- void midi_thread_work ();
- void change_midi_ports ();
- int use_config_midi_ports ();
void set_play_loop (bool yn);
void unset_play_loop ();
- void overwrite_some_buffers (Diskstream*);
+ void overwrite_some_buffers (Track *);
void flush_all_inserts ();
int micro_locate (nframes_t distance);
- void locate (nframes64_t, bool with_roll, bool with_flush, bool with_loop=false, bool force=false);
+ void locate (nframes64_t, bool with_roll, bool with_flush, bool with_loop=false, bool force=false, bool with_mmc=true);
void start_locate (nframes64_t, bool with_roll, bool with_flush, bool with_loop=false, bool force=false);
void force_locate (nframes64_t frame, bool with_roll = false);
- void set_diskstream_speed (Diskstream*, double speed);
+ void set_track_speed (Track *, double speed);
void set_transport_speed (double speed, bool abort = false, bool clear_state = false);
void stop_transport (bool abort = false, bool clear_state = false);
void start_transport ();
void xrun_recovery ();
TempoMap *_tempo_map;
- void tempo_map_changed (Change);
+ void tempo_map_changed (const PBD::PropertyChange&);
/* edit/mix groups */
std::list<RouteGroup *> _route_groups;
- /* disk-streams */
-
- SerializedRCUManager<DiskstreamList> diskstreams;
-
- int load_diskstreams (const XMLNode&);
-
/* routes stuff */
+ boost::shared_ptr<Graph> route_graph;
+
SerializedRCUManager<RouteList> routes;
void add_routes (RouteList&, bool save);
uint32_t destructive_index;
boost::shared_ptr<Route> XMLRouteFactory (const XMLNode&, int);
+ boost::shared_ptr<Route> XMLRouteFactory_2X (const XMLNode&, int);
void route_processors_changed (RouteProcessorChange);
+ bool find_route_name (const char* base, uint32_t& id, char* name, size_t name_len);
+ void count_existing_route_channels (ChanCount& in, ChanCount& out);
+ void auto_connect_route (boost::shared_ptr<Route> route, ChanCount& existing_inputs, ChanCount& existing_outputs, bool connect_inputs = true);
+
/* mixer stuff */
bool solo_update_disabled;
void route_listen_changed (void *src, boost::weak_ptr<Route>);
void route_mute_changed (void *src);
- void route_solo_changed (void *src, boost::weak_ptr<Route>);
+ void route_solo_changed (bool self_solo_change, void *src, boost::weak_ptr<Route>);
+ void route_solo_isolated_changed (void *src, boost::weak_ptr<Route>);
void update_route_solo_state (boost::shared_ptr<RouteList> r = boost::shared_ptr<RouteList>());
void listen_position_changed ();
/* REGION MANAGEMENT */
- std::map<std::string,uint32_t> region_name_map;
- void update_region_name_map (boost::shared_ptr<Region>);
-
mutable Glib::Mutex region_lock;
- typedef std::map<PBD::ID,boost::shared_ptr<Region> > RegionList;
- RegionList regions;
-
- void add_region (boost::shared_ptr<Region>);
- void region_changed (Change, boost::weak_ptr<Region>);
- void remove_region (boost::weak_ptr<Region>);
int load_regions (const XMLNode& node);
/* SOURCES */
mutable Glib::Mutex source_lock;
+
+ public:
typedef std::map<PBD::ID,boost::shared_ptr<Source> > SourceMap;
+ private:
SourceMap sources;
public:
void remove_playlist (boost::weak_ptr<Playlist>);
void playlist_length_changed ();
- void diskstream_playlist_changed (boost::weak_ptr<Diskstream>);
+ void track_playlist_changed (boost::weak_ptr<Track>);
/* NAMED SELECTIONS */
mutable Glib::Mutex named_selection_lock;
- typedef std::set<NamedSelection *> NamedSelectionList;
+ typedef std::set<boost::shared_ptr<NamedSelection> > NamedSelectionList;
NamedSelectionList named_selections;
int load_named_selections (const XMLNode&);
boost::dynamic_bitset<uint32_t> return_bitset;
boost::dynamic_bitset<uint32_t> insert_bitset;
- void add_processor (Processor *);
- void remove_processor (Processor *);
-
/* S/W RAID */
struct space_and_path {
mutable gint _playback_load;
mutable gint _capture_load;
- mutable gint _playback_load_min;
- mutable gint _capture_load_min;
/* I/O bundles */
XMLNode* _bundle_xml_node;
int load_bundles (XMLNode const &);
- void reverse_diskstream_buffers ();
+ void reverse_track_buffers ();
UndoHistory _history;
std::stack<UndoTransaction*> _current_trans;
- GlobalRouteBooleanState get_global_route_boolean (bool (Route::*method)(void) const);
- GlobalRouteMeterState get_global_route_metering ();
-
- void set_global_route_boolean (GlobalRouteBooleanState s, void (Route::*method)(bool, void*), void *arg);
- void set_global_route_metering (GlobalRouteMeterState s, void *arg);
-
- void set_global_mute (GlobalRouteBooleanState s, void *src);
- void set_global_solo (GlobalRouteBooleanState s, void *src);
- void set_global_record_enable (GlobalRouteBooleanState s, void *src);
-
void jack_timebase_callback (jack_transport_state_t, nframes_t, jack_position_t*, int);
int jack_sync_callback (jack_transport_state_t, jack_position_t*);
void reset_jack_connection (jack_client_t* jack);
- void record_enable_change_all (bool yn, sigc::slot<void,SessionEvent*>);
- void do_record_enable_change_all (RouteList*, bool);
void process_rtop (SessionEvent*);
XMLNode& state(bool);
uint32_t main_outs;
boost::shared_ptr<Route> _master_out;
- boost::shared_ptr<Route> _control_out;
-
- gain_t* _gain_automation_buffer;
- pan_t** _pan_automation_buffer;
- void allocate_pan_automation_buffers (nframes_t nframes, uint32_t howmany, bool force);
- uint32_t _npan_buffers;
+ boost::shared_ptr<Route> _monitor_out;
/* VST support */
mutable bool have_looped; ///< Used in ::audible_frame(*)
- void update_have_rec_enabled_diskstream ();
- gint _have_rec_enabled_diskstream;
+ void update_have_rec_enabled_track ();
+ gint _have_rec_enabled_track;
+
+ static int ask_about_playlist_deletion (boost::shared_ptr<Playlist>);
+
+ /* realtime "apply to set of routes" operations */
+ SessionEvent* get_rt_event (boost::shared_ptr<RouteList> rl, bool yn, SessionEvent::RTeventCallback after, bool group_override,
+ void (Session::*method) (boost::shared_ptr<RouteList>, bool, bool));
+
+ void rt_set_solo (boost::shared_ptr<RouteList>, bool yn, bool group_override);
+ void rt_set_just_one_solo (boost::shared_ptr<RouteList>, bool yn, bool /* ignored*/ );
+ void rt_set_mute (boost::shared_ptr<RouteList>, bool yn, bool group_override);
+ void rt_set_listen (boost::shared_ptr<RouteList>, bool yn, bool group_override);
+ void rt_set_solo_isolated (boost::shared_ptr<RouteList>, bool yn, bool group_override);
+ void rt_set_record_enable (boost::shared_ptr<RouteList>, bool yn, bool group_override);
+
+ /** temporary list of Diskstreams used only during load of 2.X sessions */
+ std::list<boost::shared_ptr<Diskstream> > _diskstreams_2X;
+
+ void add_session_range_location (nframes_t, nframes_t);
+
+ void setup_midi_machine_control ();
+ void cleanup_stubfiles ();
+
+ void route_order_key_changed ();
};
} // namespace ARDOUR