2 Copyright (C) 2000 Paul Davis
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 2 of the License, or
7 (at your option) any later version.
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, write to the Free Software
16 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
23 /* This is is very hacky way to get pread and pwrite declarations.
24 First, include <features.h> so that we can avoid its #undef __USE_UNIX98.
25 Then define __USE_UNIX98, include <unistd.h>, and then undef it
26 again. If #define _XOPEN_SOURCE actually worked, I'd use that, but
27 despite claims in the header that it does, it doesn't.
29 features.h isn't available on osx and it compiles fine without it.
32 #ifdef HAVE_FEATURES_H
37 // #define _XOPEN_SOURCE 500
49 #include <sys/types.h>
52 #include <sys/utsname.h>
54 #include <cstdio> /* for rename(2) */
56 #include <pbd/stl_delete.h>
57 #include <pbd/basename.h>
58 #include <pbd/dirname.h>
59 #include <pbd/lockmonitor.h>
60 #include <pbd/pathscanner.h>
62 #include <ardour/ardour.h>
63 #include <ardour/version.h>
64 #include <ardour/source.h>
65 #include <ardour/filesource.h>
66 #include <ardour/session.h>
67 #include <ardour/cycle_timer.h>
71 using namespace ARDOUR;
73 string prepare_string(string& regex);
75 char FileSource::bwf_country_code[3] = "us";
76 char FileSource::bwf_organization_code[4] = "las";
77 char FileSource::bwf_serial_number[13] = "000000000000";
78 string FileSource::search_path;
80 #undef WE_ARE_BIGENDIAN
81 #ifdef WORDS_BIGENDIAN
82 #define WE_ARE_BIGENDIAN true
84 #define WE_ARE_BIGENDIAN false
87 #define Swap_32(value) \
88 (((((uint32_t)value)<<24) & 0xFF000000) | \
89 ((((uint32_t)value)<< 8) & 0x00FF0000) | \
90 ((((uint32_t)value)>> 8) & 0x0000FF00) | \
91 ((((uint32_t)value)>>24) & 0x000000FF))
93 #define Swap_16(value) \
94 (((((uint16_t)value)>> 8) & 0x000000FF) | \
95 ((((uint16_t)value)<< 8) & 0x0000FF00))
99 FileSource::set_search_path (string p)
104 FileSource::FileSource (string pathstr, jack_nframes_t rate, bool repair_first)
106 /* constructor used when the file cannot already exist or might be damaged */
108 if (repair_first && repair (pathstr, rate)) {
109 throw failed_constructor ();
112 if (init (pathstr, false, rate)) {
113 throw failed_constructor ();
116 SourceCreated (this); /* EMIT SIGNAL */
119 FileSource::FileSource (const XMLNode& node, jack_nframes_t rate)
122 if (set_state (node)) {
123 throw failed_constructor();
126 /* constructor used when the file must already exist */
128 if (init (_name, true, rate)) {
129 throw failed_constructor ();
132 SourceCreated (this); /* EMIT SIGNAL */
136 FileSource::init (string pathstr, bool must_exist, jack_nframes_t rate)
138 bool new_file = false;
142 /* all native files end in .wav. this lets us discard
143 SndFileSource paths, which have ":N" at the end to
144 indicate which channel to read from, as well as any
145 other kind of non-native file. obviously, there
146 are more subtle checks later on.
149 if (pathstr.length() < 4 || pathstr.rfind (".wav") != pathstr.length() - 4) {
156 remove_at_unref = false;
157 next_peak_clear_should_notify = false;
159 if (pathstr[0] != '/') {
161 /* find pathstr in search path */
163 if (search_path.length() == 0) {
164 error << _("FileSource: search path not set") << endmsg;
168 /* force exact match on the filename component by prefixing the regexp.
169 otherwise, "Drums-2.wav" matches "Comp_Drums-2.wav".
173 regexp += prepare_string(pathstr);
176 vector<string*>* result = scanner (search_path, regexp, false, true, -1);
178 if (result == 0 || result->size() == 0) {
179 error << string_compose (_("FileSource: \"%1\" not found when searching %2 using %3"),
180 pathstr, search_path, regexp) << endmsg;
184 if (result->size() > 1) {
185 string msg = string_compose (_("FileSource: \"%1\" is ambigous when searching %2\n\t"), pathstr, search_path);
186 vector<string*>::iterator x = result->begin();
192 if (x == result->end()) {
199 error << msg << endmsg;
204 _path = *(result->front());
206 vector_delete (result);
211 /* old style sessions include full paths */
214 _name = pathstr.substr (pathstr.find_last_of ('/') + 1);
218 if (access (_path.c_str(), F_OK) != 0) {
220 error << string_compose(_("Filesource: cannot find required file (%1): %2"), _path, strerror (errno)) << endmsg;
225 if (errno == ENOENT) {
228 error << string_compose(_("Filesource: cannot check for existing file (%1): %2"), _path, strerror (errno)) << endmsg;
233 if ((fd = open64 (_path.c_str(), O_RDWR|O_CREAT, 0644)) < 0) {
234 error << string_compose(_("FileSource: could not open \"%1\": (%2)"), _path, strerror (errno)) << endmsg;
238 /* if there was no timestamp available via XML,
239 then get it from the filesystem.
242 if (_timestamp == 0) {
245 fstat (fd, &statbuf);
246 _timestamp = statbuf.st_mtime;
249 if (lseek (fd, 0, SEEK_END) == 0) {
253 /* check that its a RIFF/WAVE format file */
257 is_bwf = Config->get_native_format_is_bwf ();
259 if (fill_header (rate)) {
260 error << string_compose (_("FileSource: cannot write header in %1"), _path) << endmsg;
268 now = localtime (&xnow);
270 update_header (0, *now, xnow);
274 if (discover_chunks (must_exist)) {
275 error << string_compose (_("FileSource: cannot locate chunks in %1"), _path) << endmsg;
279 if (read_header (must_exist)) {
280 error << string_compose (_("FileSource: cannot read header in %1"), _path) << endmsg;
284 if (check_header (rate, must_exist)) {
285 error << string_compose (_("FileSource: cannot check header in %1"), _path) << endmsg;
289 compute_header_size ();
292 if ((ret = initialize_peakfile (new_file, _path))) {
293 error << string_compose (_("FileSource: cannot initialize peakfile for %1"), _path) << endmsg;
304 unlink (_path.c_str());
312 FileSource::~FileSource ()
314 GoingAway (this); /* EMIT SIGNAL */
318 if (remove_at_unref || is_empty (_path)) {
319 unlink (_path.c_str());
320 unlink (peakpath.c_str());
328 FileSource::discover_chunks (bool silent)
333 char null_terminated_id[5];
336 if ((end = lseek (fd, 0, SEEK_END)) < 0) {
337 error << _("FileSource: cannot seek to end of file") << endmsg;
341 if (::pread64 (fd, &rw, sizeof (rw), 0) != sizeof (rw)) {
342 error << _("FileSource: cannot read RIFF/WAVE chunk from file") << endmsg;
346 if (memcmp (rw.id, "RIFF", 4) == 0 && memcmp (rw.text, "WAVE", 4) == 0) {
347 header.bigendian = false;
349 else if (memcmp(rw.id, "RIFX", 4) == 0 && memcmp (rw.text, "WAVE", 4) == 0) {
350 header.bigendian = true;
354 error << string_compose (_("FileSource %1: not a RIFF/WAVE file"), _path) << endmsg;
359 null_terminated_id[4] = '\0';
361 /* OK, its a RIFF/WAVE file. Find each chunk */
363 doswap = header.bigendian != WE_ARE_BIGENDIAN;
371 memcpy (null_terminated_id, rw.id, 4);
372 chunk_info.push_back (ChunkInfo (null_terminated_id, rw.size, 0));
374 offset = sizeof (rw);
376 while (offset < end) {
378 GenericChunk this_chunk;
380 if (::pread64 (fd, &this_chunk, sizeof (this_chunk), offset) != sizeof (this_chunk)) {
381 error << _("FileSource: can't read a chunk") << endmsg;
386 swap_endian(this_chunk);
389 memcpy (null_terminated_id, this_chunk.id, 4);
391 /* do sanity check and possible correction to legacy ardour RIFF wavs
392 created on big endian platforms. after swapping, the size field will not be
393 in range for the fmt chunk
395 if ((memcmp(null_terminated_id, "fmt ", 4) == 0 || memcmp(null_terminated_id, "bext", 4) == 0)
396 && !header.bigendian && (this_chunk.size > 700 || this_chunk.size < 0))
398 warning << _("filesource: correcting mis-written RIFF file to become a RIFX: ") << name() << endmsg;
400 memcpy (&rw.id, "RIFX", 4);
401 ::pwrite64 (fd, &rw.id, 4, 0);
402 header.bigendian = true;
403 // fix wave chunk already read
406 doswap = header.bigendian != WE_ARE_BIGENDIAN;
408 // now reset offset and continue the loop
409 // to reread all the chunks
411 memcpy (null_terminated_id, rw.id, 4);
412 chunk_info.push_back (ChunkInfo (null_terminated_id, rw.size, 0));
413 offset = sizeof (rw);
419 if ((memcmp(null_terminated_id, "data", 4) == 0))
420 if ((this_chunk.size == 0) || (this_chunk.size > (end - offset)))
421 this_chunk.size = end - offset;
423 chunk_info.push_back (ChunkInfo (null_terminated_id, this_chunk.size, offset));
425 /* skip to the next chunk */
427 offset += sizeof(GenericChunk) + this_chunk.size;
434 FileSource::swap_endian (GenericChunk & chunk) const
436 chunk.size = Swap_32(chunk.size);
440 FileSource::swap_endian (FMTChunk & chunk) const
442 chunk.size = Swap_32(chunk.size);
444 chunk.formatTag = Swap_16(chunk.formatTag);
445 chunk.nChannels = Swap_16(chunk.nChannels);
446 chunk.nSamplesPerSec = Swap_32(chunk.nSamplesPerSec);
447 chunk.nAvgBytesPerSec = Swap_32(chunk.nAvgBytesPerSec);
448 chunk.nBlockAlign = Swap_16(chunk.nBlockAlign);
449 chunk.nBitsPerSample = Swap_16(chunk.nBitsPerSample);
453 FileSource::swap_endian (BroadcastChunk & chunk) const
455 chunk.size = Swap_32(chunk.size);
457 chunk.time_reference_low = Swap_32(chunk.time_reference_low);
458 chunk.time_reference_high = Swap_32(chunk.time_reference_high);
459 chunk.version = Swap_16(chunk.version);
462 void FileSource::swap_endian (Sample *buf, jack_nframes_t cnt) const
464 for (jack_nframes_t n=0; n < cnt; ++n) {
465 uint32_t * tmp = (uint32_t *) &buf[n];
466 *tmp = Swap_32(*tmp);
471 FileSource::ChunkInfo*
472 FileSource::lookup_chunk (string what)
474 for (vector<ChunkInfo>::iterator i = chunk_info.begin(); i != chunk_info.end(); ++i) {
475 if ((*i).name == what) {
483 FileSource::fill_header (jack_nframes_t rate)
487 if (WE_ARE_BIGENDIAN) {
488 memcpy (header.wave.id, "RIFX", 4);
489 header.bigendian = true;
492 memcpy (header.wave.id, "RIFF", 4);
493 header.bigendian = false;
495 header.wave.size = 0; /* file size */
496 memcpy (header.wave.text, "WAVE", 4);
498 /* BROADCAST WAVE EXTENSION */
502 /* fill the entire BWF header with nulls */
504 memset (&header.bext, 0, sizeof (header.bext));
506 memcpy (header.bext.id, "bext", 4);
508 snprintf (header.bext.description, sizeof (header.bext.description), "%s", "ambiguity is clearer than precision.");
510 struct passwd *pwinfo;
511 struct utsname utsinfo;
513 if ((pwinfo = getpwuid (getuid())) == 0) {
514 error << string_compose(_("FileSource: cannot get user information for BWF header (%1)"), strerror(errno)) << endmsg;
517 if (uname (&utsinfo)) {
518 error << string_compose(_("FileSource: cannot get host information for BWF header (%1)"), strerror(errno)) << endmsg;
522 snprintf (header.bext.originator, sizeof (header.bext.originator), "ardour:%s:%s:%s:%s:%s)",
529 header.bext.version = 1;
531 /* XXX do something about this field */
533 snprintf (header.bext.umid, sizeof (header.bext.umid), "%s", "fnord");
535 /* add some coding history */
539 /* encode: PCM,rate,mono,24bit,ardour-version
541 Note that because we use JACK, there is no way to tell
542 what the original bit depth of the signal was.
545 snprintf (buf, sizeof(buf), "F=%u,A=PCM,M=mono,W=24,T=ardour-%d.%d.%d",
547 libardour_major_version,
548 libardour_minor_version,
549 libardour_micro_version);
551 header.coding_history.push_back (buf);
553 /* initial size reflects coding history + "\r\n" */
555 header.bext.size = sizeof (BroadcastChunk) - sizeof (GenericChunk) + strlen (buf) + 2;
558 memcpy (header.format.id, "fmt ", 4);
559 header.format.size = sizeof (FMTChunk) - sizeof (GenericChunk);
561 header.format.formatTag = 3; /* little-endian IEEE float format */
562 header.format.nChannels = 1; /* mono */
563 header.format.nSamplesPerSec = rate;
564 header.format.nAvgBytesPerSec = rate * sizeof (Sample);
565 header.format.nBlockAlign = 4;
566 header.format.nBitsPerSample = 32;
570 memcpy (header.data.id, "data", 4);
571 header.data.size = 0;
577 FileSource::compute_header_size ()
580 int32_t coding_history_size = 0;
582 end_of_file = lseek (fd, 0, SEEK_END);
586 /* include the coding history */
588 for (vector<string>::iterator i = header.coding_history.begin(); i != header.coding_history.end(); ++i) {
589 coding_history_size += (*i).length() + 2; // include "\r\n";
592 header.bext.size = sizeof (BroadcastChunk) - sizeof (GenericChunk) + coding_history_size;
593 data_offset = bwf_header_size + coding_history_size;
596 data_offset = wave_header_size;
599 if (end_of_file == 0) {
601 /* newfile condition */
604 /* include "WAVE" then all the chunk sizes (bext, fmt, data) */
605 header.wave.size = 4 + sizeof (BroadcastChunk) + coding_history_size + sizeof (FMTChunk) + sizeof (GenericChunk);
607 /* include "WAVE" then all the chunk sizes (fmt, data) */
608 header.wave.size = 4 + sizeof (FMTChunk) + sizeof (GenericChunk);
611 header.data.size = 0;
615 header.wave.size = end_of_file - 8; /* size of initial RIFF+size pseudo-chunk */
616 header.data.size = end_of_file - data_offset;
621 FileSource::update_header (jack_nframes_t when, struct tm& now, time_t tnow)
623 LockMonitor lm (_lock, __LINE__, __FILE__);
626 /* random code is 9 digits */
628 int random_code = random() % 999999999;
630 snprintf (header.bext.originator_reference, sizeof (header.bext.originator_reference), "%2s%3s%12s%02d%02d%02d%9d",
632 bwf_organization_code,
639 snprintf (header.bext.origination_date, sizeof (header.bext.origination_date), "%4d-%02d-%02d",
644 snprintf (header.bext.origination_time, sizeof (header.bext.origination_time), "%02d-%02d-%02d",
649 header.bext.time_reference_high = 0;
650 header.bext.time_reference_low = when;
653 compute_header_size ();
655 if (write_header()) {
656 error << string_compose(_("FileSource[%1]: cannot update data size: %2"), _path, strerror (errno)) << endmsg;
666 FileSource::read_header (bool silent)
668 /* we already have the chunk info, so just load up whatever we have */
672 if (header.bigendian == false && (info = lookup_chunk ("RIFF")) == 0) {
673 error << _("FileSource: can't find RIFF chunk info") << endmsg;
676 else if (header.bigendian == true && (info = lookup_chunk ("RIFX")) == 0) {
677 error << _("FileSource: can't find RIFX chunk info") << endmsg;
682 /* just fill this chunk/header ourselves, disk i/o is stupid */
684 if (header.bigendian) {
685 memcpy (header.wave.id, "RIFX", 4);
688 memcpy (header.wave.id, "RIFF", 4);
690 header.wave.size = 0;
691 memcpy (header.wave.text, "WAVE", 4);
693 if ((info = lookup_chunk ("bext")) != 0) {
697 if (::pread64 (fd, &header.bext, sizeof (header.bext), info->offset) != sizeof (header.bext)) {
698 error << _("FileSource: can't read RIFF chunk") << endmsg;
702 if (read_broadcast_data (*info)) {
707 if ((info = lookup_chunk ("fmt ")) == 0) {
708 error << _("FileSource: can't find format chunk info") << endmsg;
712 if (::pread64 (fd, &header.format, sizeof (header.format), info->offset) != sizeof (header.format)) {
713 error << _("FileSource: can't read format chunk") << endmsg;
717 if (header.bigendian != WE_ARE_BIGENDIAN) {
718 swap_endian (header.format);
721 if ((info = lookup_chunk ("data")) == 0) {
722 error << _("FileSource: can't find data chunk info") << endmsg;
726 if (::pread (fd, &header.data, sizeof (header.data), info->offset) != sizeof (header.data)) {
727 error << _("FileSource: can't read data chunk") << endmsg;
731 if (header.bigendian != WE_ARE_BIGENDIAN) {
732 swap_endian (header.data);
739 FileSource::read_broadcast_data (ChunkInfo& info)
741 int32_t coding_history_size;
743 if (::pread (fd, (char *) &header.bext, sizeof (header.bext), info.offset + sizeof (GenericChunk)) != sizeof (header.bext)) {
744 error << string_compose(_("FileSource: cannot read Broadcast Wave data from existing audio file \"%1\" (%2)"),
745 _path, strerror (errno)) << endmsg;
749 if (header.bigendian != WE_ARE_BIGENDIAN) {
750 swap_endian (header.bext);
753 if (info.size > sizeof (header.bext)) {
755 coding_history_size = info.size - (sizeof (header.bext) - sizeof (GenericChunk));
757 char data[coding_history_size];
759 if (::pread (fd, data, coding_history_size, info.offset + sizeof (BroadcastChunk)) != coding_history_size) {
760 error << string_compose(_("FileSource: cannot read Broadcast Wave coding history from audio file \"%1\" (%2)"),
761 _path, strerror (errno)) << endmsg;
765 /* elements of the coding history are divided by \r\n */
768 char *end = data + coding_history_size;
772 if (*p == '\r' && (p+1) != end && *(p+1) == '\n') {
774 header.coding_history.push_back (tmp);
789 FileSource::check_header (jack_nframes_t rate, bool silent)
791 if (header.format.formatTag != 3) { /* IEEE float */
793 error << string_compose(_("FileSource \"%1\" does not use floating point format.\n"
794 "This is probably a programming error."), _path) << endmsg;
799 /* compute the apparent length of the data */
803 for (vector<ChunkInfo>::iterator i = chunk_info.begin(); i != chunk_info.end();) {
804 vector<ChunkInfo>::iterator n;
809 if ((*i).name == "data") {
811 data_offset = (*i).offset + sizeof (GenericChunk);
813 if (n == chunk_info.end()) {
815 end_of_file = lseek (fd, 0, SEEK_END);
817 _length = end_of_file - data_offset;
820 _length = (*n).offset - data_offset;
823 _length /= sizeof (Sample);
831 if (data_offset == 0) {
832 error << string_compose(_("FileSource \"%1\" has no \"data\" chunk"), _path) << endmsg;
836 if (_length * sizeof (Sample) != (jack_nframes_t) header.data.size) {
837 warning << string_compose(_("%1: data length in header (%2) differs from implicit size in file (%3)"),
838 _path, header.data.size, _length * sizeof (Sample)) << endmsg;
841 if ((jack_nframes_t) header.format.nSamplesPerSec != rate) {
842 warning << string_compose(_("\"%1\" has a sample rate of %2 instead of %3 as used by this session"),
843 _path, header.format.nSamplesPerSec, rate) << endmsg;
850 FileSource::write_header()
854 /* write RIFF/WAVE boilerplate */
858 WAVEChunk wchunk = header.wave;
860 if (header.bigendian != WE_ARE_BIGENDIAN) {
864 if (::pwrite64 (fd, (char *) &wchunk, sizeof (wchunk), pos) != sizeof (wchunk)) {
865 error << string_compose(_("FileSource: cannot write WAVE chunk: %1"), strerror (errno)) << endmsg;
869 pos += sizeof (header.wave);
873 /* write broadcast chunk data without copy history */
875 BroadcastChunk bchunk = header.bext;
876 if (header.bigendian != WE_ARE_BIGENDIAN) {
877 swap_endian (bchunk);
880 if (::pwrite64 (fd, (char *) &bchunk, sizeof (bchunk), pos) != sizeof (bchunk)) {
884 pos += sizeof (header.bext);
886 /* write copy history */
888 for (vector<string>::iterator i = header.coding_history.begin(); i != header.coding_history.end(); ++i) {
894 if (::pwrite64 (fd, x.c_str(), x.length(), pos) != (int32_t) x.length()) {
902 /* write fmt and data chunks */
903 FMTChunk fchunk = header.format;
904 if (header.bigendian != WE_ARE_BIGENDIAN) {
905 swap_endian (fchunk);
908 if (::pwrite64 (fd, (char *) &fchunk, sizeof (fchunk), pos) != sizeof (fchunk)) {
909 error << string_compose(_("FileSource: cannot write format chunk: %1"), strerror (errno)) << endmsg;
913 pos += sizeof (header.format);
915 GenericChunk dchunk = header.data;
916 if (header.bigendian != WE_ARE_BIGENDIAN) {
917 swap_endian (dchunk);
920 if (::pwrite64 (fd, (char *) &dchunk, sizeof (dchunk), pos) != sizeof (dchunk)) {
921 error << string_compose(_("FileSource: cannot data chunk: %1"), strerror (errno)) << endmsg;
929 FileSource::mark_for_remove ()
931 remove_at_unref = true;
935 FileSource::read (Sample *dst, jack_nframes_t start, jack_nframes_t cnt) const
937 LockMonitor lm (_lock, __LINE__, __FILE__);
938 return read_unlocked (dst, start, cnt);
942 FileSource::read_unlocked (Sample *dst, jack_nframes_t start, jack_nframes_t cnt) const
947 byte_cnt = cnt * sizeof (Sample);
949 if ((nread = pread (fd, (char *) dst, byte_cnt, data_offset + (start * sizeof (Sample)))) != (off64_t) byte_cnt) {
951 cerr << "FileSource: \""
953 << "\" bad read at frame "
959 << ") frames [length = " << _length
960 << " eor = " << start + cnt << "] ("
963 << nread / sizeof (Sample)
964 << " (bytes=" <<nread
968 << start << '*' << sizeof(Sample)
969 << " = " << data_offset + (start * sizeof(Sample))
975 if (header.bigendian != WE_ARE_BIGENDIAN) {
976 swap_endian(dst, cnt);
979 _read_data_count = byte_cnt;
985 FileSource::write (Sample *data, jack_nframes_t cnt)
988 LockMonitor lm (_lock, __LINE__, __FILE__);
990 int32_t byte_cnt = cnt * sizeof (Sample);
991 int32_t byte_pos = data_offset + (_length * sizeof (Sample));
992 jack_nframes_t oldlen;
994 if (::pwrite64 (fd, (char *) data, byte_cnt, byte_pos) != (off64_t) byte_cnt) {
995 error << string_compose(_("FileSource: \"%1\" bad write (%2)"), _path, strerror (errno)) << endmsg;
1001 _write_data_count = byte_cnt;
1003 if (_build_peakfiles) {
1004 PeakBuildRecord *pbr = 0;
1006 if (pending_peak_builds.size()) {
1007 pbr = pending_peak_builds.back();
1010 if (pbr && pbr->frame + pbr->cnt == oldlen) {
1012 /* the last PBR extended to the start of the current write,
1013 so just extend it again.
1018 pending_peak_builds.push_back (new PeakBuildRecord (oldlen, cnt));
1021 _peaks_built = false;
1027 if (_build_peakfiles) {
1028 queue_for_peaks (*this);
1035 FileSource::is_empty (string path)
1037 struct stat statbuf;
1039 stat (path.c_str(), &statbuf);
1041 /* its a bit of a problem if an audio file happens
1042 to be a regular WAVE file with just enough data
1043 to match the size of an empty BWF. hmmm. not very
1044 likely however - that represents a duration of
1045 less than 1msec at typical sample rates.
1048 /* NOTE: 700 bytes is the size of a BWF header structure *plus* our minimal coding history */
1050 return (statbuf.st_size == 0 || statbuf.st_size == wave_header_size || statbuf.st_size == 700);
1054 FileSource::mark_streaming_write_completed ()
1056 LockMonitor lm (_lock, __LINE__, __FILE__);
1058 next_peak_clear_should_notify = true;
1060 if (_peaks_built || pending_peak_builds.empty()) {
1061 _peaks_built = true;
1062 PeaksReady (); /* EMIT SIGNAL */
1067 FileSource::peak_path(string audio_path)
1069 return Session::peak_path_from_audio_path (audio_path);
1073 FileSource::old_peak_path(string audio_path)
1075 return Session::old_peak_path_from_audio_path (audio_path);
1079 FileSource::mark_take (string id)
1085 FileSource::move_to_trash (const string trash_dir_name)
1089 /* don't move the file across filesystems, just
1090 stick it in the `trash_dir_name' directory
1091 on whichever filesystem it was already on.
1094 newpath = PBD::dirname (_path);
1095 newpath = PBD::dirname (newpath);
1098 newpath += trash_dir_name;
1100 newpath += PBD::basename (_path);
1102 if (access (newpath.c_str(), F_OK) == 0) {
1104 /* the new path already exists, try versioning */
1106 char buf[PATH_MAX+1];
1110 snprintf (buf, sizeof (buf), "%s.%d", newpath.c_str(), version);
1113 while (access (newpath_v.c_str(), F_OK) == 0 && version < 999) {
1114 snprintf (buf, sizeof (buf), "%s.%d", newpath.c_str(), ++version);
1118 if (version == 999) {
1119 error << string_compose (_("there are already 1000 files with names like %1; versioning discontinued"),
1123 newpath = newpath_v;
1128 /* it doesn't exist, or we can't read it or something */
1132 if (::rename (_path.c_str(), newpath.c_str()) != 0) {
1133 error << string_compose (_("cannot rename audio file source from %1 to %2 (%3)"),
1134 _path, newpath, strerror (errno))
1139 if (::unlink (peakpath.c_str()) != 0) {
1140 error << string_compose (_("cannot remove peakfile %1 for %2 (%3)"),
1141 peakpath, _path, strerror (errno))
1143 /* try to back out */
1144 rename (newpath.c_str(), _path.c_str());
1150 remove_at_unref = false;
1156 prepare_string(string& str)
1160 for (uint32_t i = 0; i < str.size(); ++i){
1162 if (isdigit(c) || isalpha(c)){
1174 FileSource::repair (string path, jack_nframes_t rate)
1179 struct stat statbuf;
1182 bool bigend = false;
1183 bool doswap = false;
1185 if (stat (path.c_str(), &statbuf)) {
1189 if (statbuf.st_size <= (off_t) sizeof (buf)) {
1190 /* nothing was ever written to the file, so there is nothing
1196 if ((in = fopen (path.c_str(), "r+")) == NULL) {
1200 if (fread (buf, sizeof (buf), 1, in) != 1) {
1204 if (memcmp (&buf[0], "RIFF", 4) || memcmp (&buf[8], "WAVE", 4) || memcmp (&buf[0], "RIFX", 4)) {
1205 /* no header. too dangerous to proceed */
1209 if (memcmp (&buf[0], "RIFX", 4)==0) {
1213 doswap = bigend != WE_ARE_BIGENDIAN;
1215 /* reset the size of the RIFF chunk header */
1218 *((int32_t *)&buf[4]) = Swap_32((int32_t)(statbuf.st_size - 8));
1221 *((int32_t *)&buf[4]) = statbuf.st_size - 8;
1224 /* find data chunk and reset the size */
1228 for (i = 0; i < sizeof (buf); ) {
1230 if (memcmp (ptr, "fmt ", 4) == 0) {
1234 memcpy (&fmt, ptr, sizeof (fmt));
1239 fmt.nSamplesPerSec = rate;
1240 fmt.nAvgBytesPerSec = rate * 4;
1247 memcpy (ptr, &fmt, sizeof (fmt));
1248 ptr += sizeof (fmt);
1251 } else if (memcmp (ptr, "data", 4) == 0) {
1252 GenericChunk dchunk;
1253 memcpy(&dchunk, ptr, sizeof(dchunk));
1256 swap_endian(dchunk);
1259 dchunk.size = statbuf.st_size - i - 8;
1262 swap_endian(dchunk);
1264 memcpy (ptr, &dchunk, sizeof (dchunk));
1273 /* now flush it back to disk */
1277 if (fwrite (buf, sizeof (buf), 1, in) != 1) {