Remove unnecessary 0 checks before delete; see http://www.parashift.com/c++-faq-lite...
[ardour.git] / libs / ardour / auditioner.cc
index 29ae3b4d2bc109d042ff3d0de67ce60d2c58dea2..d6f63c2f9da410183e4e180672016ef4d9cec87d 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_output (DataType::AUDIO, 0);  
+       }
+
+       if (right == "default") {
+               right = _session.engine().get_nth_physical_output (DataType::AUDIO, 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);
        }
 
@@ -77,10 +86,10 @@ AudioPlaylist&
 Auditioner::prepare_playlist ()
 {
        // FIXME auditioner is still audio-only
-       AudioPlaylist* const apl = dynamic_cast<AudioPlaylist*>(_diskstream->playlist());
+       boost::shared_ptr<AudioPlaylist> apl = boost::dynamic_pointer_cast<AudioPlaylist>(_diskstream->playlist());
        assert(apl);
 
-       apl->clear (false);
+       apl->clear ();
        return *apl;
 }
 
@@ -101,7 +110,7 @@ Auditioner::audition_current_playlist ()
 
        /* force a panner reset now that we have all channels */
 
-       _panner->reset (n_outputs().get(DataType::AUDIO), _diskstream->n_channels().get(DataType::AUDIO));
+       _panner->reset (n_outputs().n_audio(), _diskstream->n_channels().n_audio());
 
        g_atomic_int_set (&_active, 1);
 }
@@ -128,15 +137,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 (false);
-       _diskstream->playlist()->add_region (the_region, 0, 1, false);
+       _diskstream->playlist()->drop_regions ();
+       _diskstream->playlist()->add_region (the_region, 0, 1);
 
-       while (_diskstream->n_channels().get(DataType::AUDIO) < the_region->n_channels()) {
-               audio_diskstream()->add_channel ();
-       }
-
-       while (_diskstream->n_channels().get(DataType::AUDIO) > the_region->n_channels()) {
-               audio_diskstream()->remove_channel ();
+       if (_diskstream->n_channels().n_audio() < the_region->n_channels()) {
+               audio_diskstream()->add_channel (the_region->n_channels() - _diskstream->n_channels().n_audio());
+       } else if (_diskstream->n_channels().n_audio() > the_region->n_channels()) {
+               audio_diskstream()->remove_channel (_diskstream->n_channels().n_audio() - the_region->n_channels());
        }
 
        /* force a panner reset now that we have all channels */
@@ -144,16 +151,27 @@ Auditioner::audition_region (boost::shared_ptr<Region> region)
        reset_panner();
 
        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);
 }
 
 int
-Auditioner::play_audition (jack_nframes_t nframes)
+Auditioner::play_audition (nframes_t nframes)
 {
        bool need_butler;
-       jack_nframes_t this_nframes;
+       nframes_t this_nframes;
        int ret;
 
        if (g_atomic_int_get (&_active) == 0) {
@@ -184,18 +202,32 @@ Auditioner::play_audition (jack_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]);
-                       free (connections);
+               vector<string> connections;
+               if (output (0)->get_connections (connections)) {
+                       phys = _session.engine().get_nth_physical_output (DataType::AUDIO, 0);
+                       if (phys != connections[0]) {
+                               Config->set_auditioner_output_left (connections[0]);
+                       } else {
+                               Config->set_auditioner_output_left ("default");
+                       }
+               } else {
+                       Config->set_auditioner_output_left ("");
                }
                
-               connections = output (1)->get_connections ();
-               if (connections) {
-                       Config->set_auditioner_output_right (connections[0]);
-                       free (connections);
+               connections.clear ();
+
+               if (output (1)->get_connections (connections)) {
+                       phys = _session.engine().get_nth_physical_output (DataType::AUDIO, 1);
+                       if (phys != connections[0]) {
+                               Config->set_auditioner_output_right (connections[0]);
+                       } else {
+                               Config->set_auditioner_output_right ("default");
+                       }
+               } else {
+                       Config->set_auditioner_output_right ("");
                }
        }
 }