X-Git-Url: https://main.carlh.net/gitweb/?a=blobdiff_plain;f=libs%2Fardour%2Fardour%2Fsession.h;h=9b25f29c8f3b2d504f04bc78ae9516d6d5c7f125;hb=e1581242ca8554660ea68290688e573a9acfca06;hp=9dd19eb2a11b5159b1f0356e288213421bb438d1;hpb=c40437430acf4b65d8acb8b084eae8cd2f6f5402;p=ardour.git diff --git a/libs/ardour/ardour/session.h b/libs/ardour/ardour/session.h index 9dd19eb2a1..9b25f29c8f 100644 --- a/libs/ardour/ardour/session.h +++ b/libs/ardour/ardour/session.h @@ -34,7 +34,7 @@ #include #include -#include +#include #include "pbd/error.h" #include "pbd/event_loop.h" @@ -64,6 +64,10 @@ #include #endif +#ifdef HAVE_LTC +#include +#endif + class XMLTree; class XMLNode; struct _AEffect; @@ -111,7 +115,6 @@ class MidiControlUI; class MidiRegion; class MidiSource; class MidiTrack; -class NamedSelection; class Playlist; class PluginInsert; class PluginInfo; @@ -235,7 +238,8 @@ class Session : public PBD::StatefulDestructible, public PBD::ScopedConnectionLi bool operator() (boost::shared_ptr, boost::shared_ptr b); }; - void sync_order_keys (std::string const &); + void notify_remote_id_change (); + void sync_order_keys (RouteSortOrderKey); template void foreach_route (T *obj, void (T::*func)(Route&)); template void foreach_route (T *obj, void (T::*func)(boost::shared_ptr)); @@ -247,7 +251,7 @@ class Session : public PBD::StatefulDestructible, public PBD::ScopedConnectionLi boost::shared_ptr route_by_id (PBD::ID); boost::shared_ptr route_by_remote_id (uint32_t id); boost::shared_ptr track_by_diskstream_id (PBD::ID); - void routes_using_input_from (const std::string& str, RouteList& rl); + 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; @@ -329,8 +333,8 @@ class Session : public PBD::StatefulDestructible, public PBD::ScopedConnectionLi void goto_start (); void use_rf_shuttle_speed (); void allow_auto_play (bool yn); - void request_transport_speed (double speed); - void request_transport_speed_nonzero (double); + void request_transport_speed (double speed, bool as_default = false); + void request_transport_speed_nonzero (double, bool as_default = false); void request_overwrite_buffer (Track *); void adjust_playback_buffering(); void adjust_capture_buffering(); @@ -357,7 +361,7 @@ class Session : public PBD::StatefulDestructible, public PBD::ScopedConnectionLi return mtc_timecode_bits; /* encoding of SMTPE type for MTC */ } - float timecode_frames_per_second() const; + double timecode_frames_per_second() const; bool timecode_drop_frames() const; /* Locations */ @@ -454,6 +458,7 @@ class Session : public PBD::StatefulDestructible, public PBD::ScopedConnectionLi ); std::list > new_midi_track ( + const ChanCount& input, const ChanCount& output, boost::shared_ptr instrument = boost::shared_ptr(), TrackMode mode = Normal, RouteGroup* route_group = 0, uint32_t how_many = 1, std::string name_template = "" @@ -463,8 +468,6 @@ class Session : public PBD::StatefulDestructible, public PBD::ScopedConnectionLi void resort_routes (); void resort_routes_using (boost::shared_ptr); - void set_remote_control_ids(); - AudioEngine & engine() { return _engine; } AudioEngine const & engine () const { return _engine; } @@ -504,9 +507,8 @@ class Session : public PBD::StatefulDestructible, public PBD::ScopedConnectionLi static PBD::Signal1 StartTimeChanged; static PBD::Signal1 EndTimeChanged; - std::vector get_available_sync_options() const; void request_sync_source (Slave*); - bool synced_to_jack() const { return config.get_external_sync() && config.get_sync_source() == JACK; } + bool synced_to_jack() const { return config.get_external_sync() && Config->get_sync_source() == JACK; } double transport_speed() const { return _transport_speed; } bool transport_stopped() const { return _transport_speed == 0.0f; } @@ -579,16 +581,6 @@ class Session : public PBD::StatefulDestructible, public PBD::ScopedConnectionLi void add_playlist (boost::shared_ptr, bool unused = false); - /* named selections */ - - boost::shared_ptr named_selection_by_name (std::string name); - void add_named_selection (boost::shared_ptr); - void remove_named_selection (boost::shared_ptr); - - template void foreach_named_selection (T& obj, void (T::*func)(boost::shared_ptr)); - PBD::Signal0 NamedSelectionAdded; - PBD::Signal0 NamedSelectionRemoved; - /* Curves and AutomationLists (TODO when they go away) */ void add_automation_list(AutomationList*); @@ -624,8 +616,8 @@ class Session : public PBD::StatefulDestructible, public PBD::ScopedConnectionLi void set_listen (boost::shared_ptr, bool, SessionEvent::RTeventCallback after = rt_cleanup, bool group_override = false); void set_record_enabled (boost::shared_ptr, bool, SessionEvent::RTeventCallback after = rt_cleanup, bool group_override = false); void set_solo_isolated (boost::shared_ptr, bool, SessionEvent::RTeventCallback after = rt_cleanup, bool group_override = false); - void set_exclusive_input_active (boost::shared_ptr rt, bool others_on); void set_monitoring (boost::shared_ptr, MonitorChoice, SessionEvent::RTeventCallback after = rt_cleanup, bool group_override = false); + void set_exclusive_input_active (boost::shared_ptr rt, bool onoff, bool flip_others=false); PBD::Signal1 SoloActive; PBD::Signal0 SoloChanged; @@ -669,7 +661,7 @@ class Session : public PBD::StatefulDestructible, public PBD::ScopedConnectionLi /* s/w "RAID" management */ - framecnt_t available_capture_duration(); + boost::optional available_capture_duration(); /* I/O bundles */ @@ -716,6 +708,8 @@ class Session : public PBD::StatefulDestructible, public PBD::ScopedConnectionLi return _current_trans_quarks; } + bool operation_in_progress (GQuark) const; + void add_commands (std::vector const & cmds); std::map registry; @@ -810,14 +804,13 @@ class Session : public PBD::StatefulDestructible, public PBD::ScopedConnectionLi }; SlaveState slave_state() const { return _slave_state; } + Slave* slave() const { return _slave; } boost::shared_ptr playlists; void send_mmc_locate (framepos_t); int send_full_time_code (framepos_t); - PBD::Signal0 RouteOrderKeyChanged; - bool step_editing() const { return (_step_editors > 0); } void request_suspend_timecode_transmission (); @@ -854,6 +847,12 @@ class Session : public PBD::StatefulDestructible, public PBD::ScopedConnectionLi /** Emitted when the session wants Ardour to quit */ static PBD::Signal0 Quit; + boost::shared_ptr ltc_input_port() const; + boost::shared_ptr ltc_output_port() const; + + boost::shared_ptr ltc_input_io() { return _ltc_input; } + boost::shared_ptr ltc_output_io() { return _ltc_output; } + protected: friend class AudioEngine; void set_block_size (pframes_t nframes); @@ -869,10 +868,12 @@ class Session : public PBD::StatefulDestructible, public PBD::ScopedConnectionLi void destroy (); enum SubState { - PendingDeclickIn = 0x1, - PendingDeclickOut = 0x2, - StopPendingCapture = 0x4, - PendingLocate = 0x20, + PendingDeclickIn = 0x1, ///< pending de-click fade-in for start + PendingDeclickOut = 0x2, ///< pending de-click fade-out for stop + StopPendingCapture = 0x4, + PendingLoopDeclickIn = 0x8, ///< pending de-click fade-in at the start of a loop + PendingLoopDeclickOut = 0x10, ///< pending de-click fade-out at the end of a loop + PendingLocate = 0x20, }; /* stuff used in process() should be close together to @@ -900,6 +901,7 @@ class Session : public PBD::StatefulDestructible, public PBD::ScopedConnectionLi // varispeed playback double _transport_speed; + double _default_transport_speed; double _last_transport_speed; double _target_transport_speed; CubicInterpolation interpolation; @@ -972,6 +974,7 @@ class Session : public PBD::StatefulDestructible, public PBD::ScopedConnectionLi framepos_t post_export_position; bool _exporting; + bool _export_started; bool _export_rolling; boost::shared_ptr export_handler; @@ -988,12 +991,25 @@ class Session : public PBD::StatefulDestructible, public PBD::ScopedConnectionLi int process_routes (pframes_t, bool& need_butler); int silent_process_routes (pframes_t, bool& need_butler); + /** @return 1 if there is a pending declick fade-in, + -1 if there is a pending declick fade-out, + 0 if there is no pending declick. + */ int get_transport_declick_required () { if (transport_sub_state & PendingDeclickIn) { transport_sub_state &= ~PendingDeclickIn; return 1; } else if (transport_sub_state & PendingDeclickOut) { + /* XXX: not entirely sure why we don't clear this */ + return -1; + } else if (transport_sub_state & PendingLoopDeclickOut) { + /* Return the declick out first ... */ + transport_sub_state &= ~PendingLoopDeclickOut; return -1; + } else if (transport_sub_state & PendingLoopDeclickIn) { + /* ... then the declick in on the next call */ + transport_sub_state &= ~PendingLoopDeclickIn; + return 1; } else { return 0; } @@ -1035,6 +1051,7 @@ class Session : public PBD::StatefulDestructible, public PBD::ScopedConnectionLi int load_state (std::string snapshot_name); framepos_t _last_roll_location; + /** the session frame time at which we last rolled, located, or changed transport direction */ framepos_t _last_roll_or_reversal_location; framepos_t _last_record_location; @@ -1058,7 +1075,7 @@ class Session : public PBD::StatefulDestructible, public PBD::ScopedConnectionLi PostTransportClearSubstate); gint _post_transport_work; /* accessed only atomic ops */ - PostTransportWork post_transport_work() const { return (PostTransportWork) g_atomic_int_get (&_post_transport_work); } + PostTransportWork post_transport_work() const { return (PostTransportWork) g_atomic_int_get (const_cast(&_post_transport_work)); } void set_post_transport_work (PostTransportWork ptw) { g_atomic_int_set (&_post_transport_work, (gint) ptw); } void add_post_transport_work (PostTransportWork ptw); @@ -1083,6 +1100,7 @@ class Session : public PBD::StatefulDestructible, public PBD::ScopedConnectionLi PBD::ScopedConnectionList loop_connections; void auto_loop_changed (Location *); + void auto_loop_declick_range (Location *, framepos_t &, framepos_t &); void first_stage_init (std::string path, std::string snapshot_name); int second_stage_init (); @@ -1170,6 +1188,35 @@ class Session : public PBD::StatefulDestructible, public PBD::ScopedConnectionLi int send_midi_time_code_for_cycle (framepos_t, framepos_t, pframes_t nframes); +#ifdef HAVE_LTC + LTCEncoder* ltc_encoder; + ltcsnd_sample_t* ltc_enc_buf; + + Timecode::TimecodeFormat ltc_enc_tcformat; + int32_t ltc_buf_off; + int32_t ltc_buf_len; + + double ltc_speed; + int32_t ltc_enc_byte; + framepos_t ltc_enc_pos; + double ltc_enc_cnt; + framepos_t ltc_enc_off; + bool restarting; + + framepos_t ltc_timecode_offset; + bool ltc_timecode_negative_offset; + + jack_latency_range_t ltc_out_latency; + + void ltc_tx_initialize(); + void ltc_tx_cleanup(); + void ltc_tx_reset(); + void ltc_tx_resync_latency(); + void ltc_tx_recalculate_position(); + void ltc_tx_parse_offset(); + void ltc_tx_send_time_code_for_cycle (framepos_t, framepos_t, double, double, pframes_t nframes); +#endif + void reset_record_status (); int no_roll (pframes_t nframes); @@ -1191,7 +1238,7 @@ class Session : public PBD::StatefulDestructible, public PBD::ScopedConnectionLi void start_locate (framepos_t, bool with_roll, bool with_flush, bool with_loop=false, bool force=false); void force_locate (framepos_t frame, bool with_roll = false); void set_track_speed (Track *, double speed); - void set_transport_speed (double speed, bool abort = false, bool clear_state = false); + void set_transport_speed (double speed, bool abort = false, bool clear_state = false, bool as_default = false); void stop_transport (bool abort = false, bool clear_state = false); void start_transport (); void realtime_stop (bool abort, bool clear_state); @@ -1251,7 +1298,7 @@ class Session : public PBD::StatefulDestructible, public PBD::ScopedConnectionLi /* REGION MANAGEMENT */ - mutable Glib::Mutex region_lock; + mutable Glib::Threads::Mutex region_lock; int load_regions (const XMLNode& node); int load_compounds (const XMLNode& node); @@ -1262,7 +1309,7 @@ class Session : public PBD::StatefulDestructible, public PBD::ScopedConnectionLi /* SOURCES */ - mutable Glib::Mutex source_lock; + mutable Glib::Threads::Mutex source_lock; public: typedef std::map > SourceMap; @@ -1287,17 +1334,6 @@ class Session : public PBD::StatefulDestructible, public PBD::ScopedConnectionLi void playlist_ranges_moved (std::list > const &); void playlist_regions_extended (std::list > const &); - /* NAMED SELECTIONS */ - - mutable Glib::Mutex named_selection_lock; - typedef std::set > NamedSelectionList; - NamedSelectionList named_selections; - - int load_named_selections (const XMLNode&); - - NamedSelection *named_selection_factory (std::string name); - NamedSelection *XMLNamedSelectionFactory (const XMLNode&); - /* CURVES and AUTOMATION LISTS */ std::map automation_lists; @@ -1329,16 +1365,21 @@ class Session : public PBD::StatefulDestructible, public PBD::ScopedConnectionLi /* S/W RAID */ struct space_and_path { - uint32_t blocks; /* 4kB blocks */ + uint32_t blocks; ///< 4kB blocks + bool blocks_unknown; ///< true if blocks is unknown std::string path; - space_and_path() { - blocks = 0; - } + space_and_path () + : blocks (0) + , blocks_unknown (true) + {} }; struct space_and_path_ascending_cmp { bool operator() (space_and_path a, space_and_path b) { + if (a.blocks_unknown != b.blocks_unknown) { + return !a.blocks_unknown; + } return a.blocks > b.blocks; } }; @@ -1348,7 +1389,12 @@ class Session : public PBD::StatefulDestructible, public PBD::ScopedConnectionLi std::vector session_dirs; std::vector::iterator last_rr_session_dir; uint32_t _total_free_4k_blocks; - Glib::Mutex space_lock; + /** If this is true, _total_free_4k_blocks is not definite, + as one or more of the session directories' filesystems + could not report free space. + */ + bool _total_free_4k_blocks_uncertain; + Glib::Threads::Mutex space_lock; bool no_questions_about_missing_files; @@ -1391,7 +1437,7 @@ class Session : public PBD::StatefulDestructible, public PBD::ScopedConnectionLi Sample* click_emphasis_data; framecnt_t click_length; framecnt_t click_emphasis_length; - mutable Glib::RWLock click_lock; + mutable Glib::Threads::RWLock click_lock; static const Sample default_click[]; static const framecnt_t default_click_length; @@ -1444,7 +1490,7 @@ class Session : public PBD::StatefulDestructible, public PBD::ScopedConnectionLi int find_all_sources_across_snapshots (std::set& result, bool exclude_this_snapshot); typedef std::set > Controllables; - Glib::Mutex controllables_lock; + Glib::Threads::Mutex controllables_lock; Controllables controllables; boost::shared_ptr _solo_cut_control; @@ -1458,7 +1504,6 @@ class Session : public PBD::StatefulDestructible, public PBD::ScopedConnectionLi XMLNode& get_control_protocol_state (); void set_history_depth (uint32_t depth); - void sync_order_keys (); static bool _disable_all_loaded_plugins; @@ -1497,8 +1542,6 @@ class Session : public PBD::StatefulDestructible, public PBD::ScopedConnectionLi void setup_midi_machine_control (); - void route_order_key_changed (); - void step_edit_status_change (bool); uint32_t _step_editors; @@ -1525,6 +1568,12 @@ class Session : public PBD::StatefulDestructible, public PBD::ScopedConnectionLi bool ignore_route_processor_changes; MidiClockTicker* midi_clock; + + boost::shared_ptr _ltc_input; + boost::shared_ptr _ltc_output; + + void reconnect_ltc_input (); + void reconnect_ltc_output (); }; } // namespace ARDOUR