Use compiler provided __BIG_ENDIAN__ instead of WORD_BIGENDIAN
[ardour.git] / libs / ardour / filesource.cc
1 /*
2     Copyright (C) 2000 Paul Davis 
3
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.
8
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.
13
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.
17
18     $Id$
19 */
20
21 #include <algorithm>
22
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.
28
29    features.h isn't available on osx and it compiles fine without it.
30 */
31
32 #ifdef HAVE_FEATURES_H
33 #include <features.h>
34 #endif
35
36 #if __GNUC__ >= 3
37 // #define _XOPEN_SOURCE 500
38 #include <unistd.h>
39 #else
40 #define __USE_UNIX98
41 #include <unistd.h>
42 #undef  __USE_UNIX98
43 #endif
44
45 #include <sys/stat.h>
46 #include <fcntl.h>
47 #include <climits>
48 #include <cerrno>
49 #include <sys/types.h>
50 #include <pwd.h>
51 #include <time.h>
52 #include <sys/utsname.h>
53 #include <vector>
54 #include <cstdio> /* for rename(2) */
55
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>
61
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>
68
69 #include "i18n.h"
70
71 using namespace ARDOUR;
72
73 string prepare_string(string& regex);
74
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;
79
80 #undef WE_ARE_BIGENDIAN
81 #ifdef __BIG_ENDIAN__
82 #define WE_ARE_BIGENDIAN true
83 #else
84 #define WE_ARE_BIGENDIAN false
85 #endif
86
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))
92
93 #define Swap_16(value)         \
94         (((((uint16_t)value)>> 8) & 0x000000FF) | \
95          ((((uint16_t)value)<< 8) & 0x0000FF00))
96
97
98 void
99 FileSource::set_search_path (string p)
100 {
101         search_path = p;
102 }
103
104 FileSource::FileSource (string pathstr, jack_nframes_t rate, bool repair_first)
105 {
106         /* constructor used when the file cannot already exist or might be damaged */
107
108         if (repair_first && repair (pathstr, rate)) {
109                 throw failed_constructor ();
110         }
111         
112         if (init (pathstr, false, rate)) {
113                 throw failed_constructor ();
114         }
115
116         SourceCreated (this); /* EMIT SIGNAL */
117 }
118
119 FileSource::FileSource (const XMLNode& node, jack_nframes_t rate) 
120         : Source (node)
121 {
122         if (set_state (node)) {
123                 throw failed_constructor();
124         }
125
126         /* constructor used when the file must already exist */
127
128         if (init (_name, true, rate)) {
129                 throw failed_constructor ();
130         }
131
132         SourceCreated (this); /* EMIT SIGNAL */
133 }
134
135 int
136 FileSource::init (string pathstr, bool must_exist, jack_nframes_t rate)
137 {
138         bool new_file = false;
139         int ret = -1;
140         PathScanner scanner;
141
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.
147         */
148
149         if (pathstr.length() < 4 || pathstr.rfind (".wav") != pathstr.length() - 4) {
150                 return ret;
151         }
152
153         is_bwf = false;
154         _length = 0;
155         fd = -1;
156         remove_at_unref = false;
157         next_peak_clear_should_notify = false;
158
159         if (pathstr[0] != '/') {
160
161                 /* find pathstr in search path */
162                 
163                 if (search_path.length() == 0) {
164                         error << _("FileSource: search path not set") << endmsg;
165                         goto out;
166                 }
167
168                 /* force exact match on the filename component by prefixing the regexp.
169                    otherwise, "Drums-2.wav" matches "Comp_Drums-2.wav".
170                 */
171
172                 string regexp = "^";
173                 regexp += prepare_string(pathstr);
174                 regexp += '$';
175
176                 vector<string*>* result = scanner (search_path, regexp, false, true, -1);
177                 
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;
181                         goto out;
182                 }
183                 
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();
187
188                         while (true) {
189                                 msg += *(*x);
190                                 ++x;
191
192                                 if (x == result->end()) {
193                                         break;
194                                 }
195
196                                 msg += "\n\t";
197                         }
198                         
199                         error << msg << endmsg;
200                         goto out;
201                 }
202                 
203                 _name = pathstr;
204                 _path = *(result->front());
205
206                 vector_delete (result);
207                 delete result;
208
209         } else {
210
211                 /* old style sessions include full paths */
212
213                 _path = pathstr;
214                 _name = pathstr.substr (pathstr.find_last_of ('/') + 1);
215
216         }
217
218         if (access (_path.c_str(), F_OK) != 0) {
219                 if (must_exist) {
220                         error << string_compose(_("Filesource: cannot find required file (%1): %2"), _path, strerror (errno)) << endmsg;
221                         goto out;
222                         
223                 }
224
225                 if (errno == ENOENT) {
226                         new_file = true;
227                 } else {
228                         error << string_compose(_("Filesource: cannot check for existing file (%1): %2"), _path, strerror (errno)) << endmsg;
229                         goto out;
230                 }
231         }
232
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;
235                 goto out;
236         }
237         
238         /* if there was no timestamp available via XML,
239            then get it from the filesystem.
240         */
241
242         if (_timestamp == 0) {
243                 struct stat statbuf;
244                 
245                 fstat (fd, &statbuf);
246                 _timestamp = statbuf.st_mtime;
247         }
248
249         if (lseek (fd, 0, SEEK_END) == 0) {
250                 new_file = true;
251         }
252
253         /* check that its a RIFF/WAVE format file */
254         
255         if (new_file) {
256
257                 is_bwf = Config->get_native_format_is_bwf ();
258
259                 if (fill_header (rate)) {
260                         error << string_compose (_("FileSource: cannot write header in %1"), _path) << endmsg;
261                         goto out;
262                 }
263
264                 struct tm* now;
265                 time_t     xnow;
266                 
267                 time (&xnow);
268                 now = localtime (&xnow);
269
270                 update_header (0, *now, xnow);
271                 
272         } else {
273
274                 if (discover_chunks (must_exist)) {
275                         error << string_compose (_("FileSource: cannot locate chunks in %1"), _path) << endmsg;
276                         goto out;
277                 }
278                 
279                 if (read_header (must_exist)) {
280                         error << string_compose (_("FileSource: cannot read header in %1"), _path) << endmsg;
281                         goto out;
282                 }
283
284                 if (check_header (rate, must_exist)) {
285                         error << string_compose (_("FileSource: cannot check header in %1"), _path) << endmsg;
286                         goto out;
287                 }
288
289                 compute_header_size ();
290         }
291         
292         if ((ret = initialize_peakfile (new_file, _path))) {
293                 error << string_compose (_("FileSource: cannot initialize peakfile for %1"), _path) << endmsg;
294         }
295
296   out:
297         if (ret) {
298
299                 if (fd >= 0) {
300                         close (fd);
301                 }
302
303                 if (new_file) {
304                         unlink (_path.c_str());
305                 }
306         }
307
308         return ret;
309
310 }
311
312 FileSource::~FileSource ()
313 {
314         GoingAway (this); /* EMIT SIGNAL */
315         
316         if (fd >= 0) {
317
318                 if (remove_at_unref || is_empty (_path)) {
319                         unlink (_path.c_str());
320                         unlink (peakpath.c_str());
321                 }
322
323                 close (fd);
324         } 
325 }
326
327 int
328 FileSource::discover_chunks (bool silent)
329 {
330         WAVEChunk rw;
331         off64_t end;
332         off64_t offset;
333         char null_terminated_id[5];
334         bool doswap = false;
335         
336         if ((end = lseek (fd, 0, SEEK_END)) < 0) {
337                 error << _("FileSource: cannot seek to end of file") << endmsg;
338                 return -1;
339         }
340
341         if (::pread64 (fd, &rw, sizeof (rw), 0) != sizeof (rw)) {
342                 error << _("FileSource: cannot read RIFF/WAVE chunk from file") << endmsg;
343                 return -1;
344         }
345
346         if (memcmp (rw.id, "RIFF", 4) == 0 && memcmp (rw.text, "WAVE", 4) == 0) {
347                 header.bigendian = false;
348         }
349         else if (memcmp(rw.id, "RIFX", 4) == 0 && memcmp (rw.text, "WAVE", 4) == 0) {
350                 header.bigendian = true;
351         }
352         else {
353                 if (!silent) {
354                         error << string_compose (_("FileSource %1: not a RIFF/WAVE file"), _path) << endmsg;
355                 }
356                 return -1;
357         }
358
359         null_terminated_id[4] = '\0';
360
361         /* OK, its a RIFF/WAVE file. Find each chunk */
362
363         doswap = header.bigendian != WE_ARE_BIGENDIAN;
364         
365         if (doswap) {
366                 swap_endian(rw);
367         }
368
369         
370         
371         memcpy (null_terminated_id, rw.id, 4);
372         chunk_info.push_back (ChunkInfo (null_terminated_id, rw.size, 0));
373
374         offset = sizeof (rw);
375
376         while (offset < end) {
377
378                 GenericChunk this_chunk;
379                 
380                 if (::pread64 (fd, &this_chunk, sizeof (this_chunk), offset) != sizeof (this_chunk)) {
381                         error << _("FileSource: can't read a chunk") << endmsg;
382                         return -1;
383                 }
384
385                 if (doswap) {
386                         swap_endian(this_chunk);
387                 }
388
389                 memcpy (null_terminated_id, this_chunk.id, 4);
390
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
394                 */
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))
397                 {
398                         warning << _("filesource: correcting mis-written RIFF file to become a RIFX: ") << name() << endmsg;
399                         
400                         memcpy (&rw.id, "RIFX", 4);
401                         ::pwrite64 (fd, &rw.id, 4, 0);
402                         header.bigendian = true;
403                         // fix wave chunk already read
404                         swap_endian(rw);
405                         
406                         doswap = header.bigendian != WE_ARE_BIGENDIAN;
407
408                         // now reset offset and continue the loop
409                         // to reread all the chunks
410                         chunk_info.clear();
411                         memcpy (null_terminated_id, rw.id, 4);
412                         chunk_info.push_back (ChunkInfo (null_terminated_id, rw.size, 0));
413                         offset = sizeof (rw);
414                         continue;
415                 }
416                                 
417
418                 if (end != 44)
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;
422                 
423                 chunk_info.push_back (ChunkInfo (null_terminated_id, this_chunk.size, offset));
424
425                 /* skip to the next chunk */
426
427                 offset += sizeof(GenericChunk) + this_chunk.size;
428         }
429
430         return 0;
431 }
432
433 void
434 FileSource::swap_endian (GenericChunk & chunk) const
435 {
436         chunk.size = Swap_32(chunk.size);
437 }
438
439 void
440 FileSource::swap_endian (FMTChunk & chunk) const
441 {
442         chunk.size = Swap_32(chunk.size);
443
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);
450 }
451
452 void
453 FileSource::swap_endian (BroadcastChunk & chunk) const
454 {
455         chunk.size = Swap_32(chunk.size);
456
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);
460 }
461
462 void FileSource::swap_endian (Sample *buf, jack_nframes_t cnt) const
463 {
464         for (jack_nframes_t n=0; n < cnt; ++n) {
465                 uint32_t * tmp = (uint32_t *) &buf[n];
466                 *tmp = Swap_32(*tmp);
467         }
468 }
469
470
471 FileSource::ChunkInfo*
472 FileSource::lookup_chunk (string what)
473 {
474         for (vector<ChunkInfo>::iterator i = chunk_info.begin(); i != chunk_info.end(); ++i) {
475                 if ((*i).name == what) {
476                         return &*i;
477                 }
478         }
479         return 0;
480 }
481
482 int
483 FileSource::fill_header (jack_nframes_t rate)
484 {
485         /* RIFF/WAVE */
486
487         if (WE_ARE_BIGENDIAN) {
488                 memcpy (header.wave.id, "RIFX", 4);
489                 header.bigendian = true;
490         }
491         else {
492                 memcpy (header.wave.id, "RIFF", 4);
493                 header.bigendian = false;
494         }
495         header.wave.size = 0; /* file size */
496         memcpy (header.wave.text, "WAVE", 4);
497
498         /* BROADCAST WAVE EXTENSION */
499         
500         if (is_bwf) {
501
502                 /* fill the entire BWF header with nulls */
503
504                 memset (&header.bext, 0, sizeof (header.bext));
505
506                 memcpy (header.bext.id, "bext", 4);
507
508                 snprintf (header.bext.description, sizeof (header.bext.description), "%s", "ambiguity is clearer than precision.");
509
510                 struct passwd *pwinfo;
511                 struct utsname utsinfo;
512
513                 if ((pwinfo = getpwuid (getuid())) == 0) {
514                         error << string_compose(_("FileSource: cannot get user information for BWF header (%1)"), strerror(errno)) << endmsg;
515                         return -1;
516                 }
517                 if (uname (&utsinfo)) {
518                         error << string_compose(_("FileSource: cannot get host information for BWF header (%1)"), strerror(errno)) << endmsg;
519                         return -1;
520                 }
521
522                 snprintf (header.bext.originator, sizeof (header.bext.originator), "ardour:%s:%s:%s:%s:%s)", 
523                           pwinfo->pw_gecos,
524                           utsinfo.nodename,
525                           utsinfo.sysname,
526                           utsinfo.release,
527                           utsinfo.version);
528
529                 header.bext.version = 1;  
530                 
531                 /* XXX do something about this field */
532
533                 snprintf (header.bext.umid, sizeof (header.bext.umid), "%s", "fnord");
534
535                 /* add some coding history */
536
537                 char buf[64];
538
539                 /* encode: PCM,rate,mono,24bit,ardour-version
540                    
541                    Note that because we use JACK, there is no way to tell
542                    what the original bit depth of the signal was.
543                  */
544                 
545                 snprintf (buf, sizeof(buf), "F=%u,A=PCM,M=mono,W=24,T=ardour-%d.%d.%d", 
546                           rate,
547                           libardour_major_version,
548                           libardour_minor_version,
549                           libardour_micro_version);
550
551                 header.coding_history.push_back (buf);
552
553                 /* initial size reflects coding history + "\r\n" */
554
555                 header.bext.size = sizeof (BroadcastChunk) - sizeof (GenericChunk) + strlen (buf) + 2;
556         }
557         
558         memcpy (header.format.id, "fmt ", 4);
559         header.format.size = sizeof (FMTChunk) - sizeof (GenericChunk);
560
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;
567         
568         /* DATA */
569
570         memcpy (header.data.id, "data", 4);
571         header.data.size = 0;
572         
573         return 0;
574 }
575
576 void
577 FileSource::compute_header_size ()
578 {
579         off64_t end_of_file;
580         int32_t coding_history_size = 0;
581                 
582         end_of_file = lseek (fd, 0, SEEK_END);
583
584         if (is_bwf) {
585                 
586                 /* include the coding history */
587                 
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";
590                 }
591                 
592                 header.bext.size = sizeof (BroadcastChunk) - sizeof (GenericChunk) + coding_history_size;
593                 data_offset = bwf_header_size + coding_history_size;
594                 
595         } else {
596                 data_offset = wave_header_size;
597         }
598
599         if (end_of_file == 0) {
600
601                 /* newfile condition */
602                 
603                 if (is_bwf) {
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);
606                 } else {
607                         /* include "WAVE" then all the chunk sizes (fmt, data) */
608                         header.wave.size = 4 + sizeof (FMTChunk) + sizeof (GenericChunk);
609                 }
610
611                 header.data.size = 0;
612
613         } else {
614
615                 header.wave.size = end_of_file - 8; /* size of initial RIFF+size pseudo-chunk */
616                 header.data.size = end_of_file - data_offset;
617         }
618 }
619
620 int
621 FileSource::update_header (jack_nframes_t when, struct tm& now, time_t tnow)
622 {
623         LockMonitor lm (_lock, __LINE__, __FILE__);
624
625         if (is_bwf) {
626                 /* random code is 9 digits */
627
628                 int random_code = random() % 999999999;
629
630                 snprintf (header.bext.originator_reference, sizeof (header.bext.originator_reference), "%2s%3s%12s%02d%02d%02d%9d",
631                           bwf_country_code,
632                           bwf_organization_code,
633                           bwf_serial_number,
634                           now.tm_hour,
635                           now.tm_min,
636                           now.tm_sec,
637                           random_code);
638                           
639                 snprintf (header.bext.origination_date, sizeof (header.bext.origination_date), "%4d-%02d-%02d",
640                           1900 + now.tm_year,
641                           now.tm_mon,
642                           now.tm_mday);
643
644                 snprintf (header.bext.origination_time, sizeof (header.bext.origination_time), "%02d-%02d-%02d",
645                           now.tm_hour,
646                           now.tm_min,
647                           now.tm_sec);
648
649                 header.bext.time_reference_high = 0;
650                 header.bext.time_reference_low = when;
651         }
652
653         compute_header_size ();
654
655         if (write_header()) {
656                 error << string_compose(_("FileSource[%1]: cannot update data size: %2"), _path, strerror (errno)) << endmsg;
657                 return -1;
658         }
659
660         stamp (tnow);
661
662         return 0;
663 }
664
665 int
666 FileSource::read_header (bool silent)
667 {
668         /* we already have the chunk info, so just load up whatever we have */
669
670         ChunkInfo* info;
671         
672         if (header.bigendian == false && (info = lookup_chunk ("RIFF")) == 0) {
673                 error << _("FileSource: can't find RIFF chunk info") << endmsg;
674                 return -1;
675         }
676         else if (header.bigendian == true && (info = lookup_chunk ("RIFX")) == 0) {
677                 error << _("FileSource: can't find RIFX chunk info") << endmsg;
678                 return -1;
679         }
680         
681         
682         /* just fill this chunk/header ourselves, disk i/o is stupid */
683
684         if (header.bigendian) {
685                 memcpy (header.wave.id, "RIFX", 4);
686         }
687         else {
688                 memcpy (header.wave.id, "RIFF", 4);
689         }
690         header.wave.size = 0;
691         memcpy (header.wave.text, "WAVE", 4);
692
693         if ((info = lookup_chunk ("bext")) != 0) {
694
695                 is_bwf = true;
696                 
697                 if (::pread64 (fd, &header.bext, sizeof (header.bext), info->offset) != sizeof (header.bext)) {
698                         error << _("FileSource: can't read RIFF chunk") << endmsg;
699                         return -1;
700                 }
701
702                 if (read_broadcast_data (*info)) {
703                         return -1;
704                 }
705         }
706
707         if ((info = lookup_chunk ("fmt ")) == 0) {
708                 error << _("FileSource: can't find format chunk info") << endmsg;
709                 return -1;
710         }
711
712         if (::pread64 (fd, &header.format, sizeof (header.format), info->offset) != sizeof (header.format)) {
713                 error << _("FileSource: can't read format chunk") << endmsg;
714                 return -1;
715         }
716
717         if (header.bigendian != WE_ARE_BIGENDIAN) {
718                 swap_endian (header.format);
719         }
720         
721         if ((info = lookup_chunk ("data")) == 0) {
722                 error << _("FileSource: can't find data chunk info") << endmsg;
723                 return -1;
724         }
725
726         if (::pread (fd, &header.data, sizeof (header.data), info->offset) != sizeof (header.data)) {
727                 error << _("FileSource: can't read data chunk") << endmsg;
728                 return -1;
729         }
730
731         if (header.bigendian != WE_ARE_BIGENDIAN) {
732                 swap_endian (header.data);
733         }
734
735         return 0;
736 }
737
738 int
739 FileSource::read_broadcast_data (ChunkInfo& info)
740 {
741         int32_t coding_history_size;
742
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;
746                 return -1;
747         }
748
749         if (header.bigendian != WE_ARE_BIGENDIAN) {
750                 swap_endian (header.bext);
751         }
752         
753         if (info.size > sizeof (header.bext)) {
754
755                 coding_history_size = info.size - (sizeof (header.bext) - sizeof (GenericChunk));
756                 
757                 char data[coding_history_size];
758                 
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;
762                         return -1;
763                 }
764                 
765                 /* elements of the coding history are divided by \r\n */
766                 
767                 char *p = data;
768                 char *end = data + coding_history_size;
769                 string tmp;
770
771                 while (p < end) {
772                         if (*p == '\r' && (p+1) != end && *(p+1) == '\n') {
773                                 if (tmp.length()) {
774                                         header.coding_history.push_back (tmp);
775                                         tmp = "";
776                                 }
777                                 p += 2;
778                         } else {
779                                 tmp += *p;
780                                 p++;
781                         }
782                 }
783         }
784
785         return 0;
786 }
787
788 int
789 FileSource::check_header (jack_nframes_t rate, bool silent)
790 {
791         if (header.format.formatTag != 3) { /* IEEE float */
792                 if (!silent) {
793                         error << string_compose(_("FileSource \"%1\" does not use floating point format.\n"   
794                                            "This is probably a programming error."), _path) << endmsg;
795                 }
796                 return -1;
797         }
798         
799         /* compute the apparent length of the data */
800
801         data_offset = 0;
802
803         for (vector<ChunkInfo>::iterator i = chunk_info.begin(); i != chunk_info.end();) {
804                 vector<ChunkInfo>::iterator n;
805
806                 n = i;
807                 ++n;
808
809                 if ((*i).name == "data") {
810
811                         data_offset = (*i).offset + sizeof (GenericChunk);
812
813                         if (n == chunk_info.end()) {
814                                 off64_t end_of_file;
815                                 end_of_file = lseek (fd, 0, SEEK_END);
816
817                                 _length = end_of_file - data_offset;
818
819                         } else {
820                                 _length = (*n).offset - data_offset;
821                         }
822
823                         _length /= sizeof (Sample);
824
825                         break;
826                 }
827                 
828                 i = n;
829         }
830
831         if (data_offset == 0) {
832                 error << string_compose(_("FileSource \"%1\" has no \"data\" chunk"), _path) << endmsg;
833                 return -1;
834         }
835
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;
839         }
840
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;
844         }
845
846         return 0;
847 }
848
849 int
850 FileSource::write_header()
851 {
852         off64_t pos;
853
854         /* write RIFF/WAVE boilerplate */
855
856         pos = 0;
857
858         WAVEChunk wchunk = header.wave;
859  
860         if (header.bigendian != WE_ARE_BIGENDIAN) {
861                 swap_endian(wchunk);
862         }
863         
864         if (::pwrite64 (fd, (char *) &wchunk, sizeof (wchunk), pos) != sizeof (wchunk)) {
865                 error << string_compose(_("FileSource: cannot write WAVE chunk: %1"), strerror (errno)) << endmsg;
866                 return -1;
867         }
868         
869         pos += sizeof (header.wave);
870         
871         if (is_bwf) {
872
873                 /* write broadcast chunk data without copy history */
874
875                 BroadcastChunk bchunk = header.bext;
876                 if (header.bigendian != WE_ARE_BIGENDIAN) {
877                         swap_endian (bchunk);
878                 }
879                 
880                 if (::pwrite64 (fd, (char *) &bchunk, sizeof (bchunk), pos) != sizeof (bchunk)) {
881                         return -1;
882                 }
883
884                 pos += sizeof (header.bext);
885
886                 /* write copy history */
887
888                 for (vector<string>::iterator i = header.coding_history.begin(); i != header.coding_history.end(); ++i) {
889                         string x;
890                         
891                         x = *i;
892                         x += "\r\n";
893                         
894                         if (::pwrite64 (fd, x.c_str(), x.length(), pos) != (int32_t) x.length()) {
895                                 return -1;
896                         }
897                         
898                         pos += x.length();
899                 }
900         }
901
902         /* write fmt and data chunks */
903         FMTChunk fchunk = header.format;
904         if (header.bigendian != WE_ARE_BIGENDIAN) {
905                 swap_endian (fchunk);
906         }
907         
908         if (::pwrite64 (fd, (char *) &fchunk, sizeof (fchunk), pos) != sizeof (fchunk)) {
909                 error << string_compose(_("FileSource: cannot write format chunk: %1"), strerror (errno)) << endmsg;
910                 return -1;
911         }
912
913         pos += sizeof (header.format);
914
915         GenericChunk dchunk = header.data;
916         if (header.bigendian != WE_ARE_BIGENDIAN) {
917                 swap_endian (dchunk);
918         }
919  
920         if (::pwrite64 (fd, (char *) &dchunk, sizeof (dchunk), pos) != sizeof (dchunk)) {
921                 error << string_compose(_("FileSource: cannot data chunk: %1"), strerror (errno)) << endmsg;
922                 return -1;
923         }
924
925         return 0;
926 }
927
928 void
929 FileSource::mark_for_remove ()
930 {
931         remove_at_unref = true;
932 }
933
934 jack_nframes_t
935 FileSource::read (Sample *dst, jack_nframes_t start, jack_nframes_t cnt) const
936 {
937         LockMonitor lm (_lock, __LINE__, __FILE__);
938         return read_unlocked (dst, start, cnt);
939 }
940
941 jack_nframes_t
942 FileSource::read_unlocked (Sample *dst, jack_nframes_t start, jack_nframes_t cnt) const
943 {
944         int32_t byte_cnt;
945         int nread;
946
947         byte_cnt = cnt * sizeof (Sample);
948
949         if ((nread = pread (fd, (char *) dst, byte_cnt, data_offset + (start * sizeof (Sample)))) != (off64_t) byte_cnt) {
950                 
951                 cerr << "FileSource: \""
952                      << _path
953                      << "\" bad read at frame "
954                      << start
955                      << ", of "
956                      << cnt
957                      << " (bytes="
958                      << byte_cnt
959                      << ") frames [length = " << _length 
960                      << " eor = " << start + cnt << "] ("
961                      << strerror (errno)
962                      << ") (read "
963                      << nread / sizeof (Sample)
964                      << " (bytes=" <<nread
965                      << ")) pos was"
966                      << data_offset
967                      << '+'
968                      << start << '*' << sizeof(Sample)
969                      << " = " << data_offset + (start * sizeof(Sample))
970                      << endl;
971                 
972                 return 0;
973         }
974
975         if (header.bigendian != WE_ARE_BIGENDIAN) {
976                 swap_endian(dst, cnt);
977         }
978         
979         _read_data_count = byte_cnt;
980                 
981         return cnt;
982 }
983
984 jack_nframes_t
985 FileSource::write (Sample *data, jack_nframes_t cnt)
986 {
987         {
988                 LockMonitor lm (_lock, __LINE__, __FILE__);
989                 
990                 int32_t byte_cnt = cnt * sizeof (Sample);
991                 int32_t byte_pos = data_offset + (_length * sizeof (Sample));
992                 jack_nframes_t oldlen;
993
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;
996                         return 0;
997                 }
998
999                 oldlen = _length;
1000                 _length += cnt;
1001                 _write_data_count = byte_cnt;
1002
1003                 if (_build_peakfiles) {
1004                         PeakBuildRecord *pbr = 0;
1005                         
1006                         if (pending_peak_builds.size()) {
1007                                 pbr = pending_peak_builds.back();
1008                         }
1009                         
1010                         if (pbr && pbr->frame + pbr->cnt == oldlen) {
1011                                 
1012                                 /* the last PBR extended to the start of the current write,
1013                                    so just extend it again.
1014                                 */
1015
1016                                 pbr->cnt += cnt;
1017                         } else {
1018                                 pending_peak_builds.push_back (new PeakBuildRecord (oldlen, cnt));
1019                         }
1020                         
1021                         _peaks_built = false;
1022                 }
1023
1024         }
1025
1026
1027         if (_build_peakfiles) {
1028                 queue_for_peaks (*this);
1029         }
1030
1031         return cnt;
1032 }
1033
1034 bool
1035 FileSource::is_empty (string path)
1036 {
1037         struct stat statbuf;
1038
1039         stat (path.c_str(), &statbuf);
1040         
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.  
1046         */
1047
1048         /* NOTE: 700 bytes is the size of a BWF header structure *plus* our minimal coding history */
1049
1050         return (statbuf.st_size == 0 || statbuf.st_size == wave_header_size || statbuf.st_size == 700);
1051 }
1052
1053 void
1054 FileSource::mark_streaming_write_completed ()
1055 {
1056         LockMonitor lm (_lock, __LINE__, __FILE__);
1057
1058         next_peak_clear_should_notify = true;
1059
1060         if (_peaks_built || pending_peak_builds.empty()) {
1061                 _peaks_built = true;
1062                  PeaksReady (); /* EMIT SIGNAL */
1063         }
1064 }
1065
1066 string
1067 FileSource::peak_path(string audio_path)
1068 {
1069         return Session::peak_path_from_audio_path (audio_path);
1070 }
1071
1072 string
1073 FileSource::old_peak_path(string audio_path)
1074 {
1075         return Session::old_peak_path_from_audio_path (audio_path);
1076 }
1077
1078 void
1079 FileSource::mark_take (string id)
1080 {
1081         _take_id = id;
1082 }
1083
1084 int
1085 FileSource::move_to_trash (const string trash_dir_name)
1086 {
1087         string newpath;
1088
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.
1092         */
1093
1094         newpath = PBD::dirname (_path);
1095         newpath = PBD::dirname (newpath);
1096
1097         newpath += '/';
1098         newpath += trash_dir_name;
1099         newpath += '/';
1100         newpath += PBD::basename (_path);
1101
1102         if (access (newpath.c_str(), F_OK) == 0) {
1103
1104                 /* the new path already exists, try versioning */
1105                 
1106                 char buf[PATH_MAX+1];
1107                 int version = 1;
1108                 string newpath_v;
1109
1110                 snprintf (buf, sizeof (buf), "%s.%d", newpath.c_str(), version);
1111                 newpath_v = buf;
1112
1113                 while (access (newpath_v.c_str(), F_OK) == 0 && version < 999) {
1114                         snprintf (buf, sizeof (buf), "%s.%d", newpath.c_str(), ++version);
1115                         newpath_v = buf;
1116                 }
1117                 
1118                 if (version == 999) {
1119                         error << string_compose (_("there are already 1000 files with names like %1; versioning discontinued"),
1120                                           newpath)
1121                               << endmsg;
1122                 } else {
1123                         newpath = newpath_v;
1124                 }
1125
1126         } else {
1127
1128                 /* it doesn't exist, or we can't read it or something */
1129
1130         }
1131
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))
1135                       << endmsg;
1136                 return -1;
1137         }
1138
1139         if (::unlink (peakpath.c_str()) != 0) {
1140                 error << string_compose (_("cannot remove peakfile %1 for %2 (%3)"),
1141                                   peakpath, _path, strerror (errno))
1142                       << endmsg;
1143                 /* try to back out */
1144                 rename (newpath.c_str(), _path.c_str());
1145                 return -1;
1146         }
1147             
1148         _path = newpath;
1149         peakpath = "";
1150         remove_at_unref = false;
1151         
1152         return 0;
1153 }
1154
1155 string
1156 prepare_string(string& str)
1157 {
1158         string prepared;
1159         
1160         for (uint32_t i = 0; i < str.size(); ++i){
1161                 char c = str[i];
1162                 if (isdigit(c) || isalpha(c)){
1163                         prepared += c;
1164                 } else {
1165                         prepared += '\\';
1166                         prepared += c;
1167                 }
1168         }
1169
1170         return prepared;
1171 }
1172
1173 int
1174 FileSource::repair (string path, jack_nframes_t rate)
1175 {
1176         FILE* in;
1177         char buf[700];
1178         char* ptr;
1179         struct stat statbuf;
1180         size_t i;
1181         int ret = -1;
1182         bool bigend = false;
1183         bool doswap = false;
1184         
1185         if (stat (path.c_str(), &statbuf)) {
1186                 return -1;
1187         }
1188
1189         if (statbuf.st_size <= (off_t) sizeof (buf)) {
1190                 /* nothing was ever written to the file, so there is nothing
1191                    really to do.
1192                 */
1193                 return 0;
1194         }
1195
1196         if ((in = fopen (path.c_str(), "r+")) == NULL) {
1197                 return -1;
1198         }
1199
1200         if (fread (buf, sizeof (buf), 1, in) != 1) {
1201                 goto out;
1202         }
1203         
1204         if (memcmp (&buf[0], "RIFF", 4) || memcmp (&buf[8], "WAVE", 4) || memcmp (&buf[0], "RIFX", 4)) {
1205                 /* no header. too dangerous to proceed */
1206                 goto out;
1207         } 
1208
1209         if (memcmp (&buf[0], "RIFX", 4)==0) {
1210                 bigend = true;
1211         }
1212
1213         doswap = bigend != WE_ARE_BIGENDIAN;
1214         
1215         /* reset the size of the RIFF chunk header */
1216
1217         if (doswap) {
1218                 *((int32_t *)&buf[4]) = Swap_32((int32_t)(statbuf.st_size - 8));
1219         }
1220         else {
1221                 *((int32_t *)&buf[4]) = statbuf.st_size - 8;
1222         }
1223
1224         /* find data chunk and reset the size */
1225
1226         ptr = buf;
1227
1228         for (i = 0; i < sizeof (buf); ) {
1229
1230                 if (memcmp (ptr, "fmt ", 4) == 0) {
1231                         
1232                         FMTChunk fmt;
1233
1234                         memcpy (&fmt, ptr, sizeof (fmt));
1235                         if (doswap) {
1236                                 swap_endian(fmt);
1237                         }
1238                         
1239                         fmt.nSamplesPerSec = rate;
1240                         fmt.nAvgBytesPerSec = rate * 4;
1241                         
1242                         /* put it back */
1243                         if (doswap) {
1244                                 swap_endian(fmt);
1245                         }
1246
1247                         memcpy (ptr, &fmt, sizeof (fmt));
1248                         ptr += sizeof (fmt);
1249                         i += sizeof (fmt);
1250
1251                 } else if (memcmp (ptr, "data", 4) == 0) {
1252                         GenericChunk dchunk;
1253                         memcpy(&dchunk, ptr, sizeof(dchunk));
1254
1255                         if(doswap) {
1256                                 swap_endian(dchunk);
1257                         }
1258
1259                         dchunk.size = statbuf.st_size - i - 8;
1260
1261                         if (doswap) {
1262                                 swap_endian(dchunk);
1263                         }
1264                         memcpy (ptr, &dchunk, sizeof (dchunk));
1265                         break;
1266
1267                 } else {
1268                         ++ptr;
1269                         ++i;
1270                 }
1271         }
1272
1273         /* now flush it back to disk */
1274         
1275         rewind (in);
1276
1277         if (fwrite (buf, sizeof (buf), 1, in) != 1) {
1278                 goto out;
1279         }
1280
1281         ret = 0;
1282         fflush (in);
1283
1284   out:
1285         fclose (in);
1286         return ret;
1287 }