Fix bugs in BroadcastInfo, and use it in SndfileSource
authorSakari Bergen <sakari.bergen@beatwaves.net>
Wed, 17 Sep 2008 20:34:31 +0000 (20:34 +0000)
committerSakari Bergen <sakari.bergen@beatwaves.net>
Wed, 17 Sep 2008 20:34:31 +0000 (20:34 +0000)
git-svn-id: svn://localhost/ardour2/branches/3.0@3747 d708f5d6-7413-0410-9779-e7cbd77b26cf

libs/ardour/ardour/broadcast_info.h
libs/ardour/ardour/sndfilesource.h
libs/ardour/broadcast_info.cc
libs/ardour/sndfilesource.cc

index 07522839fabf1fae7c91be786bc2e465cd65d295..ff042dfbbbdec438f807a08888bd07113db56a03 100644 (file)
@@ -48,7 +48,7 @@ class BroadcastInfo
        
        /* Convenience functions */
        
-       void set_from_session (Session const & session, int64_t time);
+       void set_from_session (Session const & session, int64_t time_ref);
        
        /* Reading */
        
index 4ad967c132a2a4e8ce46ad7ccb9b416453be5b6e..b7c7a9daf15c2b4b9dfaec806d4281cff0573bbc 100644 (file)
@@ -23,6 +23,7 @@
 #include <sndfile.h>
 
 #include <ardour/audiofilesource.h>
+#include <ardour/broadcast_info.h>
 
 namespace ARDOUR {
 
@@ -74,7 +75,7 @@ class SndFileSource : public AudioFileSource {
   private:
        SNDFILE *sf;
        SF_INFO _info;
-       SF_BROADCAST_INFO *_broadcast_info;
+       BroadcastInfo *_broadcast_info;
 
        void init ();
        int open();
@@ -99,8 +100,6 @@ class SndFileSource : public AudioFileSource {
        nframes_t destructive_write_unlocked (Sample *dst, nframes_t cnt);
        nframes_t nondestructive_write_unlocked (Sample *dst, nframes_t cnt);
        void handle_header_position_change ();
-
-       static int64_t get_timecode_info (SNDFILE* sf, SF_BROADCAST_INFO* binfo, bool& exists);
 };
 
 } // namespace ARDOUR
index b887c4fe18c0e5f4306bb632147bdde24bbb98a7..b4a5427945a2394dde3e78e0acc44114780504c1 100644 (file)
@@ -36,6 +36,21 @@ using namespace PBD;
 namespace ARDOUR
 {
 
+static void
+snprintf_bounded_null_filled (char* target, size_t target_size, char const * fmt, ...)
+{
+       char buf[target_size+1];
+       va_list ap;
+
+       va_start (ap, fmt);
+       vsnprintf (buf, target_size+1, fmt, ap);
+       va_end (ap);
+
+       memset (target, 0, target_size);
+       memcpy (target, buf, target_size);
+
+}
+
 BroadcastInfo::BroadcastInfo () :
   _has_info (false)
 {
@@ -56,10 +71,10 @@ BroadcastInfo::~BroadcastInfo ()
 }
 
 void
-BroadcastInfo::set_from_session (Session const & session, int64_t time)
+BroadcastInfo::set_from_session (Session const & session, int64_t time_ref)
 {
        set_description (session.name());
-       set_time_reference (time);
+       set_time_reference (time_ref);
        set_origination_time ();
        set_originator ();
        set_originator_ref ();
@@ -181,7 +196,7 @@ BroadcastInfo::set_description (string const & desc)
 {
        _has_info = true;
        
-       snprintf (info->description, sizeof (info->description), desc.c_str());
+       snprintf_bounded_null_filled (info->description, sizeof (info->description), desc.c_str());
 }
 
 void
@@ -202,12 +217,12 @@ BroadcastInfo::set_origination_time (struct tm * now)
                _time = *now;
        }
        
-       snprintf (info->origination_date, sizeof (info->origination_date), "%4d-%02d-%02d",
+       snprintf_bounded_null_filled (info->origination_date, sizeof (info->origination_date), "%4d-%02d-%02d",
                  _time.tm_year + 1900,
                  _time.tm_mon + 1,
                  _time.tm_mday);
        
-       snprintf (info->origination_time, sizeof (info->origination_time), "%02d:%02d:%02d",
+       snprintf_bounded_null_filled (info->origination_time, sizeof (info->origination_time), "%02d:%02d:%02d",
                  _time.tm_hour,
                  _time.tm_min,
                  _time.tm_sec);
@@ -219,11 +234,11 @@ BroadcastInfo::set_originator (string const & str)
        _has_info = true;
        
        if (!str.empty()) {
-               snprintf (info->originator, sizeof (info->originator), str.c_str());
+               snprintf_bounded_null_filled (info->originator, sizeof (info->originator), str.c_str());
                return;
        }
        
-       snprintf (info->originator, sizeof (info->originator), Glib::get_real_name().c_str());
+       snprintf_bounded_null_filled (info->originator, sizeof (info->originator), Glib::get_real_name().c_str());
 }
 
 void
@@ -232,7 +247,7 @@ BroadcastInfo::set_originator_ref (string const & str)
        _has_info = true;
        
        if (!str.empty()) {
-               snprintf (info->originator_reference, sizeof (info->originator_reference), str.c_str());
+               snprintf_bounded_null_filled (info->originator_reference, sizeof (info->originator_reference), str.c_str());
                return;
        }
        
@@ -245,7 +260,7 @@ BroadcastInfo::set_originator_ref (string const & str)
        std::ostringstream serial_number;
        serial_number << "ARDOUR" << "r" <<  std::setfill('0') << std::right << std::setw(5) << svn_revision;
        
-       snprintf (info->originator_reference, sizeof (info->originator_reference), "%2s%3s%12s%02d%02d%02d%9d",
+       snprintf_bounded_null_filled (info->originator_reference, sizeof (info->originator_reference), "%2s%3s%12s%02d%02d%02d%9d",
                  Config->get_bwf_country_code().c_str(),
                  Config->get_bwf_organization_code().c_str(),
                  serial_number.str().c_str(),
index ed63fb61327fa915627e7b2383eabbababe77d2b..097f0c235d16d41142af0229891b565f22fc3994 100644 (file)
@@ -48,21 +48,6 @@ const AudioFileSource::Flag SndFileSource::default_writable_flags = AudioFileSou
                                                                                           AudioFileSource::RemovableIfEmpty|
                                                                                           AudioFileSource::CanRename);
 
-static void
-snprintf_bounded_null_filled (char* target, size_t target_size, char* fmt, ...)
-{
-       char buf[target_size+1];
-       va_list ap;
-
-       va_start (ap, fmt);
-       vsnprintf (buf, target_size+1, fmt, ap);
-       va_end (ap);
-
-       memset (target, 0, target_size);
-       memcpy (target, buf, target_size);
-
-}
-
 SndFileSource::SndFileSource (Session& s, const XMLNode& node)
        : AudioFileSource (s, node)
 {
@@ -156,35 +141,22 @@ SndFileSource::SndFileSource (Session& s, ustring path, SampleFormat sfmt, Heade
 
        if (writable() && (_flags & Broadcast)) {
 
-               _broadcast_info = new SF_BROADCAST_INFO;
-               memset (_broadcast_info, 0, sizeof (*_broadcast_info));
-               
-               snprintf_bounded_null_filled (_broadcast_info->description, sizeof (_broadcast_info->description), "BWF %s", _name.c_str());
-               snprintf_bounded_null_filled (_broadcast_info->originator, sizeof (_broadcast_info->originator), "ardour %d.%d.%d %s", 
-                                             libardour3_major_version,
-                                             libardour3_minor_version,
-                                             libardour3_micro_version,
-                                             Glib::get_real_name().c_str());
-
-               _broadcast_info->version = 1;  
-               _broadcast_info->time_reference_low = 0;  
-               _broadcast_info->time_reference_high = 0;  
-               
-               /* XXX do something about this field */
-               
-               snprintf_bounded_null_filled (_broadcast_info->umid, sizeof (_broadcast_info->umid), "%s", "fnord");
-               
-               /* coding history is added by libsndfile */
+               if (!_broadcast_info) {
+                       _broadcast_info = new BroadcastInfo;
+               }
 
-               if (sf_command (sf, SFC_SET_BROADCAST_INFO, _broadcast_info, sizeof (_broadcast_info)) != SF_TRUE) {
-                       char errbuf[256];
-                       sf_error_str (0, errbuf, sizeof (errbuf) - 1);
-                       error << string_compose (_("cannot set broadcast info for audio file %1 (%2); dropping broadcast info for this file"), _path, errbuf) << endmsg;
+               _broadcast_info->set_from_session (s, header_position_offset);
+               _broadcast_info->set_description (string_compose ("BWF %1", _name));
+
+               if (!_broadcast_info->write_to_file (sf)) {
+                       error << string_compose (_("cannot set broadcast info for audio file %1 (%2); dropping broadcast info for this file"),
+                                                  _path, _broadcast_info->get_error())
+                             << endmsg;
                        _flags = Flag (_flags & ~Broadcast);
                        delete _broadcast_info;
                        _broadcast_info = 0;
-               } 
-       } 
+               }
+       }
 }
 
 void 
@@ -249,14 +221,15 @@ SndFileSource::open ()
 
        _length = _info.frames;
 
-       _broadcast_info = new SF_BROADCAST_INFO;
-       memset (_broadcast_info, 0, sizeof (*_broadcast_info));
+       if (!_broadcast_info) {
+               _broadcast_info = new BroadcastInfo;
+       }
        
-       bool timecode_info_exists;
+       bool bwf_info_exists = _broadcast_info->load_from_file (sf);
 
-       set_timeline_position (get_timecode_info (sf, _broadcast_info, timecode_info_exists));
+       set_timeline_position (bwf_info_exists ? _broadcast_info->get_time_reference() : header_position_offset);
 
-       if (_length != 0 && !timecode_info_exists) {
+       if (_length != 0 && !bwf_info_exists) {
                delete _broadcast_info;
                _broadcast_info = 0;
                _flags = Flag (_flags & ~Broadcast);
@@ -540,39 +513,20 @@ SndFileSource::setup_broadcast_info (nframes_t when, struct tm& now, time_t tnow
                return 0;
        }
 
-       /* random code is 9 digits */
-       
-       int random_code = random() % 999999999;
-
-       snprintf_bounded_null_filled (_broadcast_info->originator_reference, sizeof (_broadcast_info->originator_reference), "%2s%3s%12s%02d%02d%02d%9d",
-                                     Config->get_bwf_country_code().c_str(),
-                                     Config->get_bwf_organization_code().c_str(),
-                                     bwf_serial_number,
-                                     now.tm_hour,
-                                     now.tm_min,
-                                     now.tm_sec,
-                                     random_code);
-       
-       snprintf_bounded_null_filled (_broadcast_info->origination_date, sizeof (_broadcast_info->origination_date), "%4d-%02d-%02d",
-                                     1900 + now.tm_year,
-                                     now.tm_mon + 1, // shift range from 0..11 to 1..12
-                                     now.tm_mday);
-       
-       snprintf_bounded_null_filled (_broadcast_info->origination_time, sizeof (_broadcast_info->origination_time), "%02d:%02d:%02d",
-                                     now.tm_hour,
-                                     now.tm_min,
-                                     now.tm_sec);
+       _broadcast_info->set_originator_ref ();
+       _broadcast_info->set_origination_time (&now);
        
        /* now update header position taking header offset into account */
        
        set_header_timeline_position ();
 
-       if (sf_command (sf, SFC_SET_BROADCAST_INFO, _broadcast_info, sizeof (*_broadcast_info)) != SF_TRUE) {
-               error << string_compose (_("cannot set broadcast info for audio file %1; Dropping broadcast info for this file"), _path) << endmsg;
+       if (!_broadcast_info->write_to_file (sf)) {
+               error << string_compose (_("cannot set broadcast info for audio file %1 (%2); dropping broadcast info for this file"),
+                                          _path, _broadcast_info->get_error())
+                     << endmsg;
                _flags = Flag (_flags & ~Broadcast);
                delete _broadcast_info;
                _broadcast_info = 0;
-               return -1;
        }
 
        return 0;
@@ -585,11 +539,12 @@ SndFileSource::set_header_timeline_position ()
                return;
        }
 
-       _broadcast_info->time_reference_high = (timeline_position >> 32);
-       _broadcast_info->time_reference_low = (timeline_position & 0xffffffff);
+       _broadcast_info->set_time_reference (timeline_position);
 
-       if (sf_command (sf, SFC_SET_BROADCAST_INFO, _broadcast_info, sizeof (*_broadcast_info)) != SF_TRUE) {
-               error << string_compose (_("cannot set broadcast info for audio file %1; Dropping broadcast info for this file"), _path) << endmsg;
+       if (!_broadcast_info->write_to_file (sf)) {
+               error << string_compose (_("cannot set broadcast info for audio file %1 (%2); dropping broadcast info for this file"),
+                                          _path, _broadcast_info->get_error())
+                     << endmsg;
                _flags = Flag (_flags & ~Broadcast);
                delete _broadcast_info;
                _broadcast_info = 0;
@@ -853,8 +808,7 @@ SndFileSource::get_soundfile_info (const ustring& path, SoundFileInfo& info, str
 {
        SNDFILE *sf;
        SF_INFO sf_info;
-       SF_BROADCAST_INFO binfo;
-       bool timecode_exists;
+       BroadcastInfo binfo;
 
        sf_info.format = 0; // libsndfile says to clear this before sf_open().
 
@@ -871,37 +825,13 @@ SndFileSource::get_soundfile_info (const ustring& path, SoundFileInfo& info, str
                                           sndfile_major_format(sf_info.format),
                                           sndfile_minor_format(sf_info.format));
 
-       memset (&binfo, 0, sizeof (binfo));
-       info.timecode  = get_timecode_info (sf, &binfo, timecode_exists);
+       info.timecode = binfo.load_from_file (sf) ? binfo.get_time_reference() : 0;
 
-       if (!timecode_exists) {
-               info.timecode = 0;
-       }
-       
        sf_close (sf);
 
        return true;
 }
 
-int64_t
-SndFileSource::get_timecode_info (SNDFILE* sf, SF_BROADCAST_INFO* binfo, bool& exists)
-{
-       if (sf_command (sf, SFC_GET_BROADCAST_INFO, binfo, sizeof (*binfo)) != SF_TRUE) {
-               exists = false;
-               return (header_position_offset);
-       } 
-       
-       /* XXX 64 bit alert: when JACK switches to a 64 bit frame count, this needs to use the high bits
-          of the time reference.
-       */
-       
-       exists = true;
-       int64_t ret = (uint32_t) binfo->time_reference_high;
-       ret <<= 32;
-       ret |= (uint32_t) binfo->time_reference_low;
-       return ret;
-}
-
 bool
 SndFileSource::one_of_several_channels () const
 {