summaryrefslogtreecommitdiff
path: root/libs
diff options
context:
space:
mode:
authorPaul Davis <paul@linuxaudiosystems.com>2015-02-05 16:21:01 -0500
committerPaul Davis <paul@linuxaudiosystems.com>2015-02-05 16:35:56 -0500
commite72a4ec8508fd61b534d1cedb63b70d13ed2677f (patch)
tree433ba6aafda1666a4f48a1bb5b5e0964efa0e7bb /libs
parentec9c6a58e21e282df8b8b37ae16dd572994e1f3c (diff)
modify behaviour of session when updating skips to use new SessionEvent API
Conflicts: libs/ardour/ardour/session.h libs/ardour/session.cc
Diffstat (limited to 'libs')
-rw-r--r--libs/ardour/ardour/session.h186
-rw-r--r--libs/ardour/session.cc64
2 files changed, 132 insertions, 118 deletions
diff --git a/libs/ardour/ardour/session.h b/libs/ardour/ardour/session.h
index 552c8e203a..4008ddbef4 100644
--- a/libs/ardour/ardour/session.h
+++ b/libs/ardour/ardour/session.h
@@ -1,19 +1,19 @@
/*
- Copyright (C) 2000 Paul Davis
+ Copyright (C) 2000 Paul Davis
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
@@ -70,18 +70,18 @@ struct _AEffect;
typedef struct _AEffect AEffect;
namespace MIDI {
- class Port;
- class MachineControl;
- class Parser;
+class Port;
+class MachineControl;
+class Parser;
}
namespace PBD {
- class Controllable;
- class ControllableDescriptor;
+class Controllable;
+class ControllableDescriptor;
}
namespace Evoral {
- class Curve;
+class Curve;
}
namespace ARDOUR {
@@ -160,7 +160,7 @@ class LIBARDOUR_API Session : public PBD::StatefulDestructible, public PBD::Scop
virtual ~Session ();
- static int get_info_from_path (const std::string& xmlpath, float& sample_rate, SampleFormat& data_format);
+ static int get_info_from_path (const std::string& xmlpath, float& sample_rate, SampleFormat& data_format);
std::string path() const { return _path; }
std::string name() const { return _name; }
@@ -198,7 +198,7 @@ class LIBARDOUR_API Session : public PBD::StatefulDestructible, public PBD::Scop
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&);
- RouteList new_route_from_template (uint32_t how_many, const std::string& template_path, const std::string& name);
+ RouteList new_route_from_template (uint32_t how_many, const std::string& template_path, const std::string& name);
std::vector<std::string> get_paths_for_new_sources (bool allow_replacing, const std::string& import_file_path, uint32_t channels);
int bring_all_sources_into_session (boost::function<void(uint32_t,uint32_t,std::string)> callback);
@@ -244,8 +244,8 @@ class LIBARDOUR_API Session : public PBD::StatefulDestructible, public PBD::Scop
};
void set_order_hint (uint32_t order_hint) {_order_hint = order_hint;};
- void notify_remote_id_change ();
- void sync_order_keys ();
+ void notify_remote_id_change ();
+ void sync_order_keys ();
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>));
@@ -257,7 +257,7 @@ class LIBARDOUR_API Session : public PBD::StatefulDestructible, public PBD::Scop
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);
+ 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;
@@ -301,7 +301,7 @@ class LIBARDOUR_API Session : public PBD::StatefulDestructible, public PBD::Scop
* - 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 */
@@ -343,8 +343,8 @@ class LIBARDOUR_API Session : public PBD::StatefulDestructible, public PBD::Scop
void goto_start ();
void use_rf_shuttle_speed ();
void allow_auto_play (bool yn);
- void request_transport_speed (double speed, bool as_default = false);
- void request_transport_speed_nonzero (double, bool as_default = false);
+ 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();
@@ -448,20 +448,20 @@ class LIBARDOUR_API Session : public PBD::StatefulDestructible, public PBD::Scop
StateOfTheState state_of_the_state() const { return _state_of_the_state; }
class StateProtector {
- public:
- StateProtector (Session* s) : _session (s) {
- g_atomic_int_inc (&s->_suspend_save);
- }
- ~StateProtector () {
- if (g_atomic_int_dec_and_test (&_session->_suspend_save)) {
- while (_session->_save_queued) {
- _session->_save_queued = false;
- _session->save_state ("");
- }
+ public:
+ StateProtector (Session* s) : _session (s) {
+ g_atomic_int_inc (&s->_suspend_save);
+ }
+ ~StateProtector () {
+ if (g_atomic_int_dec_and_test (&_session->_suspend_save)) {
+ while (_session->_save_queued) {
+ _session->_save_queued = false;
+ _session->save_state ("");
}
}
- private:
- Session * _session;
+ }
+ private:
+ Session * _session;
};
void add_route_group (RouteGroup *);
@@ -544,7 +544,7 @@ class LIBARDOUR_API Session : public PBD::StatefulDestructible, public PBD::Scop
void timecode_time_subframes (framepos_t when, Timecode::Time&);
void timecode_duration (framecnt_t, Timecode::Time&) const;
- void timecode_duration_string (char *, size_t len, framecnt_t) const;
+ void timecode_duration_string (char *, size_t len, framecnt_t) const;
framecnt_t convert_to_frames (AnyTime const & position);
framecnt_t any_duration_to_frames (framepos_t position, AnyTime const & duration);
@@ -598,10 +598,10 @@ class LIBARDOUR_API Session : public PBD::StatefulDestructible, public PBD::Scop
int remove_last_capture ();
- /** handlers should return 0 for "everything OK", and any other value for
+ /** handlers should return 0 for "everything OK", and any other value for
* "cannot setup audioengine".
*/
- static PBD::Signal1<int,uint32_t> AudioEngineSetupRequired;
+ static PBD::Signal1<int,uint32_t> AudioEngineSetupRequired;
/** handlers should return -1 for "stop cleanup",
0 for "yes, delete this playlist",
@@ -615,7 +615,7 @@ class LIBARDOUR_API Session : public PBD::StatefulDestructible, public PBD::Scop
static PBD::Signal2<int, framecnt_t, framecnt_t> AskAboutSampleRateMismatch;
/** handlers should return !0 for use pending state, 0 for ignore it.
- */
+ */
static PBD::Signal0<int> AskAboutPendingState;
boost::shared_ptr<AudioFileSource> create_audio_source_for_session (
@@ -647,9 +647,9 @@ class LIBARDOUR_API Session : public PBD::StatefulDestructible, public PBD::Scop
/* flattening stuff */
boost::shared_ptr<Region> write_one_track (Track&, framepos_t start, framepos_t end,
- bool overwrite, std::vector<boost::shared_ptr<Source> >&, InterThreadInfo& wot,
- boost::shared_ptr<Processor> endpoint,
- bool include_endpoint, bool for_export, bool for_freeze);
+ bool overwrite, std::vector<boost::shared_ptr<Source> >&, InterThreadInfo& wot,
+ boost::shared_ptr<Processor> endpoint,
+ bool include_endpoint, bool for_export, bool for_freeze);
int freeze_all (InterThreadInfo&);
/* session-wide solo/mute/rec-enable */
@@ -668,7 +668,7 @@ class LIBARDOUR_API Session : public PBD::StatefulDestructible, public PBD::Scop
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_monitoring (boost::shared_ptr<RouteList>, MonitorChoice, SessionEvent::RTeventCallback after = rt_cleanup, bool group_override = false);
- void set_exclusive_input_active (boost::shared_ptr<RouteList> rt, bool onoff, bool flip_others=false);
+ void set_exclusive_input_active (boost::shared_ptr<RouteList> rt, bool onoff, bool flip_others=false);
PBD::Signal1<void,bool> SoloActive;
PBD::Signal0<void> SoloChanged;
@@ -867,13 +867,13 @@ class LIBARDOUR_API Session : public PBD::StatefulDestructible, public PBD::Scop
};
SlaveState slave_state() const { return _slave_state; }
- Slave* slave() const { return _slave; }
+ Slave* slave() const { return _slave; }
boost::shared_ptr<SessionPlaylists> playlists;
void send_mmc_locate (framepos_t);
- void queue_full_time_code () { _send_timecode_update = true; }
- void queue_song_position_pointer () { /* currently does nothing */ }
+ void queue_full_time_code () { _send_timecode_update = true; }
+ void queue_song_position_pointer () { /* currently does nothing */ }
bool step_editing() const { return (_step_editors > 0); }
@@ -912,15 +912,15 @@ class LIBARDOUR_API Session : public PBD::StatefulDestructible, public PBD::Scop
/** Emitted when the session wants Ardour to quit */
static PBD::Signal0<void> Quit;
- /** Emitted when Ardour is asked to load a session in an older session
+ /** Emitted when Ardour is asked to load a session in an older session
* format, and makes a backup copy.
*/
- static PBD::Signal2<void,std::string,std::string> VersionMismatch;
+ static PBD::Signal2<void,std::string,std::string> VersionMismatch;
SceneChanger* scene_changer() const { return _scene_changer; }
- boost::shared_ptr<Port> ltc_input_port() const;
- boost::shared_ptr<Port> ltc_output_port() const;
+ boost::shared_ptr<Port> ltc_input_port() const;
+ boost::shared_ptr<Port> ltc_output_port() const;
boost::shared_ptr<IO> ltc_input_io() { return _ltc_input; }
boost::shared_ptr<IO> ltc_output_io() { return _ltc_output; }
@@ -947,7 +947,7 @@ class LIBARDOUR_API Session : public PBD::StatefulDestructible, public PBD::Scop
friend class AudioEngine;
void set_block_size (pframes_t nframes);
void set_frame_rate (framecnt_t nframes);
- void reconnect_existing_routes (bool withLock, bool reconnect_master = true, bool reconnect_inputs = true, bool reconnect_outputs = true);
+ void reconnect_existing_routes (bool withLock, bool reconnect_master = true, bool reconnect_inputs = true, bool reconnect_outputs = true);
protected:
friend class Route;
@@ -1084,8 +1084,8 @@ class LIBARDOUR_API Session : public PBD::StatefulDestructible, public PBD::Scop
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.
+ -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) {
@@ -1160,17 +1160,17 @@ class LIBARDOUR_API Session : public PBD::StatefulDestructible, public PBD::Scop
static const PostTransportWork ProcessCannotProceedMask =
PostTransportWork (
- PostTransportInputChange|
- PostTransportSpeed|
- PostTransportReverse|
- PostTransportCurveRealloc|
- PostTransportAudition|
- PostTransportLocate|
- PostTransportStop|
- PostTransportClearSubstate);
+ PostTransportInputChange|
+ PostTransportSpeed|
+ PostTransportReverse|
+ PostTransportCurveRealloc|
+ PostTransportAudition|
+ PostTransportLocate|
+ PostTransportStop|
+ PostTransportClearSubstate);
gint _post_transport_work; /* accessed only atomic ops */
- PostTransportWork post_transport_work() const { return (PostTransportWork) g_atomic_int_get (const_cast<gint*>(&_post_transport_work)); }
+ PostTransportWork post_transport_work() const { return (PostTransportWork) g_atomic_int_get (const_cast<gint*>(&_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);
@@ -1184,15 +1184,21 @@ class LIBARDOUR_API Session : public PBD::StatefulDestructible, public PBD::Scop
void reset_rf_scale (framecnt_t frames_moved);
Locations* _locations;
- void location_added (Location*);
- void location_removed (Location*);
- void locations_changed ();
- void _locations_changed (const Locations::LocationList&);
-
- void update_skips (Location*, bool consolidate);
- Locations::LocationList consolidate_skips (Location*);
- void sync_locations_to_skips (const Locations::LocationList&);
- PBD::ScopedConnectionList skip_connections;
+ void location_added (Location*);
+ void location_removed (Location*);
+ void locations_changed ();
+ void _locations_changed (const Locations::LocationList&);
+
+ void update_skips (Location*, bool consolidate);
+ void update_marks (Location* loc);
+ void update_loop (Location* loc);
+ void consolidate_skips (Location*);
+ void sync_locations_to_skips ();
+ void _sync_locations_to_skips ();
+
+ PBD::ScopedConnectionList loop_update_connections;
+ PBD::ScopedConnectionList mark_update_connections;
+ PBD::ScopedConnectionList skip_update_connections;
PBD::ScopedConnectionList punch_connections;
void auto_punch_start_changed (Location *);
@@ -1203,10 +1209,10 @@ class LIBARDOUR_API Session : public PBD::StatefulDestructible, public PBD::Scop
void auto_loop_changed (Location *);
void auto_loop_declick_range (Location *, framepos_t &, framepos_t &);
- int ensure_engine (uint32_t desired_sample_rate);
+ int ensure_engine (uint32_t desired_sample_rate);
void pre_engine_init (std::string path);
int post_engine_init ();
- int immediately_post_engine ();
+ int immediately_post_engine ();
void remove_empty_sounds ();
void setup_midi_control ();
@@ -1341,7 +1347,7 @@ class LIBARDOUR_API Session : public PBD::StatefulDestructible, public PBD::Scop
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, framepos_t destination_frame, bool abort = false, bool clear_state = false, bool as_default = false);
+ void set_transport_speed (double speed, framepos_t destination_frame, 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);
@@ -1355,12 +1361,12 @@ class LIBARDOUR_API Session : public PBD::StatefulDestructible, public PBD::Scop
void engine_halted ();
void xrun_recovery ();
- /* These are synchronous and so can only be called from within the process
- * cycle
- */
+ /* These are synchronous and so can only be called from within the process
+ * cycle
+ */
- int send_full_time_code (framepos_t, pframes_t nframes);
- void send_song_position_pointer (framepos_t);
+ int send_full_time_code (framepos_t, pframes_t nframes);
+ void send_song_position_pointer (framepos_t);
TempoMap *_tempo_map;
void tempo_map_changed (const PBD::PropertyChange&);
@@ -1379,8 +1385,8 @@ class LIBARDOUR_API Session : public PBD::StatefulDestructible, public PBD::Scop
SerializedRCUManager<RouteList> routes;
void add_routes (RouteList&, bool input_auto_connect, bool output_auto_connect, bool save);
- void add_routes_inner (RouteList&, bool input_auto_connect, bool output_auto_connect);
- bool _adding_routes_in_progress;
+ void add_routes_inner (RouteList&, bool input_auto_connect, bool output_auto_connect);
+ bool _adding_routes_in_progress;
uint32_t destructive_index;
boost::shared_ptr<Route> XMLRouteFactory (const XMLNode&, int);
@@ -1532,7 +1538,7 @@ class LIBARDOUR_API Session : public PBD::StatefulDestructible, public PBD::Scop
*/
std::list<GQuark> _current_trans_quarks;
- int backend_sync_callback (TransportState, framepos_t);
+ int backend_sync_callback (TransportState, framepos_t);
void process_rtop (SessionEvent*);
@@ -1623,7 +1629,7 @@ class LIBARDOUR_API Session : public PBD::StatefulDestructible, public PBD::Scop
/* realtime "apply to set of routes" operations */
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)) {
+ 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;
@@ -1676,11 +1682,11 @@ class LIBARDOUR_API Session : public PBD::StatefulDestructible, public PBD::Scop
MidiClockTicker* midi_clock;
- boost::shared_ptr<IO> _ltc_input;
- boost::shared_ptr<IO> _ltc_output;
+ boost::shared_ptr<IO> _ltc_input;
+ boost::shared_ptr<IO> _ltc_output;
- void reconnect_ltc_input ();
- void reconnect_ltc_output ();
+ void reconnect_ltc_input ();
+ void reconnect_ltc_output ();
/* Scene Changing */
SceneChanger* _scene_changer;
diff --git a/libs/ardour/session.cc b/libs/ardour/session.cc
index 59f6425266..182d29ca0b 100644
--- a/libs/ardour/session.cc
+++ b/libs/ardour/session.cc
@@ -1310,32 +1310,35 @@ Session::set_auto_loop_location (Location* location)
}
void
-Session::update_skips (Location* loc, bool consolidate)
+Session::update_loop (Location*)
{
- Locations::LocationList skips;
+ set_dirty ();
+}
- if (consolidate) {
+void
+Session::update_marks (Location*)
+{
+ set_dirty ();
+}
- skips = consolidate_skips (loc);
+void
+Session::update_skips (Location* loc, bool consolidate)
+{
+ Locations::LocationList skips;
- } else {
- Locations::LocationList all_locations = _locations->list ();
-
- for (Locations::LocationList::iterator l = all_locations.begin(); l != all_locations.end(); ++l) {
- if ((*l)->is_skip ()) {
- skips.push_back (*l);
- }
- }
- }
+ if (consolidate) {
+ consolidate_skips (loc);
+ }
- sync_locations_to_skips (skips);
+ sync_locations_to_skips ();
+
+ set_dirty ();
}
-Locations::LocationList
+void
Session::consolidate_skips (Location* loc)
{
Locations::LocationList all_locations = _locations->list ();
- Locations::LocationList skips;
for (Locations::LocationList::iterator l = all_locations.begin(); l != all_locations.end(); ) {
@@ -1366,35 +1369,40 @@ Session::consolidate_skips (Location* loc)
break;
case Evoral::OverlapNone:
- skips.push_back (*l);
++l;
break;
}
}
+}
- /* add the new one, which now covers the maximal appropriate range based on overlaps with existing skips */
-
- skips.push_back (loc);
-
- return skips;
+void
+Session::sync_locations_to_skips ()
+{
+ /* This happens asynchronously (in the audioengine thread). After the clear is done, we will call
+ * Session::_sync_locations_to_skips() from the audioengine thread.
+ */
+ clear_events (SessionEvent::Skip, boost::bind (&Session::_sync_locations_to_skips, this));
}
void
-Session::sync_locations_to_skips (const Locations::LocationList& locations)
+Session::_sync_locations_to_skips ()
{
- clear_events (SessionEvent::Skip);
+ /* called as a callback after existing Skip events have been cleared from a realtime audioengine thread */
- for (Locations::LocationList::const_iterator i = locations.begin(); i != locations.end(); ++i) {
-
+ Locations::LocationList const & locs (_locations->list());
+
+ for (Locations::LocationList::const_iterator i = locs.begin(); i != locs.end(); ++i) {
+
Location* location = *i;
-
- if (location->is_skipping()) {
+
+ if (location->is_skip() && location->is_skipping()) {
SessionEvent* ev = new SessionEvent (SessionEvent::Skip, SessionEvent::Add, location->start(), location->end(), 1.0);
queue_event (ev);
}
}
}
+
void
Session::location_added (Location *location)
{