#include <set>
#include <string>
#include <vector>
+#include <queue>
#include <stdint.h>
#include <boost/dynamic_bitset.hpp>
#include "lua/luastate.h"
-#include "evoral/types.hpp"
+#include "evoral/Range.hpp"
#include "midi++/types.h"
#include "midi++/mmc.h"
std::string _message;
};
+/** Ardour Session */
class LIBARDOUR_API Session : public PBD::StatefulDestructible, public PBD::ScopedConnectionList, public SessionEventManager
{
public:
static int get_info_from_path (const std::string& xmlpath, float& sample_rate, SampleFormat& data_format);
static std::string get_snapshot_from_instant (const std::string& session_dir);
+ /** a monotonic counter used for naming user-visible things uniquely
+ * (curently the sidechain port).
+ * Use sparingly to keep the numbers low, prefer PBD::ID for all
+ * internal, not user-visible IDs */
+ static unsigned int next_name_id ();
+
std::string path() const { return _path; }
std::string name() const { return _name; }
std::string snap_name() const { return _current_snapshot_name; }
std::string new_audio_source_path_for_embedded (const std::string& existing_path);
std::string new_audio_source_path (const std::string&, uint32_t nchans, uint32_t chan, bool destructive, bool take_required);
std::string new_midi_source_path (const std::string&);
+ /** create a new track or bus from a template (XML path)
+ * @param how_many how many tracks or busses to create
+ * @param template_path path to xml template file
+ * @param name name (prefix) of the route to create
+ * @param pd Playlist disposition
+ * @return list of newly created routes
+ */
RouteList new_route_from_template (uint32_t how_many, const std::string& template_path, const std::string& name, PlaylistDisposition pd = NewPlaylist);
RouteList new_route_from_template (uint32_t how_many, XMLNode&, const std::string& name, PlaylistDisposition pd = NewPlaylist);
std::vector<std::string> get_paths_for_new_sources (bool allow_replacing, const std::string& import_file_path, uint32_t channels);
void process (pframes_t nframes);
BufferSet& get_silent_buffers (ChanCount count = ChanCount::ZERO);
- BufferSet& get_scratch_buffers (ChanCount count = ChanCount::ZERO, bool silence = true );
+ BufferSet& get_noinplace_buffers (ChanCount count = ChanCount::ZERO);
+ BufferSet& get_scratch_buffers (ChanCount count = ChanCount::ZERO, bool silence = true);
BufferSet& get_route_buffers (ChanCount count = ChanCount::ZERO, bool silence = true);
BufferSet& get_mix_buffers (ChanCount count = ChanCount::ZERO);
};
int save_as (SaveAs&);
+ /** save session
+ * @param snapshot_name name of the session (use an empty string for the current name)
+ * @param pending save a 'recovery', not full state (default: false)
+ * @param switch_to_snapshot switch to given snapshot after saving (default: false)
+ * @param template_only save a session template (default: false)
+ * @return zero on success
+ */
int save_state (std::string snapshot_name, bool pending = false, bool switch_to_snapshot = false, bool template_only = false);
int restore_state (std::string snapshot_name);
int save_template (std::string template_name, bool replace_existing = false);
*/
static PBD::Signal2<int, framecnt_t, framecnt_t> AskAboutSampleRateMismatch;
+ /** non interactive message */
+ static PBD::Signal2<void, framecnt_t, framecnt_t> NotifyAboutSampleRateMismatch;
+
/** handlers should return !0 for use pending state, 0 for ignore it.
*/
static PBD::Signal0<int> AskAboutPendingState;
std::string next_undo() const { return _history.next_undo(); }
std::string next_redo() const { return _history.next_redo(); }
+ /** begin collecting undo information
+ *
+ * This call must always be followed by either
+ * begin_reversible_command() or commit_reversible_command()
+ *
+ * @param cmd_name human readable name for the undo operation
+ */
void begin_reversible_command (const std::string& cmd_name);
void begin_reversible_command (GQuark);
+ /** abort an open undo command
+ * This must only be called after begin_reversible_command ()
+ */
void abort_reversible_command ();
+ /** finalize an undo command and commit pending transactions
+ *
+ * This must only be called after begin_reversible_command ()
+ * @param cmd (additional) command to add
+ */
void commit_reversible_command (Command* cmd = 0);
void add_command (Command *const cmd);
+ /** create an StatefulDiffCommand from the given object and add it to the stack.
+ *
+ * This function must only be called after begin_reversible_command.
+ * Failing to do so may lead to a crash.
+ *
+ * @param sfd the object to diff
+ * @returns the allocated StatefulDiffCommand (already added via add_command)
+ */
+ PBD::StatefulDiffCommand* add_stateful_diff_command (boost::shared_ptr<PBD::StatefulDestructible> sfd);
+
/** @return The list of operations that are currently in progress */
std::list<GQuark> const & current_operations () {
return _current_trans_quarks;
friend class AudioEngine;
void set_block_size (pframes_t nframes);
void set_frame_rate (framecnt_t nframes);
+#ifdef USE_TRACKS_CODE_FEATURES
void reconnect_existing_routes (bool withLock, bool reconnect_master = true, bool reconnect_inputs = true, bool reconnect_outputs = true);
+#endif
protected:
friend class Route;
int create (const std::string& mix_template, BusProfile*);
void destroy ();
+ static guint _name_id_counter;
+ static void init_name_id_counter (guint n);
+ static unsigned int name_id_counter ();
+
enum SubState {
PendingDeclickIn = 0x1, ///< pending de-click fade-in for start
PendingDeclickOut = 0x2, ///< pending de-click fade-out for stop
process_function_type last_process_function;
bool _bounce_processing_active;
bool waiting_for_sync_offset;
- framecnt_t _base_frame_rate;
- framecnt_t _current_frame_rate; //this includes video pullup offset
- framecnt_t _nominal_frame_rate; //ignores audioengine setting, "native" SR
+ framecnt_t _base_frame_rate; // sample-rate of the session at creation time, "native" SR
+ framecnt_t _nominal_frame_rate; // overridden by audioengine setting
+ framecnt_t _current_frame_rate; // this includes video pullup offset
int transport_sub_state;
mutable gint _record_status;
framepos_t _transport_frame;
pthread_cond_t _rt_emit_cond;
bool _rt_emit_pending;
+ /* Auto Connect Thread */
+ static void *auto_connect_thread (void *);
+ void auto_connect_thread_run ();
+ void auto_connect_thread_start ();
+ void auto_connect_thread_terminate ();
+
+ pthread_t _auto_connect_thread;
+ bool _ac_thread_active;
+ pthread_mutex_t _auto_connect_mutex;
+ pthread_cond_t _auto_connect_cond;
+
+ struct AutoConnectRequest {
+ public:
+ AutoConnectRequest (boost::shared_ptr <Route> r, bool ci,
+ const ChanCount& is,
+ const ChanCount& os,
+ const ChanCount& io,
+ const ChanCount& oo)
+ : route (boost::weak_ptr<Route> (r))
+ , connect_inputs (ci)
+ , input_start (is)
+ , output_start (os)
+ , input_offset (io)
+ , output_offset (oo)
+ {}
+
+ boost::weak_ptr <Route> route;
+ bool connect_inputs;
+ ChanCount input_start;
+ ChanCount output_start;
+ ChanCount input_offset;
+ ChanCount output_offset;
+ };
+
+ typedef std::queue<AutoConnectRequest> AutoConnectQueue;
+ Glib::Threads::Mutex _auto_connect_queue_lock;
+ AutoConnectQueue _auto_connect_queue;
+
+ void auto_connect (const AutoConnectRequest&);
/* SessionEventManager interface */
bool find_route_name (std::string const &, uint32_t& id, std::string& name, 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 auto_connect_route (boost::shared_ptr<Route>, bool, const ChanCount&, const ChanCount&, const ChanCount& io = ChanCount(), const ChanCount& oo = ChanCount());
void midi_output_change_handler (IOChange change, void* /*src*/, boost::weak_ptr<Route> midi_track);
/* track numbering */