fix a bad transition in the transportFSM.
[ardour.git] / libs / ardour / sndfilesource.cc
index b34bbaa9d26527af37c6b6fd9e7cb80513a572d1..0ca7e07247006f91a9475cedab2ae27b5239ac80 100644 (file)
@@ -1,21 +1,26 @@
 /*
-    Copyright (C) 2006 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 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.
-
-*/
+ * Copyright (C) 2005-2006 Taybin Rutkin <taybin@taybin.com>
+ * Copyright (C) 2005-2017 Paul Davis <paul@linuxaudiosystems.com>
+ * Copyright (C) 2006-2014 David Robillard <d@drobilla.net>
+ * Copyright (C) 2008-2012 Carl Hetherington <carl@carlh.net>
+ * Copyright (C) 2012-2018 Robin Gareus <robin@gareus.org>
+ * Copyright (C) 2013-2015 John Emmas <john@creativepost.co.uk>
+ * Copyright (C) 2015 Tim Mayberry <mojofunk@gmail.com>
+ *
+ * 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.
+ *
+ * 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.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
 
 #ifdef WAF_BUILD
 #include "libardour-config.h"
@@ -120,9 +125,9 @@ SndFileSource::SndFileSource (Session& s, const string& path, const string& orig
 {
        int fmt = 0;
 
-        init_sndfile ();
+       init_sndfile ();
 
-        assert (!Glib::file_test (_path, Glib::FILE_TEST_EXISTS));
+       assert (!Glib::file_test (_path, Glib::FILE_TEST_EXISTS));
        existence_check ();
 
        _file_is_new = true;
@@ -133,6 +138,15 @@ SndFileSource::SndFileSource (Session& s, const string& path, const string& orig
                _flags = Flag (_flags & ~Broadcast);
                break;
 
+       case FLAC:
+               fmt = SF_FORMAT_FLAC;
+               if (sfmt == FormatFloat) {
+                       sfmt = FormatInt24;
+               }
+               _flags = Flag (_flags & ~Broadcast);
+               _flags = Flag (_flags & ~Destructive); // XXX or force WAV if destructive?
+               break;
+
        case AIFF:
                fmt = SF_FORMAT_AIFF;
                _flags = Flag (_flags & ~Broadcast);
@@ -341,7 +355,7 @@ SndFileSource::init_sndfile ()
 
        if (destructive()) {
                xfade_buf = new Sample[xfade_samples];
-               _timeline_position = header_position_offset;
+               _natural_position = header_position_offset;
        }
 
        AudioFileSource::HeaderPositionOffsetChanged.connect_same_thread (header_position_connection, boost::bind (&SndFileSource::handle_header_position_change, this));
@@ -384,8 +398,8 @@ SndFileSource::open ()
        }
 
        if ((_info.format & SF_FORMAT_TYPEMASK ) == SF_FORMAT_FLAC) {
-               assert (!writable());
-               _sndfile = sf_open_fd (fd, SFM_READ, &_info, true);
+               assert (!destructive());
+               _sndfile = sf_open_fd (fd, writable () ? SFM_WRITE : SFM_READ, &_info, true);
        } else {
                _sndfile = sf_open_fd (fd, writable() ? SFM_RDWR : SFM_READ, &_info, true);
        }
@@ -438,15 +452,22 @@ SndFileSource::open ()
 
        if (_file_is_new && _length == 0 && writable() && !bwf_info_exists) {
                /* newly created files will not have a BWF header at this point in time.
-                * Import will have called Source::set_timeline_position() if one exists
+                * Import will have called Source::set_natural_position() if one exists
                 * in the original. */
-               header_position_offset = _timeline_position;
+               header_position_offset = _natural_position;
        }
 
-       /* Set our timeline position to either the time reference from a BWF header or the current
-          start of the session.
-       */
-       set_timeline_position (bwf_info_exists ? _broadcast_info->get_time_reference() : header_position_offset);
+       if (destructive()) {
+               /* Set our timeline position to either the time reference from a BWF header or the current
+                  start of the session.
+               */
+               set_natural_position (bwf_info_exists ? _broadcast_info->get_time_reference() : header_position_offset);
+       } else {
+               /* If a BWF header exists, set our _natural_position from it */
+               if (bwf_info_exists) {
+                       set_natural_position (_broadcast_info->get_time_reference());
+               }
+       }
 
        if (_length != 0 && !bwf_info_exists) {
                delete _broadcast_info;
@@ -659,7 +680,7 @@ SndFileSource::destructive_write_unlocked (Sample* data, samplecnt_t cnt)
                _capture_end = false;
 
                /* move to the correct location place */
-               file_pos = capture_start_sample - _timeline_position;
+               file_pos = capture_start_sample - _natural_position;
 
                // split cnt in half
                samplecnt_t subcnt = cnt / 2;
@@ -691,7 +712,7 @@ SndFileSource::destructive_write_unlocked (Sample* data, samplecnt_t cnt)
                _capture_end = false;
 
                /* move to the correct location place */
-               file_pos = capture_start_sample - _timeline_position;
+               file_pos = capture_start_sample - _natural_position;
 
                if (crossfade (data, cnt, 1) != cnt) {
                        return 0;
@@ -733,7 +754,7 @@ SndFileSource::destructive_write_unlocked (Sample* data, samplecnt_t cnt)
 int
 SndFileSource::update_header (samplepos_t when, struct tm& now, time_t tnow)
 {
-       set_timeline_position (when);
+       set_natural_position (when);
 
        if (_flags & Broadcast) {
                if (setup_broadcast_info (when, now, tnow)) {
@@ -801,20 +822,20 @@ SndFileSource::setup_broadcast_info (samplepos_t /*when*/, struct tm& now, time_
 
        /* now update header position taking header offset into account */
 
-       set_header_timeline_position ();
+       set_header_natural_position ();
 
        return 0;
 }
 
 void
-SndFileSource::set_header_timeline_position ()
+SndFileSource::set_header_natural_position ()
 {
        if (!(_flags & Broadcast)) {
                return;
        }
        assert (_broadcast_info);
 
-       _broadcast_info->set_time_reference (_timeline_position);
+       _broadcast_info->set_time_reference (_natural_position);
 
        if (_sndfile == 0 || !_broadcast_info->write_to_file (_sndfile)) {
                error << string_compose (_("cannot set broadcast info for audio file %1 (%2); dropping broadcast info for this file"),
@@ -846,12 +867,6 @@ SndFileSource::write_float (Sample* data, samplepos_t sample_pos, samplecnt_t cn
        return cnt;
 }
 
-samplepos_t
-SndFileSource::natural_position() const
-{
-       return _timeline_position;
-}
-
 void
 SndFileSource::clear_capture_marks ()
 {
@@ -864,7 +879,7 @@ void
 SndFileSource::mark_capture_start (samplepos_t pos)
 {
        if (destructive()) {
-               if (pos < _timeline_position) {
+               if (pos < _natural_position) {
                        _capture_start = false;
                } else {
                        _capture_start = true;
@@ -1022,8 +1037,8 @@ SndFileSource::handle_header_position_change ()
                        error << string_compose(_("Filesource: start time is already set for existing file (%1): Cannot change start time."), _path ) << endmsg;
                        //in the future, pop up a dialog here that allows user to regenerate file with new start offset
                } else if (writable()) {
-                       _timeline_position = header_position_offset;
-                       set_header_timeline_position ();  //this will get flushed if/when the file is recorded to
+                       _natural_position = header_position_offset;
+                       set_header_natural_position ();  //this will get flushed if/when the file is recorded to
                }
        }
 }
@@ -1047,14 +1062,14 @@ SndFileSource::setup_standard_crossfades (Session const & s, samplecnt_t rate)
 }
 
 void
-SndFileSource::set_timeline_position (samplepos_t pos)
+SndFileSource::set_natural_position (samplepos_t pos)
 {
        // destructive track timeline postion does not change
        // except at instantion or when header_position_offset
        // (session start) changes
 
        if (!destructive()) {
-               AudioFileSource::set_timeline_position (pos);
+               AudioFileSource::set_natural_position (pos);
        }
 }
 
@@ -1140,4 +1155,3 @@ SndFileSource::set_path (const string& p)
 {
         FileSource::set_path (p);
 }
-