provide support for playhead-to-next/previous-region-boundary actions, and bindings...
[ardour.git] / libs / ardour / auditioner.cc
index ce6bcd41430f598a25dbc8e981f04daec551f374..7f1154a13d017288b296a3f0616a307c945a1c8e 100644 (file)
@@ -15,7 +15,6 @@
     along with this program; if not, write to the Free Software
     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 
-    $Id$
 */
 
 #include <glibmm/thread.h>
@@ -24,6 +23,7 @@
 
 #include <ardour/audio_diskstream.h>
 #include <ardour/audioregion.h>
+#include <ardour/audioengine.h>
 #include <ardour/route.h>
 #include <ardour/session.h>
 #include <ardour/auditioner.h>
@@ -43,8 +43,17 @@ Auditioner::Auditioner (Session& s)
 {
        string left = Config->get_auditioner_output_left();
        string right = Config->get_auditioner_output_right();
+
+       if (left == "default") {
+               left = _session.engine().get_nth_physical_audio_output (0);     
+       }
+
+       if (right == "default") {
+               right = _session.engine().get_nth_physical_audio_output (1);
+       }
        
        if ((left.length() == 0) && (right.length() == 0)) {
+               warning << _("no outputs available for auditioner - manual connection required") << endmsg;
                return;
        }
 
@@ -55,7 +64,7 @@ Auditioner::Auditioner (Session& s)
        }
 
        if (right.length()) {
-               audio_diskstream()->add_channel();
+               audio_diskstream()->add_channel (1);
                add_output_port (right, this, DataType::AUDIO);
        }
 
@@ -126,15 +135,13 @@ Auditioner::audition_region (boost::shared_ptr<Region> region)
        boost::shared_ptr<AudioRegion> the_region (boost::dynamic_pointer_cast<AudioRegion> (RegionFactory::create (region)));
        the_region->set_position (0, this);
 
-       _diskstream->playlist()->clear ();
+       _diskstream->playlist()->drop_regions ();
        _diskstream->playlist()->add_region (the_region, 0, 1);
 
-       while (_diskstream->n_channels() < the_region->n_channels()) {
-               audio_diskstream()->add_channel ();
-       }
-
-       while (_diskstream->n_channels() > the_region->n_channels()) {
-               audio_diskstream()->remove_channel ();
+       if (_diskstream->n_channels() < the_region->n_channels()) {
+               audio_diskstream()->add_channel (the_region->n_channels() - _diskstream->n_channels());
+       } else if (_diskstream->n_channels() > the_region->n_channels()) {
+               audio_diskstream()->remove_channel (_diskstream->n_channels() - the_region->n_channels());
        }
 
        /* force a panner reset now that we have all channels */
@@ -142,8 +149,19 @@ Auditioner::audition_region (boost::shared_ptr<Region> region)
        _panner->reset (n_outputs(), _diskstream->n_channels());
 
        length = the_region->length();
-       _diskstream->seek (0);
-       current_frame = 0;
+
+       int dir;
+       nframes_t offset = the_region->sync_offset (dir);
+
+       /* can't audition from a negative sync point */
+
+       if (dir < 0) {
+               offset = 0;
+       }
+
+       _diskstream->seek (offset);
+       current_frame = offset;
+
        g_atomic_int_set (&_active, 1);
 }
 
@@ -169,6 +187,7 @@ Auditioner::play_audition (nframes_t nframes)
        }
 
        need_butler = _diskstream->commit (this_nframes);
+
        current_frame += this_nframes;
 
        if (current_frame >= length) {
@@ -182,18 +201,34 @@ Auditioner::play_audition (nframes_t nframes)
 void
 Auditioner::output_changed (IOChange change, void* src)
 {
+       string phys;
+
        if (change & ConnectionsChanged) {
                const char ** connections;
                connections =  output (0)->get_connections ();
                if (connections) {
-                       Config->set_auditioner_output_left (connections[0]);
+                       phys = _session.engine().get_nth_physical_audio_output (0);
+                       if (phys != connections[0]) {
+                               Config->set_auditioner_output_left (connections[0]);
+                       } else {
+                               Config->set_auditioner_output_left ("default");
+                       }
                        free (connections);
+               } else {
+                       Config->set_auditioner_output_left ("");
                }
                
                connections = output (1)->get_connections ();
                if (connections) {
-                       Config->set_auditioner_output_right (connections[0]);
+                       phys = _session.engine().get_nth_physical_audio_output (1);
+                       if (phys != connections[0]) {
+                               Config->set_auditioner_output_right (connections[0]);
+                       } else {
+                               Config->set_auditioner_output_right ("default");
+                       }
                        free (connections);
+               } else {
+                       Config->set_auditioner_output_right ("");
                }
        }
 }