X-Git-Url: https://main.carlh.net/gitweb/?a=blobdiff_plain;f=libs%2Fardour%2Fsndfilesource.cc;h=5936f6257027eb77256e2ec2138f89b6dd88ca5b;hb=dca612e82af4f89dad4f15454cbbb15694fa077c;hp=24a70f636be085987cb11987989d5f0c865ad51b;hpb=912da52a539981193941d8739fa6f103b5e406db;p=ardour.git diff --git a/libs/ardour/sndfilesource.cc b/libs/ardour/sndfilesource.cc index 24a70f636b..5936f62570 100644 --- a/libs/ardour/sndfilesource.cc +++ b/libs/ardour/sndfilesource.cc @@ -55,6 +55,7 @@ SndFileSource::SndFileSource (const XMLNode& node) } SndFileSource::SndFileSource (string idstr, Flag flags) + /* files created this way are never writable or removable */ : AudioFileSource (idstr, Flag (flags & ~(Writable|Removable|RemovableIfEmpty|RemoveAtDestroy))) { init (idstr); @@ -63,7 +64,7 @@ SndFileSource::SndFileSource (string idstr, Flag flags) throw failed_constructor (); } - if (_build_peakfiles) { + if (!(_flags & NoPeakFile) && _build_peakfiles) { if (initialize_peakfile (false, _path)) { sf_close (sf); sf = 0; @@ -155,6 +156,8 @@ SndFileSource::SndFileSource (string idstr, SampleFormat sfmt, HeaderFormat hf, utsinfo.version); _broadcast_info->version = 1; + _broadcast_info->time_reference_low = 0; + _broadcast_info->time_reference_high = 0; /* XXX do something about this field */ @@ -170,9 +173,10 @@ SndFileSource::SndFileSource (string idstr, SampleFormat sfmt, HeaderFormat hf, delete _broadcast_info; _broadcast_info = 0; } + } - if (_build_peakfiles) { + if (!(_flags & NoPeakFile) && _build_peakfiles) { if (initialize_peakfile (true, _path)) { sf_close (sf); sf = 0; @@ -180,13 +184,8 @@ SndFileSource::SndFileSource (string idstr, SampleFormat sfmt, HeaderFormat hf, } } - /* since SndFileSource's constructed with this constructor can be writable, make sure we update if the header info changes */ - - if (writable()) { - HeaderPositionOffsetChanged.connect (mem_fun (*this, &AudioFileSource::handle_header_position_change)); - } - AudioSourceCreated (this); /* EMIT SIGNAL */ + } void @@ -235,6 +234,32 @@ SndFileSource::open () _length = _info.frames; + + _broadcast_info = (SF_BROADCAST_INFO*) calloc (1, sizeof (SF_BROADCAST_INFO)); + + /* lookup broadcast info */ + + if (sf_command (sf, SFC_GET_BROADCAST_INFO, _broadcast_info, sizeof (*_broadcast_info)) != SF_TRUE) { + + /* if the file has data but no broadcast info, then clearly, there is no broadcast info */ + + if (_length) { + free (_broadcast_info); + _broadcast_info = 0; + _flags = Flag (_flags & ~Broadcast); + } + + set_timeline_position (header_position_offset); + + } else { + + /* XXX 64 bit alert: when JACK switches to a 64 bit frame count, this needs to use the high bits + of the time reference. + */ + + set_timeline_position ( _broadcast_info->time_reference_low ); + } + if (writable()) { sf_command (sf, SFC_SET_UPDATE_HEADER_AUTO, 0, SF_FALSE); } @@ -242,27 +267,21 @@ SndFileSource::open () return 0; } -void -SndFileSource::close () +SndFileSource::~SndFileSource () { + GoingAway (this); /* EMIT SIGNAL */ + if (sf) { sf_close (sf); sf = 0; } -} - -SndFileSource::~SndFileSource () -{ - GoingAway (this); /* EMIT SIGNAL */ - - close (); if (interleave_buf) { delete [] interleave_buf; } if (_broadcast_info) { - delete [] _broadcast_info; + delete _broadcast_info; } } @@ -404,27 +423,38 @@ SndFileSource::write_unlocked (Sample *data, jack_nframes_t cnt, char * workbuf) int SndFileSource::update_header (jack_nframes_t when, struct tm& now, time_t tnow) { - /* allow derived classes to override how this is done */ - set_timeline_position (when); if (_flags & Broadcast) { - /* this will flush the header implicitly */ - return setup_broadcast_info (when, now, tnow); - } else { - return flush_header (); - } + if (setup_broadcast_info (when, now, tnow)) { + return -1; + } + } + + return flush_header (); } int SndFileSource::flush_header () { + if (!writable() || (sf == 0)) { + return -1; + } + return (sf_command (sf, SFC_UPDATE_HEADER_NOW, 0, 0) != SF_TRUE); } int SndFileSource::setup_broadcast_info (jack_nframes_t when, struct tm& now, time_t tnow) { + if (!writable()) { + return -1; + } + + if (!(_flags & Broadcast)) { + return 0; + } + /* random code is 9 digits */ int random_code = random() % 999999999; @@ -443,7 +473,7 @@ SndFileSource::setup_broadcast_info (jack_nframes_t when, struct tm& now, time_t now.tm_mon, now.tm_mday); - snprintf (_broadcast_info->origination_time, sizeof (_broadcast_info->origination_time), "%02d-%02d-%02d", + snprintf (_broadcast_info->origination_time, sizeof (_broadcast_info->origination_time), "%02d:%02d:%02d", now.tm_hour, now.tm_min, now.tm_sec); @@ -452,12 +482,10 @@ SndFileSource::setup_broadcast_info (jack_nframes_t when, struct tm& now, time_t set_header_timeline_position (); - /* note that libsndfile flushes the header to disk when resetting the broadcast info */ - 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; _flags = Flag (_flags & ~Broadcast); - delete _broadcast_info; + free (_broadcast_info); _broadcast_info = 0; return -1; } @@ -468,29 +496,19 @@ SndFileSource::setup_broadcast_info (jack_nframes_t when, struct tm& now, time_t void SndFileSource::set_header_timeline_position () { - uint64_t pos; - - _broadcast_info->time_reference_high = 0; - - if (header_position_negative) { - - if (ULONG_LONG_MAX - header_position_offset < timeline_position) { - pos = ULONG_LONG_MAX; // impossible - } else { - pos = timeline_position + header_position_offset; - } + if (!(_flags & Broadcast)) { + return; + } - } else { + _broadcast_info->time_reference_high = (timeline_position >> 32); + _broadcast_info->time_reference_low = (timeline_position & 0xffffffff); - if (timeline_position < header_position_offset) { - pos = 0; - } else { - pos = timeline_position - header_position_offset; - } + 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; + _flags = Flag (_flags & ~Broadcast); + free (_broadcast_info); + _broadcast_info = 0; } - - _broadcast_info->time_reference_high = (pos >> 32); - _broadcast_info->time_reference_low = (pos & 0xffffffff); } jack_nframes_t @@ -507,3 +525,9 @@ SndFileSource::write_float (Sample* data, jack_nframes_t frame_pos, jack_nframes return cnt; } + +jack_nframes_t +SndFileSource::natural_position() const +{ + return timeline_position; +}