#include <pwd.h>
#include <sys/utsname.h>
+#include <sys/stat.h>
#include <glibmm/miscutils.h>
using namespace ARDOUR;
using namespace PBD;
-SndFileSource::SndFileSource (const XMLNode& node)
- : AudioFileSource (node)
+SndFileSource::SndFileSource (Session& s, const XMLNode& node)
+ : AudioFileSource (s, node)
{
init (_name);
if (open()) {
throw failed_constructor ();
}
-
- if (_build_peakfiles) {
- if (initialize_peakfile (false, _path)) {
- sf_close (sf);
- sf = 0;
- throw failed_constructor ();
- }
- }
-
- AudioSourceCreated (this); /* EMIT SIGNAL */
}
-SndFileSource::SndFileSource (string idstr, Flag flags)
+SndFileSource::SndFileSource (Session& s, string idstr, Flag flags)
/* files created this way are never writable or removable */
- : AudioFileSource (idstr, Flag (flags & ~(Writable|Removable|RemovableIfEmpty|RemoveAtDestroy)))
+ : AudioFileSource (s, idstr, Flag (flags & ~(Writable|Removable|RemovableIfEmpty|RemoveAtDestroy)))
{
init (idstr);
if (open()) {
throw failed_constructor ();
}
-
- if (!(_flags & NoPeakFile) && _build_peakfiles) {
- if (initialize_peakfile (false, _path)) {
- sf_close (sf);
- sf = 0;
- throw failed_constructor ();
- }
- }
-
-
- AudioSourceCreated (this); /* EMIT SIGNAL */
}
-SndFileSource::SndFileSource (string idstr, SampleFormat sfmt, HeaderFormat hf, jack_nframes_t rate, Flag flags)
- : AudioFileSource(idstr, flags, sfmt, hf)
+SndFileSource::SndFileSource (Session& s, string idstr, SampleFormat sfmt, HeaderFormat hf, nframes_t rate, Flag flags)
+ : AudioFileSource (s, idstr, flags, sfmt, hf)
{
int fmt = 0;
init (idstr);
+ /* this constructor is used to construct new files, not open
+ existing ones.
+ */
+
+ file_is_new = true;
+
switch (hf) {
case CAF:
fmt = SF_FORMAT_CAF;
utsinfo.version);
_broadcast_info->version = 1;
+ _broadcast_info->time_reference_low = 0;
+ _broadcast_info->time_reference_high = 0;
/* XXX do something about this field */
}
}
-
- if (!(_flags & NoPeakFile) && _build_peakfiles) {
- if (initialize_peakfile (true, _path)) {
- sf_close (sf);
- sf = 0;
- throw failed_constructor ();
- }
- }
-
- AudioSourceCreated (this); /* EMIT SIGNAL */
}
void
_length = _info.frames;
-
- _broadcast_info = (SF_BROADCAST_INFO*) calloc (1, sizeof (SF_BROADCAST_INFO));
+ _broadcast_info = new SF_BROADCAST_INFO;
+ memset (_broadcast_info, 0, sizeof (*_broadcast_info));
/* lookup broadcast info */
/* if the file has data but no broadcast info, then clearly, there is no broadcast info */
if (_length) {
- free (_broadcast_info);
+ delete _broadcast_info;
_broadcast_info = 0;
_flags = Flag (_flags & ~Broadcast);
}
- set_timeline_position (0);
+ 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);
+
+ set_timeline_position ( _broadcast_info->time_reference_low );
}
if (writable()) {
sf_command (sf, SFC_SET_UPDATE_HEADER_AUTO, 0, SF_FALSE);
-
- /* update header if header offset info changes */
-
- AudioFileSource::HeaderPositionOffsetChanged.connect (mem_fun (*this, &AudioFileSource::handle_header_position_change));
}
return 0;
SndFileSource::~SndFileSource ()
{
- GoingAway (this); /* EMIT SIGNAL */
+ GoingAway (); /* EMIT SIGNAL */
if (sf) {
sf_close (sf);
sf = 0;
+
+ /* stupid libsndfile updated the headers on close,
+ so touch the peakfile if it exists and has data
+ to make sure its time is as new as the audio
+ file.
+ */
+
+ touch_peakfile ();
}
if (interleave_buf) {
return _info.samplerate;
}
-jack_nframes_t
-SndFileSource::read_unlocked (Sample *dst, jack_nframes_t start, jack_nframes_t cnt, char * workbuf) const
+nframes_t
+SndFileSource::read_unlocked (Sample *dst, nframes_t start, nframes_t cnt) const
{
int32_t nread;
float *ptr;
uint32_t real_cnt;
- jack_nframes_t file_cnt;
+ nframes_t file_cnt;
if (start > _length) {
}
if (_info.channels == 1) {
- jack_nframes_t ret = sf_read_float (sf, dst, file_cnt);
+ nframes_t ret = sf_read_float (sf, dst, file_cnt);
_read_data_count = cnt * sizeof(float);
return ret;
}
}
if (file_cnt != cnt) {
- jack_nframes_t delta = cnt - file_cnt;
+ nframes_t delta = cnt - file_cnt;
memset (dst+file_cnt, 0, sizeof (Sample) * delta);
}
return nread;
}
-jack_nframes_t
-SndFileSource::write_unlocked (Sample *data, jack_nframes_t cnt, char * workbuf)
+nframes_t
+SndFileSource::write_unlocked (Sample *data, nframes_t cnt)
{
if (!writable()) {
return 0;
return 0;
}
- jack_nframes_t oldlen;
+ nframes_t oldlen;
int32_t frame_pos = _length;
if (write_float (data, frame_pos, cnt) != cnt) {
if (_build_peakfiles) {
- queue_for_peaks (*this);
+ queue_for_peaks (shared_from_this ());
}
_write_data_count = cnt;
}
int
-SndFileSource::update_header (jack_nframes_t when, struct tm& now, time_t tnow)
+SndFileSource::update_header (nframes_t when, struct tm& now, time_t tnow)
{
set_timeline_position (when);
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)
+SndFileSource::setup_broadcast_info (nframes_t when, struct tm& now, time_t tnow)
{
if (!writable()) {
return -1;
int random_code = random() % 999999999;
snprintf (_broadcast_info->originator_reference, sizeof (_broadcast_info->originator_reference), "%2s%3s%12s%02d%02d%02d%9d",
- bwf_country_code,
- bwf_organization_code,
+ 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_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);
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);
+ delete _broadcast_info;
_broadcast_info = 0;
return -1;
}
void
SndFileSource::set_header_timeline_position ()
{
- uint64_t pos;
-
if (!(_flags & Broadcast)) {
return;
}
- cerr << "timeline pos = " << timeline_position << " offset = " << header_position_offset << endl;
-
- _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;
- }
-
- } else {
-
- if (timeline_position < header_position_offset) {
- pos = 0;
- } else {
- pos = timeline_position - header_position_offset;
- }
- }
-
- _broadcast_info->time_reference_high = (pos >> 32);
- _broadcast_info->time_reference_low = (pos & 0xffffffff);
-
- cerr << "set binfo pos to " << _broadcast_info->time_reference_high << " + " << _broadcast_info->time_reference_low << endl;
+ _broadcast_info->time_reference_high = (timeline_position >> 32);
+ _broadcast_info->time_reference_low = (timeline_position & 0xffffffff);
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);
+ delete _broadcast_info;
_broadcast_info = 0;
}
+
+
+
}
-jack_nframes_t
-SndFileSource::write_float (Sample* data, jack_nframes_t frame_pos, jack_nframes_t cnt)
+nframes_t
+SndFileSource::write_float (Sample* data, nframes_t frame_pos, nframes_t cnt)
{
if (sf_seek (sf, frame_pos, SEEK_SET|SFM_WRITE) != frame_pos) {
error << string_compose (_("%1: cannot seek to %2"), _path, frame_pos) << endmsg;
return cnt;
}
+
+nframes_t
+SndFileSource::natural_position() const
+{
+ return timeline_position;
+}