new automation state model, sort of working, but not really
[ardour.git] / libs / ardour / audiofilesource.cc
index fbddcdafdfaf959b382ee503e054459bd2639a9e..77709e3a3cb58294ac6c29c42937ae3921cbabe4 100644 (file)
 #include <ardour/sndfilesource.h>
 #include <ardour/destructive_filesource.h>
 #include <ardour/session.h>
+#include <ardour/source_factory.h>
 
 // if these headers come before sigc++ is included
 // the parser throws ObjC++ errors. (nil is a keyword)
 #ifdef HAVE_COREAUDIO 
-#include <ardour/coreaudio_source.h>
+#include <ardour/coreaudiosource.h>
 #include <AudioToolbox/ExtendedAudioFile.h>
 #include <AudioToolbox/AudioFormat.h>
 #endif // HAVE_COREAUDIO
 #include "i18n.h"
 
 using namespace ARDOUR;
+using namespace PBD;
 
 string AudioFileSource::peak_dir = "";
 string AudioFileSource::search_path;
 
-sigc::signal<void,struct tm*, time_t> AudioFileSource::HeaderPositionOffsetChanged;
-bool                                  AudioFileSource::header_position_negative;
-uint64_t                              AudioFileSource::header_position_offset;
+sigc::signal<void> AudioFileSource::HeaderPositionOffsetChanged;
+uint64_t           AudioFileSource::header_position_offset = 0;
 
-char   AudioFileSource::bwf_country_code[3] = "US";
-char   AudioFileSource::bwf_organization_code[4] = "LAS";
+/* XXX maybe this too */
 char   AudioFileSource::bwf_serial_number[13] = "000000000000";
 
-AudioFileSource::AudioFileSource (string idstr, Flag flags)
-       : AudioSource (idstr), _flags (flags)
+AudioFileSource::AudioFileSource (Session& s, string idstr, Flag flags)
+       : AudioSource (s, idstr), _flags (flags)
 {
        /* constructor used for existing external to session files. file must exist already */
 
@@ -73,8 +73,8 @@ AudioFileSource::AudioFileSource (string idstr, Flag flags)
 
 }
 
-AudioFileSource::AudioFileSource (std::string path, Flag flags, SampleFormat samp_format, HeaderFormat hdr_format)
-       : AudioSource (path), _flags (flags)
+AudioFileSource::AudioFileSource (Session& s, std::string path, Flag flags, SampleFormat samp_format, HeaderFormat hdr_format)
+       : AudioSource (s, path), _flags (flags)
 {
        /* constructor used for new internal-to-session files. file cannot exist */
 
@@ -83,8 +83,8 @@ AudioFileSource::AudioFileSource (std::string path, Flag flags, SampleFormat sam
        }
 }
 
-AudioFileSource::AudioFileSource (const XMLNode& node)
-       : AudioSource (node), _flags (Flag (Writable|CanRename))
+AudioFileSource::AudioFileSource (Session& s, const XMLNode& node)
+       : AudioSource (s, node), _flags (Flag (Writable|CanRename))
 {
        /* constructor used for existing internal-to-session files. file must exist */
 
@@ -108,8 +108,7 @@ AudioFileSource::~AudioFileSource ()
 bool
 AudioFileSource::removable () const
 {
-       return (_flags & Removable) && ((_flags & RemoveAtDestroy) || 
-                                     ((_flags & RemovableIfEmpty) && is_empty (_path)));
+       return (_flags & Removable) && ((_flags & RemoveAtDestroy) || ((_flags & RemovableIfEmpty) && length() == 0));
 }
 
 int
@@ -118,10 +117,12 @@ AudioFileSource::init (string pathstr, bool must_exist)
        bool is_new = false;
 
        _length = 0;
+       timeline_position = 0;
        next_peak_clear_should_notify = false;
-       
+       _peaks_built = false;
+       file_is_new = false;
+
        if (!find (pathstr, must_exist, is_new)) {
-               cerr << "cannot find " << pathstr << " with me = " << must_exist << endl;
                return -1;
        }
 
@@ -136,7 +137,7 @@ AudioFileSource::init (string pathstr, bool must_exist)
 string
 AudioFileSource::peak_path (string audio_path)
 {
-       return Session::peak_path_from_audio_path (audio_path);
+       return _session.peak_path_from_audio_path (audio_path);
 }
 
 string
@@ -165,95 +166,6 @@ AudioFileSource::old_peak_path (string audio_path)
        return res;
 }
 
-#ifdef HAVE_COREAUDIO
-
-AudioFileSource*
-AudioFileSource::create (const XMLNode& node)
-{
-       AudioFileSource* es = 0;
-
-       if (node.property (X_("destructive")) != 0) {
-               
-               es = new DestructiveFileSource (node);
-       
-       } else {
-               
-               try {
-                       es = new CoreAudioSource (node);
-               } 
-               
-               
-               catch (failed_constructor& err) {
-                       es = new SndFileSource (node);
-               }
-       }
-       
-       return es;
-}
-
-#else
-
-AudioFileSource*
-AudioFileSource::create (const XMLNode& node)
-{
-       if (node.property (X_("destructive")) != 0) {
-               
-               return new DestructiveFileSource (node);
-               
-       } else {
-               
-               return new SndFileSource (node);
-       }
-}
-
-#endif // HAVE_COREAUDIO
-
-#ifdef HAVE_COREAUDIO
-AudioFileSource*
-AudioFileSource::create (const string& idstr)
-{
-       AudioFileSource* es = 0;
-
-       try {
-               es = new CoreAudioSource (idstr);
-       }
-
-       catch (failed_constructor& err) {
-               es = new SndFileSource (idstr);
-       }
-
-       return es;
-}
-
-#else
-
-AudioFileSource*
-AudioFileSource::create (string idstr)
-{
-       return new SndFileSource (idstr);
-}
-
-#endif // HAVE_COREAUDIO
-
-#ifdef HAVE_COREAUDIO
-std::string 
-CFStringRefToStdString(CFStringRef stringRef)
-{
-       CFIndex size = 
-               CFStringGetMaximumSizeForEncoding(CFStringGetLength(stringRef) , 
-               kCFStringEncodingASCII);
-           char *buf = new char[size];
-       
-       std::string result;
-
-       if(CFStringGetCString(stringRef, buf, size, kCFStringEncodingASCII)) {
-           result = buf;
-       }
-       delete [] buf;
-       return result;
-}
-#endif // HAVE_COREAUDIO
-
 bool
 AudioFileSource::get_soundfile_info (string path, SoundFileInfo& _info, string& error_msg)
 {
@@ -374,7 +286,8 @@ AudioFileSource::mark_for_remove ()
        if (!writable()) {
                return;
        }
-       _flags = Flag (_flags | RemoveAtDestroy);
+
+       _flags = Flag (_flags | Removable | RemoveAtDestroy);
 }
 
 void
@@ -592,39 +505,29 @@ AudioFileSource::set_search_path (string p)
 }
 
 void
-AudioFileSource::set_header_position_offset (jack_nframes_t offset, bool negative)
+AudioFileSource::set_header_position_offset (nframes_t offset)
 {
-       time_t tnow;
-
-       time (&tnow);
-
        header_position_offset = offset;
-       header_position_negative = negative;
-       HeaderPositionOffsetChanged (localtime (&tnow), tnow); /* EMIT SIGNAL */
+       HeaderPositionOffsetChanged ();
 }
 
 void
-AudioFileSource::set_timeline_position (jack_nframes_t pos)
+AudioFileSource::set_timeline_position (nframes_t pos)
 {
        timeline_position = pos;
 }
 
 void
-AudioFileSource::handle_header_position_change (struct tm* now, time_t tnow)
+AudioFileSource::set_allow_remove_if_empty (bool yn)
 {
-       /* don't do this if the file has never had its header flushed to disk yet */
-
-       if (writable() && _timestamp) {
-               set_header_timeline_position ();
-               flush_header ();
+       if (!writable()) {
+               return;
        }
-}
 
-void
-AudioFileSource::set_allow_remove_if_empty (bool yn)
-{
-       if (writable()) {
-               allow_remove_if_empty = yn;
+       if (yn) {
+               _flags = Flag (_flags | RemovableIfEmpty);
+       } else {
+               _flags = Flag (_flags & ~RemovableIfEmpty);
        }
 }
 
@@ -640,6 +543,12 @@ AudioFileSource::set_name (string newname, bool destructive)
                return -1;
        }
 
+       // Test whether newpath exists, if yes notify the user but continue. 
+       if (access(newpath.c_str(),F_OK) == 0) {
+               error << _("Programming error! Ardour tried to rename a file over another file! It's safe to continue working, but please report this to the developers.") << endmsg;
+               return -1;
+       }
+
        if (rename (oldpath.c_str(), newpath.c_str()) != 0) {
                error << string_compose (_("cannot rename audio file for %1 to %2"), _name, newpath) << endmsg;
                return -1;
@@ -652,10 +561,24 @@ AudioFileSource::set_name (string newname, bool destructive)
 }
 
 bool
-AudioFileSource::is_empty (string path)
+AudioFileSource::is_empty (Session& s, string path)
 {
-       /* XXX fix me */
+       bool ret = false;
+       boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource> (SourceFactory::createReadable (s, path, NoPeakFile, false));
+
+       if (afs) {
+               ret = (afs->length() == 0);
+       }
 
-       return false;
+       return ret;
 }
 
+int
+AudioFileSource::setup_peakfile ()
+{
+       if (!(_flags & NoPeakFile)) {
+               return initialize_peakfile (file_is_new, _path);
+       } else {
+               return 0;
+       }
+}