summaryrefslogtreecommitdiff
path: root/libs/ardour
diff options
context:
space:
mode:
authorCarl Hetherington <carl@carlh.net>2010-05-09 20:48:21 +0000
committerCarl Hetherington <carl@carlh.net>2010-05-09 20:48:21 +0000
commit792e3de1d4cb291a02c5c31dad54028049bafed9 (patch)
treee65183deeb01752110a59a5b834e06deef811dab /libs/ardour
parentacfc44f3889704587ff281c6348523b2811e7c2e (diff)
Create the session range location as and when the session first gets some content. Allows both the beginning and end of the range to expand to contain the actual session contents.
git-svn-id: svn://localhost/ardour2/branches/3.0@7087 d708f5d6-7413-0410-9779-e7cbd77b26cf
Diffstat (limited to 'libs/ardour')
-rw-r--r--libs/ardour/ardour/playlist.h4
-rw-r--r--libs/ardour/ardour/session.h25
-rw-r--r--libs/ardour/ardour/session_configuration_vars.h1
-rw-r--r--libs/ardour/audiofilesource.cc2
-rw-r--r--libs/ardour/auditioner.cc2
-rw-r--r--libs/ardour/location.cc2
-rw-r--r--libs/ardour/playlist.cc50
-rw-r--r--libs/ardour/session.cc133
-rw-r--r--libs/ardour/session_state.cc19
-rw-r--r--libs/ardour/session_transport.cc34
10 files changed, 151 insertions, 121 deletions
diff --git a/libs/ardour/ardour/playlist.h b/libs/ardour/ardour/playlist.h
index c5b79644c6..d13789fa38 100644
--- a/libs/ardour/ardour/playlist.h
+++ b/libs/ardour/ardour/playlist.h
@@ -126,7 +126,7 @@ class Playlist : public SessionObject
bool hidden() const { return _hidden; }
bool empty() const;
uint32_t n_regions() const;
- framecnt_t get_maximum_extent () const;
+ std::pair<framecnt_t, framecnt_t> get_extent () const;
layer_t top_layer() const;
EditMode get_edit_mode() const { return _edit_mode; }
@@ -334,7 +334,7 @@ class Playlist : public SessionObject
void copy_regions (RegionList&) const;
void partition_internal (framepos_t start, framepos_t end, bool cutting, RegionList& thawlist);
- framecnt_t _get_maximum_extent() const;
+ std::pair<framecnt_t, framecnt_t> _get_extent() const;
boost::shared_ptr<Playlist> cut_copy (boost::shared_ptr<Playlist> (Playlist::*pmf)(framepos_t, framecnt_t, bool),
std::list<AudioRange>& ranges, bool result_is_hidden);
diff --git a/libs/ardour/ardour/session.h b/libs/ardour/ardour/session.h
index 4182ce1ea1..0f5a73a280 100644
--- a/libs/ardour/ardour/session.h
+++ b/libs/ardour/ardour/session.h
@@ -270,7 +270,6 @@ class Session : public PBD::StatefulDestructible, public PBD::ScopedConnectionLi
PBD::Signal0<void> TransportStateChange; /* generic */
PBD::Signal1<void,nframes64_t> PositionChanged; /* sent after any non-sequential motion */
- PBD::Signal0<void> DurationChanged;
PBD::Signal1<void,nframes64_t> Xrun;
PBD::Signal0<void> TransportLooped;
@@ -291,10 +290,10 @@ class Session : public PBD::StatefulDestructible, public PBD::ScopedConnectionLi
bool get_play_loop () const { return play_loop; }
nframes_t last_transport_start() const { return _last_roll_location; }
- void goto_end () { request_locate (_session_range_location->end(), false);}
- void goto_start () { request_locate (_session_range_location->start(), false); }
- void set_session_start (nframes_t start) { _session_range_location->set_start(start); }
- void set_session_end (nframes_t end) { _session_range_location->set_end(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);
@@ -307,9 +306,9 @@ class Session : public PBD::StatefulDestructible, public PBD::ScopedConnectionLi
int wipe ();
- nframes_t get_maximum_extent () const;
- nframes_t current_end_frame() const { return _session_range_location->end(); }
- nframes_t current_start_frame() const { return _session_range_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
@@ -805,11 +804,9 @@ class Session : public PBD::StatefulDestructible, public PBD::ScopedConnectionLi
void update_latency_compensation (bool, bool);
private:
- int create (const std::string& mix_template, nframes_t initial_length, BusProfile*);
+ int create (const std::string& mix_template, BusProfile*);
void destroy ();
- nframes_t compute_initial_length ();
-
enum SubState {
PendingDeclickIn = 0x1,
PendingDeclickOut = 0x2,
@@ -836,7 +833,7 @@ class Session : public PBD::StatefulDestructible, public PBD::ScopedConnectionLi
int transport_sub_state;
mutable gint _record_status;
volatile nframes64_t _transport_frame;
- Location* _session_range_location;
+ Location* _session_range_location; ///< session range, or 0 if there is nothing in the session yet
Slave* _slave;
bool _silent;
@@ -1056,7 +1053,7 @@ class Session : public PBD::StatefulDestructible, public PBD::ScopedConnectionLi
void first_stage_init (std::string path, std::string snapshot_name);
int second_stage_init ();
- void find_current_end ();
+ void update_session_range_location_marker ();
void remove_empty_sounds ();
void setup_midi_control ();
@@ -1442,6 +1439,8 @@ class Session : public PBD::StatefulDestructible, public PBD::ScopedConnectionLi
/** 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);
};
} // namespace ARDOUR
diff --git a/libs/ardour/ardour/session_configuration_vars.h b/libs/ardour/ardour/session_configuration_vars.h
index 2776787271..df76057e0b 100644
--- a/libs/ardour/ardour/session_configuration_vars.h
+++ b/libs/ardour/ardour/session_configuration_vars.h
@@ -37,7 +37,6 @@ CONFIG_VARIABLE (TimecodeFormat, timecode_format, "timecode-format", timecode_30
CONFIG_VARIABLE_SPECIAL(Glib::ustring, raid_path, "raid-path", "", path_expand)
CONFIG_VARIABLE (std::string, bwf_country_code, "bwf-country-code", "US")
CONFIG_VARIABLE (std::string, bwf_organization_code, "bwf-organization-code", "US")
-CONFIG_VARIABLE (bool, end_marker_is_free, "end-marker-is-free", true)
CONFIG_VARIABLE (LayerModel, layer_model, "layer-model", MoveAddHigher)
CONFIG_VARIABLE (std::string, auditioner_output_left, "auditioner-output-left", "default")
CONFIG_VARIABLE (std::string, auditioner_output_right, "auditioner-output-right", "default")
diff --git a/libs/ardour/audiofilesource.cc b/libs/ardour/audiofilesource.cc
index 0e498c3d59..1973678359 100644
--- a/libs/ardour/audiofilesource.cc
+++ b/libs/ardour/audiofilesource.cc
@@ -222,7 +222,7 @@ AudioFileSource::old_peak_path (ustring audio_path)
#ifdef __APPLE__
snprintf (buf, sizeof (buf), "%u-%u-%d.peak", stat_mount.st_ino, stat_file.st_ino, _channel);
#else
- snprintf (buf, sizeof (buf), "%ld-%ld-%d.peak", stat_mount.st_ino, stat_file.st_ino, _channel);
+ snprintf (buf, sizeof (buf), "%lld-%lld-%d.peak", stat_mount.st_ino, stat_file.st_ino, _channel);
#endif
ustring res = peak_dir;
diff --git a/libs/ardour/auditioner.cc b/libs/ardour/auditioner.cc
index 8b8f850f8b..45a836582d 100644
--- a/libs/ardour/auditioner.cc
+++ b/libs/ardour/auditioner.cc
@@ -127,7 +127,7 @@ Auditioner::audition_current_playlist ()
Glib::Mutex::Lock lm (lock);
_diskstream->seek (0);
- length = _diskstream->playlist()->get_maximum_extent();
+ length = _diskstream->playlist()->get_extent().second;
current_frame = 0;
/* force a panner reset now that we have all channels */
diff --git a/libs/ardour/location.cc b/libs/ardour/location.cc
index f855cb75cf..7202e1ef03 100644
--- a/libs/ardour/location.cc
+++ b/libs/ardour/location.cc
@@ -548,6 +548,8 @@ Locations::clear_ranges ()
void
Locations::add (Location *loc, bool make_current)
{
+ assert (loc);
+
{
Glib::Mutex::Lock lm (lock);
locations.push_back (loc);
diff --git a/libs/ardour/playlist.cc b/libs/ardour/playlist.cc
index 649d549b86..a5e662f4d0 100644
--- a/libs/ardour/playlist.cc
+++ b/libs/ardour/playlist.cc
@@ -452,7 +452,7 @@ void
Playlist::delay_notifications ()
{
g_atomic_int_inc (&block_notifications);
- freeze_length = _get_maximum_extent();
+ freeze_length = _get_extent().second;
}
void
@@ -574,7 +574,7 @@ Playlist::flush_notifications ()
if (!pending_bounds.empty() || !pending_removes.empty() || !pending_adds.empty()) {
regions_changed = true;
if (!pending_length) {
- old_length = _get_maximum_extent ();
+ old_length = _get_extent ().second;
check_length = true;
}
}
@@ -608,13 +608,13 @@ Playlist::flush_notifications ()
}
if (check_length) {
- if (old_length != _get_maximum_extent()) {
+ if (old_length != _get_extent().second) {
pending_length = true;
// cerr << _name << " length has changed\n";
}
}
- if (pending_length || (freeze_length != _get_maximum_extent())) {
+ if (pending_length || (freeze_length != _get_extent().second)) {
pending_length = false;
// cerr << _name << " sends LengthChanged\n";
LengthChanged(); /* EMIT SIGNAL */
@@ -737,7 +737,7 @@ Playlist::add_region_internal (boost::shared_ptr<Region> region, framepos_t posi
framecnt_t old_length = 0;
if (!holding_state()) {
- old_length = _get_maximum_extent();
+ old_length = _get_extent().second;
}
if (!first_set_state) {
@@ -767,7 +767,7 @@ Playlist::add_region_internal (boost::shared_ptr<Region> region, framepos_t posi
check_dependents (region, false);
- if (old_length != _get_maximum_extent()) {
+ if (old_length != _get_extent().second) {
notify_length_changed ();
}
}
@@ -808,7 +808,7 @@ Playlist::remove_region_internal (boost::shared_ptr<Region> region)
int ret = -1;
if (!holding_state()) {
- old_length = _get_maximum_extent();
+ old_length = _get_extent().second;
}
if (!in_set_state) {
@@ -832,7 +832,7 @@ Playlist::remove_region_internal (boost::shared_ptr<Region> region)
relayer ();
remove_dependents (region);
- if (old_length != _get_maximum_extent()) {
+ if (old_length != _get_extent().second) {
notify_length_changed ();
}
}
@@ -1203,7 +1203,7 @@ Playlist::copy (framepos_t start, framecnt_t cnt, bool result_is_hidden)
new_name += '.';
new_name += buf;
- cnt = min (_get_maximum_extent() - start, cnt);
+ cnt = min (_get_extent().second - start, cnt);
return PlaylistFactory::create (shared_from_this(), start, cnt, new_name, result_is_hidden);
}
@@ -1216,11 +1216,11 @@ Playlist::paste (boost::shared_ptr<Playlist> other, framepos_t position, float t
RegionLock rl1 (this);
RegionLock rl2 (other.get());
- framecnt_t old_length = _get_maximum_extent();
+ framecnt_t const old_length = _get_extent().second;
int itimes = (int) floor (times);
framepos_t pos = position;
- framecnt_t shift = other->_get_maximum_extent();
+ framecnt_t const shift = other->_get_extent().second;
layer_t top_layer = regions.size();
while (itimes--) {
@@ -1240,7 +1240,7 @@ Playlist::paste (boost::shared_ptr<Playlist> other, framepos_t position, float t
/* XXX shall we handle fractional cases at some point? */
- if (old_length != _get_maximum_extent()) {
+ if (old_length != _get_extent().second) {
notify_length_changed ();
}
@@ -2280,27 +2280,29 @@ Playlist::n_regions() const
return regions.size();
}
-framecnt_t
-Playlist::get_maximum_extent () const
+pair<framecnt_t, framecnt_t>
+Playlist::get_extent () const
{
RegionLock rlock (const_cast<Playlist *>(this), false);
- return _get_maximum_extent ();
+ return _get_extent ();
}
-framecnt_t
-Playlist::_get_maximum_extent () const
+pair<framecnt_t, framecnt_t>
+Playlist::_get_extent () const
{
- RegionList::const_iterator i;
- framecnt_t max_extent = 0;
- framepos_t end = 0;
+ pair<framecnt_t, framecnt_t> ext (max_frames, 0);
- for (i = regions.begin(); i != regions.end(); ++i) {
- if ((end = (*i)->position() + (*i)->length()) > max_extent) {
- max_extent = end;
+ for (RegionList::const_iterator i = regions.begin(); i != regions.end(); ++i) {
+ pair<framecnt_t, framecnt_t> const e ((*i)->position(), (*i)->position() + (*i)->length());
+ if (e.first < ext.first) {
+ ext.first = e.first;
+ }
+ if (e.second > ext.second) {
+ ext.second = e.second;
}
}
- return max_extent;
+ return ext;
}
string
diff --git a/libs/ardour/session.cc b/libs/ardour/session.cc
index 2d4aefd388..a5443a1797 100644
--- a/libs/ardour/session.cc
+++ b/libs/ardour/session.cc
@@ -172,7 +172,7 @@ Session::Session (AudioEngine &eng,
_is_new = !Glib::file_test (_path, Glib::FileTest (G_FILE_TEST_EXISTS | G_FILE_TEST_IS_DIR));
if (_is_new) {
- if (create (mix_template, compute_initial_length(), bus_profile)) {
+ if (create (mix_template, bus_profile)) {
destroy ();
throw failed_constructor ();
}
@@ -700,13 +700,7 @@ Session::hookup_io ()
void
Session::playlist_length_changed ()
{
- /* we can't just increase session_range_location->end() if pl->get_maximum_extent()
- if larger. if the playlist used to be the longest playlist,
- and its now shorter, we have to decrease session_range_location->end(). hence,
- we have to iterate over all diskstreams and check the
- playlists currently in use.
- */
- find_current_end ();
+ update_session_range_location_marker ();
}
void
@@ -723,8 +717,7 @@ Session::track_playlist_changed (boost::weak_ptr<Track> wp)
playlist->LengthChanged.connect_same_thread (*this, boost::bind (&Session::playlist_length_changed, this));
}
- /* see comment in playlist_length_changed () */
- find_current_end ();
+ update_session_range_location_marker ();
}
bool
@@ -2082,7 +2075,7 @@ Session::remove_route (shared_ptr<Route> route)
}
update_route_solo_state ();
- find_current_end ();
+ update_session_range_location_marker ();
// We need to disconnect the route's inputs and outputs
@@ -2396,43 +2389,64 @@ Session::route_by_remote_id (uint32_t id)
return shared_ptr<Route> ((Route*) 0);
}
+/** If either end of the session range location marker lies inside the current
+ * session extent, move it to the corresponding session extent.
+ */
void
-Session::find_current_end ()
+Session::update_session_range_location_marker ()
{
if (_state_of_the_state & Loading) {
return;
}
- nframes_t max = get_maximum_extent ();
+ pair<nframes_t, nframes_t> const ext = get_extent ();
- if (max > _session_range_location->end()) {
- _session_range_location->set_end (max);
- set_dirty();
- DurationChanged(); /* EMIT SIGNAL */
+ if (_session_range_location == 0) {
+ /* we don't have a session range yet; use this one (provided it is valid) */
+ if (ext.first != max_frames) {
+ add_session_range_location (ext.first, ext.second);
+ }
+ } else {
+ /* update the existing session range */
+ if (ext.first < _session_range_location->start()) {
+ _session_range_location->set_start (ext.first);
+ set_dirty ();
+ }
+
+ if (ext.second > _session_range_location->end()) {
+ _session_range_location->set_end (ext.second);
+ set_dirty ();
+ }
+
}
}
-nframes_t
-Session::get_maximum_extent () const
+/** @return Extent of the session's contents; if the session is empty, the first value of
+ * the pair will equal max_frames.
+ */
+pair<nframes_t, nframes_t>
+Session::get_extent () const
{
- nframes_t max = 0;
- nframes_t me;
+ pair<nframes_t, nframes_t> ext (max_frames, 0);
boost::shared_ptr<RouteList> rl = routes.reader ();
for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
boost::shared_ptr<Track> tr = boost::dynamic_pointer_cast<Track> (*i);
if (!tr || tr->destructive()) {
- //ignore tape tracks when getting max extents
+ // ignore tape tracks when getting extents
continue;
}
-
- boost::shared_ptr<Playlist> pl = tr->playlist();
- if ((me = pl->get_maximum_extent()) > max) {
- max = me;
+
+ pair<nframes_t, nframes_t> e = tr->playlist()->get_extent ();
+ if (e.first < ext.first) {
+ ext.first = e.first;
+ }
+ if (e.second > ext.second) {
+ ext.second = e.second;
}
}
- return max;
+ return ext;
}
/* Region management */
@@ -3693,12 +3707,6 @@ Session::add_automation_list(AutomationList *al)
automation_lists[al->id()] = al;
}
-nframes_t
-Session::compute_initial_length ()
-{
- return _engine.frame_rate() * 60 * 5;
-}
-
void
Session::sync_order_keys (std::string const & base)
{
@@ -3838,3 +3846,62 @@ Session::get_routes_with_regions_at (nframes64_t const p) const
return rl;
}
+
+void
+Session::goto_end ()
+{
+ if (_session_range_location) {
+ request_locate (_session_range_location->end(), false);
+ } else {
+ request_locate (0, false);
+ }
+}
+
+void
+Session::goto_start ()
+{
+ if (_session_range_location) {
+ request_locate (_session_range_location->start(), false);
+ } else {
+ request_locate (0, false);
+ }
+}
+
+void
+Session::set_session_start (nframes_t start)
+{
+ if (_session_range_location) {
+ _session_range_location->set_start (start);
+ } else {
+ add_session_range_location (start, start);
+ }
+}
+
+void
+Session::set_session_end (nframes_t end)
+{
+ if (_session_range_location) {
+ _session_range_location->set_end (end);
+ } else {
+ add_session_range_location (end, end);
+ }
+}
+
+nframes_t
+Session::current_start_frame () const
+{
+ return _session_range_location ? _session_range_location->start() : 0;
+}
+
+nframes_t
+Session::current_end_frame () const
+{
+ return _session_range_location ? _session_range_location->end() : 0;
+}
+
+void
+Session::add_session_range_location (nframes_t start, nframes_t end)
+{
+ _session_range_location = new Location (start, end, _("session"), Location::IsSessionRange);
+ _locations.add (_session_range_location);
+}
diff --git a/libs/ardour/session_state.cc b/libs/ardour/session_state.cc
index a0e61d547a..ee7e88caaa 100644
--- a/libs/ardour/session_state.cc
+++ b/libs/ardour/session_state.cc
@@ -179,7 +179,7 @@ Session::first_stage_init (string fullpath, string snapshot_name)
transport_sub_state = 0;
_transport_frame = 0;
_requested_return_frame = -1;
- _session_range_location = new Location (0, 0, _("session"), Location::IsSessionRange);
+ _session_range_location = 0;
g_atomic_int_set (&_record_status, Disabled);
loop_changing = false;
play_loop = false;
@@ -365,8 +365,6 @@ Session::second_stage_init ()
ControlProtocolManager::instance().set_session (this);
- config.set_end_marker_is_free (_is_new);
-
_state_of_the_state = Clean;
DirtyChanged (); /* EMIT SIGNAL */
@@ -491,7 +489,7 @@ Session::ensure_subdirs ()
}
int
-Session::create (const string& mix_template, nframes_t initial_length, BusProfile* bus_profile)
+Session::create (const string& mix_template, BusProfile* bus_profile)
{
if (g_mkdir_with_parents (_path.c_str(), 0755) < 0) {
@@ -540,9 +538,6 @@ Session::create (const string& mix_template, nframes_t initial_length, BusProfil
/* set initial start + end point */
- _session_range_location->set (0, initial_length);
- _locations.add (_session_range_location);
-
_state_of_the_state = Clean;
/* set up Master Out and Control Out if necessary */
@@ -1051,7 +1046,7 @@ Session::state(bool full_state)
// with the default start and end, and get the state for that.
Locations loc;
Location* range = new Location (0, 0, _("session"), Location::IsSessionRange);
- range->set (0, compute_initial_length ());
+ range->set (max_frames, 0);
loc.add (range);
node->add_child_nocopy (loc.get_state());
}
@@ -1242,14 +1237,14 @@ Session::set_state (const XMLNode& node, int version)
set_auto_punch_location (location);
}
- if ((location = _locations.session_range_location()) == 0) {
- _locations.add (_session_range_location);
- } else {
+ if ((location = _locations.session_range_location()) != 0) {
delete _session_range_location;
_session_range_location = location;
}
- AudioFileSource::set_header_position_offset (_session_range_location->start());
+ if (_session_range_location) {
+ AudioFileSource::set_header_position_offset (_session_range_location->start());
+ }
if ((child = find_named_node (node, "Sources")) == 0) {
error << _("Session: XML state has no sources section") << endmsg;
diff --git a/libs/ardour/session_transport.cc b/libs/ardour/session_transport.cc
index 6d7d3b4521..7a378e1a01 100644
--- a/libs/ardour/session_transport.cc
+++ b/libs/ardour/session_transport.cc
@@ -408,36 +408,6 @@ Session::non_realtime_stop (bool abort, int on_entry, bool& finished)
if (did_record) {
begin_reversible_command ("capture");
-
- Location* loc = _locations.session_range_location();
- bool change_end = false;
-
- if (_transport_frame < loc->end()) {
-
- /* stopped recording before current end */
-
- if (config.get_end_marker_is_free()) {
-
- /* first capture for this session, move end back to where we are */
-
- change_end = true;
- }
-
- } else if (_transport_frame > loc->end()) {
-
- /* stopped recording after the current end, extend it */
-
- change_end = true;
- }
-
- if (change_end) {
- XMLNode &before = loc->get_state();
- loc->set_end(_transport_frame);
- XMLNode &after = loc->get_state();
- add_command (new MementoCommand<Location>(*loc, &before, &after));
- }
-
- config.set_end_marker_is_free (false);
_have_captured = true;
}
@@ -587,10 +557,6 @@ Session::non_realtime_stop (bool abort, int on_entry, bool& finished)
save_state (_current_snapshot_name);
}
- if (ptw & PostTransportDuration) {
- DurationChanged (); /* EMIT SIGNAL */
- }
-
if (ptw & PostTransportStop) {
_play_range = false;
play_loop = false;