#include <glibmm/thread.h>
#include "pbd/error.h"
+#include "pbd/event_loop.h"
#include "pbd/rcu.h"
#include "pbd/statefuldestructible.h"
#include "pbd/signals.h"
#include "pbd/undo.h"
+#include "evoral/types.hpp"
+
#include "midi++/types.h"
#include "timecode/time.h"
#include "ardour/ardour.h"
-#include "ardour/click.h"
#include "ardour/chan_count.h"
#include "ardour/rc_configuration.h"
#include "ardour/session_configuration.h"
#include "ardour/session_event.h"
#include "ardour/location.h"
#include "ardour/interpolation.h"
-#include "ardour/speakers.h"
+#include "ardour/route_graph.h"
#ifdef HAVE_JACK_SESSION
#include <jack/session.h>
class XMLTree;
class XMLNode;
-class AEffect;
+struct _AEffect;
+typedef struct _AEffect AEffect;
namespace MIDI {
class Port;
class BufferSet;
class Bundle;
class Butler;
+class Click;
class Diskstream;
class ExportHandler;
class ExportStatus;
+class Graph;
class IO;
class IOProcessor;
class ImportStatus;
+class MidiControlUI;
class MidiRegion;
class MidiSource;
class MidiTrack;
-class MidiControlUI;
class NamedSelection;
class Playlist;
class PluginInsert;
class Source;
class Speakers;
class TempoMap;
-class VSTPlugin;
-class Graph;
class Track;
+class WindowsVSTPlugin;
extern void setup_enum_writer ();
static PBD::Signal1<void,std::string> Dialog;
- std::string sound_dir (bool with_path = true) const;
- std::string peak_dir () const;
- std::string dead_dir () const;
+ int ensure_subdirs ();
+
std::string automation_dir () const;
std::string analysis_dir() const;
std::string plugins_dir() const;
-
- int ensure_subdirs ();
std::string peak_path (std::string) const;
void refresh_disk_space ();
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);
+ static char session_name_is_legal (const std::string&);
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);
+ boost::shared_ptr<Track> track_by_diskstream_id (PBD::ID);
+ void routes_using_input_from (const std::string& str, RouteList& rl);
bool route_name_unique (std::string) const;
bool route_name_internal (std::string) const;
return (RecordState) g_atomic_int_get (&_record_status);
}
- bool actively_recording () {
+ bool actively_recording () const {
return record_status() == Recording;
}
/* Transport mechanism signals */
- PBD::Signal0<void> TransportStateChange; /* generic */
+ /** Emitted on the following changes in transport state:
+ * - stop (from the butler thread)
+ * - change in whether or not we are looping (from the process thread)
+ * - change in the play range (from the process thread)
+ * - start (from the process thread)
+ * - engine halted
+ */
+ PBD::Signal0<void> TransportStateChange;
+
PBD::Signal1<void,framepos_t> PositionChanged; /* sent after any non-sequential motion */
PBD::Signal1<void,framepos_t> Xrun;
PBD::Signal0<void> TransportLooped;
PBD::Signal0<void> Located;
PBD::Signal1<void,RouteList&> RouteAdded;
- /** Emitted when anything about any of our route groups changes */
- PBD::Signal0<void> RouteGroupChanged;
+ /** Emitted when a property of one of our route groups changes.
+ * The parameter is the RouteGroup that has changed.
+ */
+ PBD::Signal1<void, RouteGroup *> RouteGroupPropertyChanged;
+ /** Emitted when a route is added to one of our route groups.
+ * First parameter is the RouteGroup, second is the route.
+ */
+ PBD::Signal2<void, RouteGroup *, boost::weak_ptr<Route> > RouteAddedToRouteGroup;
+ /** Emitted when a route is removed from one of our route groups.
+ * First parameter is the RouteGroup, second is the route.
+ */
+ PBD::Signal2<void, RouteGroup *, boost::weak_ptr<Route> > RouteRemovedFromRouteGroup;
/* Step Editing status changed */
PBD::Signal1<void,bool> StepEditStatusChange;
framecnt_t worst_track_latency () const { return _worst_track_latency; }
framecnt_t worst_playback_latency () const { return _worst_output_latency + _worst_track_latency; }
-#ifdef HAVE_JACK_SESSION
+#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);
void remove_state (std::string snapshot_name);
void rename_state (std::string old_name, std::string new_name);
void remove_pending_capture_state ();
-
- static int rename_template (std::string old_name, std::string new_name);
- static int delete_template (std::string name);
+ int rename (const std::string&);
PBD::Signal1<void,std::string> StateSaved;
PBD::Signal0<void> StateReady;
void timecode_duration_string (char *, framecnt_t) const;
framecnt_t convert_to_frames (AnyTime const & position);
- framecnt_t any_duration_to_frames (framepos_t position, AnyTime const & duration);
+ framecnt_t any_duration_to_frames (framepos_t position, AnyTime const & duration);
static PBD::Signal1<void, framepos_t> StartTimeChanged;
static PBD::Signal1<void, framepos_t> EndTimeChanged;
boost::shared_ptr<AudioFileSource> create_audio_source_for_session (
size_t, std::string const &, uint32_t, bool destructive);
-
+
boost::shared_ptr<MidiSource> create_midi_source_for_session (
Track*, std::string const &);
void set_listen (boost::shared_ptr<RouteList>, bool, SessionEvent::RTeventCallback after = rt_cleanup, bool group_override = false);
void set_record_enabled (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);
+ void set_exclusive_input_active (boost::shared_ptr<Route> rt, bool others_on);
+ void set_monitoring (boost::shared_ptr<RouteList>, MonitorChoice, 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> monitor_out() const { return _monitor_out; }
/* VST support */
- static long vst_callback (AEffect* effect,
- long opcode,
- long index,
- long value,
- void* ptr,
- float opt);
-
+ static intptr_t vst_callback (
+ AEffect* effect,
+ int32_t opcode,
+ int32_t index,
+ intptr_t value,
+ void* ptr,
+ float opt
+ );
+
static PBD::Signal0<void> SendFeedback;
/* Speakers */
- boost::shared_ptr<Speakers> get_speakers ();
+ boost::shared_ptr<Speakers> get_speakers ();
/* Controllables */
void add_controllable (boost::shared_ptr<PBD::Controllable>);
void remove_controllable (PBD::Controllable*);
- boost::shared_ptr<PBD::Controllable> solo_cut_control() const;
+ boost::shared_ptr<PBD::Controllable> solo_cut_control() const;
SessionMetadata & metadata () { return *_metadata; }
enum PostTransportWork {
PostTransportStop = 0x1,
- PostTransportDisableRecord = 0x2,
- PostTransportPosition = 0x8,
- PostTransportDidRecord = 0x20,
- PostTransportDuration = 0x40,
- PostTransportLocate = 0x80,
- PostTransportRoll = 0x200,
- PostTransportAbort = 0x800,
- PostTransportOverWrite = 0x1000,
- PostTransportSpeed = 0x2000,
- PostTransportAudition = 0x4000,
- PostTransportScrub = 0x8000,
- PostTransportReverse = 0x10000,
- PostTransportInputChange = 0x20000,
- PostTransportCurveRealloc = 0x40000,
- PostTransportClearSubstate = 0x80000,
- PostTransportAdjustPlaybackBuffering = 0x100000,
- PostTransportAdjustCaptureBuffering = 0x200000
+ PostTransportDuration = 0x2,
+ PostTransportLocate = 0x4,
+ PostTransportRoll = 0x8,
+ PostTransportAbort = 0x10,
+ PostTransportOverWrite = 0x20,
+ PostTransportSpeed = 0x40,
+ PostTransportAudition = 0x80,
+ PostTransportReverse = 0x100,
+ PostTransportInputChange = 0x200,
+ PostTransportCurveRealloc = 0x400,
+ PostTransportClearSubstate = 0x800,
+ PostTransportAdjustPlaybackBuffering = 0x1000,
+ PostTransportAdjustCaptureBuffering = 0x2000
};
enum SlaveState {
Waiting,
Running
};
-
+
SlaveState slave_state() const { return _slave_state; }
boost::shared_ptr<SessionPlaylists> playlists;
std::list<std::string> unknown_processors () const;
+ /** Emitted when a feedback cycle has been detected within Ardour's signal
+ processing path. Until it is fixed (by the user) some (unspecified)
+ routes will not be run.
+ */
+ static PBD::Signal0<void> FeedbackDetected;
+
+ /** Emitted when a graph sort has successfully completed, which means
+ that it has no feedback cycles.
+ */
+ static PBD::Signal0<void> SuccessfulGraphSort;
+
/* handlers can return an integer value:
0: config.set_audio_search_path() or config.set_midi_search_path() was used
to modify the search path and we should try to find it again.
bool _silent;
void maybe_update_session_range (framepos_t, framepos_t);
-
+
// varispeed playback
double _transport_speed;
double _last_transport_speed;
bool _writable;
bool _was_seamless;
+ void initialize_latencies ();
void set_worst_io_latencies ();
void set_worst_playback_latency ();
void set_worst_capture_latency ();
void set_worst_io_latencies_x (IOChange, void *) {
set_worst_io_latencies ();
}
- void post_capture_latency ();
- void post_playback_latency ();
+ void post_capture_latency ();
+ void post_playback_latency ();
void update_latency_compensation_proxy (void* ignored);
int process_routes (pframes_t, bool& need_butler);
int silent_process_routes (pframes_t, bool& need_butler);
- bool get_rec_monitors_input () {
- if (actively_recording()) {
- return true;
- } else {
- if (config.get_auto_input()) {
- return false;
- } else {
- return true;
- }
- }
- }
-
int get_transport_declick_required () {
if (transport_sub_state & PendingDeclickIn) {
transport_sub_state &= ~PendingDeclickIn;
void when_engine_running ();
void graph_reordered ();
+ /** current snapshot name, without the .ardour suffix */
std::string _current_snapshot_name;
XMLTree* state_tree;
Butler* _butler;
-#if 0 // these should be here, see comments in their other location above
- enum PostTransportWork {
- PostTransportStop = 0x1,
- PostTransportDisableRecord = 0x2,
- PostTransportPosition = 0x8,
- PostTransportDidRecord = 0x20,
- PostTransportDuration = 0x40,
- PostTransportLocate = 0x80,
- PostTransportRoll = 0x200,
- PostTransportAbort = 0x800,
- PostTransportOverWrite = 0x1000,
- PostTransportSpeed = 0x2000,
- PostTransportAudition = 0x4000,
- PostTransportScrub = 0x8000,
- PostTransportReverse = 0x10000,
- PostTransportInputChange = 0x20000,
- PostTransportCurveRealloc = 0x40000,
- PostTransportClearSubstate = 0x80000
- };
-#endif
static const PostTransportWork ProcessCannotProceedMask =
PostTransportWork (
PostTransportInputChange|
PostTransportSpeed|
PostTransportReverse|
PostTransportCurveRealloc|
- PostTransportScrub|
PostTransportAudition|
PostTransportLocate|
PostTransportStop|
void stop_transport (bool abort = false, bool clear_state = false);
void start_transport ();
void realtime_stop (bool abort, bool clear_state);
+ void realtime_locate ();
void non_realtime_start_scrub ();
void non_realtime_set_speed ();
void non_realtime_locate ();
/* routes stuff */
- boost::shared_ptr<Graph> route_graph;
+ boost::shared_ptr<Graph> _process_graph;
SerializedRCUManager<RouteList> routes;
bool find_route_name (std::string const &, uint32_t& id, char* name, size_t name_len, bool);
void count_existing_track_channels (ChanCount& in, ChanCount& out);
void auto_connect_route (boost::shared_ptr<Route> route, ChanCount& existing_inputs, ChanCount& existing_outputs,
- bool with_lock, bool connect_inputs = true,
- ChanCount input_start = ChanCount (), ChanCount output_start = ChanCount ());
- void midi_output_change_handler (IOChange change, void* /*src*/, boost::weak_ptr<Route> midi_track);
+ bool with_lock, bool connect_inputs = true,
+ ChanCount input_start = ChanCount (), ChanCount output_start = ChanCount ());
+ void midi_output_change_handler (IOChange change, void* /*src*/, boost::weak_ptr<Route> midi_track);
/* mixer stuff */
mutable Glib::Mutex region_lock;
int load_regions (const XMLNode& node);
+ int load_compounds (const XMLNode& node);
- void route_group_changed ();
+ void route_added_to_route_group (RouteGroup *, boost::weak_ptr<Route>);
+ void route_removed_from_route_group (RouteGroup *, boost::weak_ptr<Route>);
+ void route_group_property_changed (RouteGroup *);
/* SOURCES */
mutable Glib::Mutex source_lock;
- public:
+ public:
typedef std::map<PBD::ID,boost::shared_ptr<Source> > SourceMap;
- private:
+ private:
SourceMap sources;
public:
XMLNode* _bundle_xml_node;
int load_bundles (XMLNode const &);
- void reverse_track_buffers ();
-
UndoHistory _history;
/** current undo transaction, or 0 */
UndoTransaction* _current_trans;
void reset_jack_connection (jack_client_t* jack);
void process_rtop (SessionEvent*);
- void update_latency (bool playback);
+ void update_latency (bool playback);
XMLNode& state(bool);
/* click track */
-
+ typedef std::list<Click*> Clicks;
Clicks clicks;
bool _clicking;
boost::shared_ptr<IO> _click_io;
boost::shared_ptr<Route> _master_out;
boost::shared_ptr<Route> _monitor_out;
- /* VST support */
+ /* Windows VST support */
- long _vst_callback (VSTPlugin*,
- long opcode,
- long index,
- long value,
- void* ptr,
- float opt);
+ long _windows_vst_callback (
+ WindowsVSTPlugin*,
+ long opcode,
+ long index,
+ long value,
+ void* ptr,
+ float opt
+ );
/* number of hardware ports we're using,
based on max (requested,available)
Glib::Mutex controllables_lock;
Controllables controllables;
- boost::shared_ptr<PBD::Controllable> _solo_cut_control;
+ boost::shared_ptr<PBD::Controllable> _solo_cut_control;
void reset_native_file_format();
bool first_file_data_format_reset;
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));
+ template<typename T> SessionEvent*
+ get_rt_event (boost::shared_ptr<RouteList> rl, T targ, SessionEvent::RTeventCallback after, bool group_override,
+ void (Session::*method) (boost::shared_ptr<RouteList>, T, bool)) {
+ SessionEvent* ev = new SessionEvent (SessionEvent::RealTimeOperation, SessionEvent::Add, SessionEvent::Immediate, 0, 0.0);
+ ev->rt_slot = boost::bind (method, this, rl, targ, group_override);
+ ev->rt_return = after;
+ ev->event_loop = PBD::EventLoop::get_event_loop_for_thread ();
+
+ return ev;
+ }
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_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_enabled (boost::shared_ptr<RouteList>, bool yn, bool group_override);
+ void rt_set_monitoring (boost::shared_ptr<RouteList>, MonitorChoice, bool group_override);
/** temporary list of Diskstreams used only during load of 2.X sessions */
std::list<boost::shared_ptr<Diskstream> > _diskstreams_2X;
void start_time_changed (framepos_t);
void end_time_changed (framepos_t);
- void set_track_monitor_input_status (bool);
+ void set_track_monitor_input_status (bool);
+ framepos_t compute_stop_limit () const;
- boost::shared_ptr<Speakers> _speakers;
+ boost::shared_ptr<Speakers> _speakers;
+ void load_nested_sources (const XMLNode& node);
+
+ /** The directed graph of routes that is currently being used for audio processing
+ and solo/mute computations.
+ */
+ GraphEdges _current_route_graph;
};
} // namespace ARDOUR