Merged with trunk R846
[ardour.git] / libs / ardour / location.cc
index 87a27e5c3d5069032edf2904118945aac1156b13..ca88a2851b131826d9a88ab0a04c396ef49050dc 100644 (file)
 #include <pbd/xml++.h>
 
 #include <ardour/location.h>
+#include <ardour/audiofilesource.h>
 
 #include "i18n.h"
 
 using namespace std;
 using namespace ARDOUR;
 using namespace sigc;
+using namespace PBD;
 
 Location::Location (const Location& other)
        : _name (other._name),
@@ -43,6 +45,10 @@ Location::Location (const Location& other)
          _end (other._end),
          _flags (other._flags)
 {
+       /* start and end flags can never be copied, because there can only ever be one of each */
+
+       _flags = Flags (_flags & ~IsStart);
+       _flags = Flags (_flags & ~IsEnd);
 }
 
 Location*
@@ -70,6 +76,9 @@ Location::set_start (jack_nframes_t s)
                        _start = s;
                        _end = s;
                        start_changed(this); /* EMIT SIGNAL */
+                       if ( is_start() ) {
+                               AudioFileSource::set_header_position_offset ( s );
+                       }
                }
                return 0;
        }
@@ -371,7 +380,7 @@ Locations::set_current (Location *loc, bool want_lock)
        int ret;
 
        if (want_lock) {
-               LockMonitor lm (lock, __LINE__, __FILE__);
+               Glib::Mutex::Lock lm (lock);
                ret = set_current_unlocked (loc);
        } else {
                ret = set_current_unlocked (loc);
@@ -399,7 +408,7 @@ void
 Locations::clear ()
 {
        {
-               LockMonitor lm (lock, __LINE__, __FILE__);
+               Glib::Mutex::Lock lm (lock);
                LocationList::iterator tmp;
                for (LocationList::iterator i = locations.begin(); i != locations.end(); ) {
                        tmp = i;
@@ -424,7 +433,7 @@ void
 Locations::clear_markers ()
 {
        {
-               LockMonitor lm (lock, __LINE__, __FILE__);
+               Glib::Mutex::Lock lm (lock);
                LocationList::iterator tmp;
 
                for (LocationList::iterator i = locations.begin(); i != locations.end(); ) {
@@ -448,7 +457,7 @@ void
 Locations::clear_ranges ()
 {
        {
-               LockMonitor lm (lock, __LINE__, __FILE__);
+               Glib::Mutex::Lock lm (lock);
                LocationList::iterator tmp;
                
                for (LocationList::iterator i = locations.begin(); i != locations.end(); ) {
@@ -477,7 +486,7 @@ void
 Locations::add (Location *loc, bool make_current)
 {
        {
-               LockMonitor lm (lock, __LINE__, __FILE__);
+               Glib::Mutex::Lock lm (lock);
                locations.push_back (loc);
 
                if (make_current) {
@@ -507,7 +516,7 @@ Locations::remove (Location *loc)
        }
 
        {
-               LockMonitor lm (lock, __LINE__, __FILE__);
+               Glib::Mutex::Lock lm (lock);
 
                for (i = locations.begin(); i != locations.end(); ++i) {
                        if ((*i) == loc) {
@@ -547,7 +556,7 @@ Locations::get_state ()
 {
        XMLNode *node = new XMLNode ("Locations");
        LocationList::iterator iter;
-       LockMonitor lm (lock, __LINE__, __FILE__);
+       Glib::Mutex::Lock lm (lock);
        
        for (iter  = locations.begin(); iter != locations.end(); ++iter) {
                node->add_child_nocopy ((*iter)->get_state ());
@@ -570,7 +579,7 @@ Locations::set_state (const XMLNode& node)
        nlist = node.children();
        
        {
-               LockMonitor lm (lock, __LINE__, __FILE__);
+               Glib::Mutex::Lock lm (lock);
 
                for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
                        Location *loc = new Location;
@@ -614,7 +623,7 @@ Locations::first_location_before (jack_nframes_t frame)
        LocationList locs;
 
        {
-               LockMonitor lm (lock, __LINE__, __FILE__);
+               Glib::Mutex::Lock lm (lock);
                locs = locations;
        }
 
@@ -638,7 +647,7 @@ Locations::first_location_after (jack_nframes_t frame)
        LocationList locs;
 
        {
-               LockMonitor lm (lock, __LINE__, __FILE__);
+               Glib::Mutex::Lock lm (lock);
                locs = locations;
        }
 
@@ -656,6 +665,80 @@ Locations::first_location_after (jack_nframes_t frame)
        return 0;
 }
 
+jack_nframes_t
+Locations::first_mark_before (jack_nframes_t frame)
+{
+       LocationList locs;
+
+       {
+        Glib::Mutex::Lock lm (lock);
+               locs = locations;
+       }
+
+       LocationStartLaterComparison cmp;
+       locs.sort (cmp);
+
+       /* locs is now sorted latest..earliest */
+       
+       for (LocationList::iterator i = locs.begin(); i != locs.end(); ++i) {
+               if (!(*i)->is_hidden()) {
+                       if ((*i)->is_mark()) {
+                               /* MARK: start == end */
+                               if ((*i)->start() < frame) {
+                                       return (*i)->start();
+                               }
+                       } else {
+                               /* RANGE: start != end, compare start and end */
+                               if ((*i)->end() < frame) {
+                                       return (*i)->end();
+                               }
+                               if ((*i)->start () < frame) {
+                                       return (*i)->start();
+                               }
+                       }
+               }
+       }
+
+       return 0;
+}
+
+jack_nframes_t
+Locations::first_mark_after (jack_nframes_t frame)
+{
+       LocationList locs;
+
+       {
+        Glib::Mutex::Lock lm (lock);
+               locs = locations;
+       }
+
+       LocationStartEarlierComparison cmp;
+       locs.sort (cmp);
+
+       /* locs is now sorted earliest..latest */
+       
+       for (LocationList::iterator i = locs.begin(); i != locs.end(); ++i) {
+               if (!(*i)->is_hidden()) {
+                       if ((*i)->is_mark()) {
+                               /* MARK, start == end so just compare start */
+                               if ((*i)->start() > frame) {
+                                       return (*i)->start();
+                               }
+                       } else {
+                               /* RANGE, start != end, compare start and end */
+                               if ((*i)->start() > frame ) {
+                                       return (*i)->start ();
+                               }
+                               if ((*i)->end() > frame) {
+                                       return (*i)->end ();
+                               }
+                       }
+               }
+       }
+
+       return max_frames;
+}
+
 Location*
 Locations::end_location () const
 {
@@ -718,7 +801,7 @@ Change
 Locations::restore_state (StateManager::State& state) 
 {
        {
-               LockMonitor lm (lock, __LINE__, __FILE__);
+               Glib::Mutex::Lock lm (lock);
                State* lstate = dynamic_cast<State*> (&state);
 
                locations = lstate->locations;
@@ -743,7 +826,7 @@ uint32_t
 Locations::num_range_markers () const
 {
        uint32_t cnt = 0;
-       LockMonitor lm (lock, __LINE__, __FILE__);
+       Glib::Mutex::Lock lm (lock);
        for (LocationList::const_iterator i = locations.begin(); i != locations.end(); ++i) {
                if ((*i)->is_range_marker()) {
                        ++cnt;
@@ -751,3 +834,14 @@ Locations::num_range_markers () const
        }
        return cnt;
 }
+
+Location *
+Locations::get_location_by_id(PBD::ID id)
+{
+    LocationList::iterator it;
+    for (it  = locations.begin(); it != locations.end(); it++)
+        if (id == (*it)->id())
+            return *it;
+
+    return 0;
+}