pulling trunk
[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 <glibmm.h>
57
58 #include <pbd/stl_delete.h>
59
60 #include <glibmm/thread.h>
61 #include <pbd/pathscanner.h>
62
63 #include <ardour/ardour.h>
64 #include <ardour/version.h>
65 #include <ardour/source.h>
66 #include <ardour/filesource.h>
67 #include <ardour/session.h>
68 #include <ardour/cycle_timer.h>
69 #include <ardour/pcm_utils.h>
70
71 #include "i18n.h"
72
73 using namespace ARDOUR;
74
75 string prepare_string(string& regex);
76
77 char   FileSource::bwf_country_code[3] = "us";
78 char   FileSource::bwf_organization_code[4] = "las";
79 char   FileSource::bwf_serial_number[13] = "000000000000";
80 string FileSource::search_path;
81
82 #undef WE_ARE_BIGENDIAN
83 #ifdef __BIG_ENDIAN__
84 #define WE_ARE_BIGENDIAN true
85 #else
86 #define WE_ARE_BIGENDIAN false
87 #endif
88
89 #define Swap_32(value)         \
90         (((((uint32_t)value)<<24) & 0xFF000000) | \
91          ((((uint32_t)value)<< 8) & 0x00FF0000) | \
92          ((((uint32_t)value)>> 8) & 0x0000FF00) | \
93          ((((uint32_t)value)>>24) & 0x000000FF))
94
95 #define Swap_16(value)         \
96         (((((uint16_t)value)>> 8) & 0x000000FF) | \
97          ((((uint16_t)value)<< 8) & 0x0000FF00))
98
99
100 void
101 FileSource::set_search_path (string p)
102 {
103         search_path = p;
104 }
105
106 FileSource::FileSource (string pathstr, jack_nframes_t rate, bool repair_first, SampleFormat samp_format)
107 {
108         /* constructor used when the file cannot already exist or might be damaged */
109         _sample_format = samp_format;
110         if (samp_format == FormatInt24) {
111                 _sample_size = 3;
112         } else {
113                 _sample_size = sizeof(float);
114         }
115         
116         if (repair_first && repair (pathstr, rate)) {
117                 throw failed_constructor ();
118         }
119         
120         if (init (pathstr, false, rate)) {
121                 throw failed_constructor ();
122         }
123
124         SourceCreated (this); /* EMIT SIGNAL */
125 }
126
127 FileSource::FileSource (const XMLNode& node, jack_nframes_t rate) 
128         : Source (node)
129 {
130         _sample_format = FormatFloat;
131         _sample_size = sizeof(float);
132
133         if (set_state (node)) {
134                 throw failed_constructor();
135         }
136
137         /* constructor used when the file must already exist */
138
139         if (init (_name, true, rate)) {
140                 throw failed_constructor ();
141         }
142
143         SourceCreated (this); /* EMIT SIGNAL */
144 }
145
146 int
147 FileSource::init (string pathstr, bool must_exist, jack_nframes_t rate)
148 {
149         bool new_file = false;
150         int ret = -1;
151         PathScanner scanner;
152
153         /* all native files end in .wav. this lets us discard
154            SndFileSource paths, which have ":N" at the end to
155            indicate which channel to read from, as well as any
156            other kind of non-native file. obviously, there
157            are more subtle checks later on.
158         */
159
160         if (pathstr.length() < 4 || pathstr.rfind (".wav") != pathstr.length() - 4) {
161                 return ret;
162         }
163
164         is_bwf = false;
165         _length = 0;
166         fd = -1;
167         remove_at_unref = false;
168         next_peak_clear_should_notify = false;
169         allow_remove_if_empty = true;
170
171         if (pathstr[0] != '/') {
172
173                 /* find pathstr in search path */
174                 
175                 if (search_path.length() == 0) {
176                         error << _("FileSource: search path not set") << endmsg;
177                         goto out;
178                 }
179
180                 /* force exact match on the filename component by prefixing the regexp.
181                    otherwise, "Drums-2.wav" matches "Comp_Drums-2.wav".
182                 */
183
184                 string regexp = "^";
185                 regexp += prepare_string(pathstr);
186                 regexp += '$';
187
188                 vector<string*>* result = scanner (search_path, regexp, false, true, -1);
189                 
190                 if (result == 0 || result->size() == 0) {
191                         error << string_compose (_("FileSource: \"%1\" not found when searching %2 using %3"), 
192                                           pathstr, search_path, regexp) << endmsg;
193                         goto out;
194                 }
195                 
196                 if (result->size() > 1) {
197                         string msg = string_compose (_("FileSource: \"%1\" is ambigous when searching %2\n\t"), pathstr, search_path);
198                         vector<string*>::iterator x = result->begin();
199
200                         while (true) {
201                                 msg += *(*x);
202                                 ++x;
203
204                                 if (x == result->end()) {
205                                         break;
206                                 }
207
208                                 msg += "\n\t";
209                         }
210                         
211                         error << msg << endmsg;
212                         goto out;
213                 }
214                 
215                 _name = pathstr;
216                 _path = *(result->front());
217
218                 vector_delete (result);
219                 delete result;
220
221         } else {
222
223                 /* old style sessions include full paths */
224
225                 _path = pathstr;
226                 _name = pathstr.substr (pathstr.find_last_of ('/') + 1);
227
228         }
229
230         if (access (_path.c_str(), F_OK) != 0) {
231                 if (must_exist) {
232                         error << string_compose(_("Filesource: cannot find required file (%1): %2"), _path, strerror (errno)) << endmsg;
233                         goto out;
234                         
235                 }
236
237                 if (errno == ENOENT) {
238                         new_file = true;
239                 } else {
240                         error << string_compose(_("Filesource: cannot check for existing file (%1): %2"), _path, strerror (errno)) << endmsg;
241                         goto out;
242                 }
243         }
244
245         if ((fd = open64 (_path.c_str(), O_RDWR|O_CREAT, 0644)) < 0) {
246                 error << string_compose(_("FileSource: could not open \"%1\": (%2)"), _path, strerror (errno)) << endmsg;
247                 goto out;
248         }
249         
250         /* if there was no timestamp available via XML,
251            then get it from the filesystem.
252         */
253
254         if (_timestamp == 0) {
255                 struct stat statbuf;
256                 
257                 fstat (fd, &statbuf);
258                 _timestamp = statbuf.st_mtime;
259         }
260
261         if (lseek (fd, 0, SEEK_END) == 0) {
262                 new_file = true;
263         }
264
265         /* check that its a RIFF/WAVE format file */
266         
267         if (new_file) {
268
269                 switch (Config->get_native_file_header_format()) {
270                 case BWF:
271                         is_bwf = true;
272                         break;
273                 default:
274                         is_bwf = false;
275                         break;
276                 }
277
278                 if (fill_header (rate)) {
279                         error << string_compose (_("FileSource: cannot write header in %1"), _path) << endmsg;
280                         goto out;
281                 }
282
283                 struct tm* now;
284                 time_t     xnow;
285                 
286                 time (&xnow);
287                 now = localtime (&xnow);
288
289                 update_header (0, *now, xnow);
290                 
291         } else {
292
293                 if (discover_chunks (must_exist)) {
294                         error << string_compose (_("FileSource: cannot locate chunks in %1"), _path) << endmsg;
295                         goto out;
296                 }
297                 
298                 if (read_header (must_exist)) {
299                         error << string_compose (_("FileSource: cannot read header in %1"), _path) << endmsg;
300                         goto out;
301                 }
302
303                 if (check_header (rate, must_exist)) {
304                         error << string_compose (_("FileSource: cannot check header in %1"), _path) << endmsg;
305                         goto out;
306                 }
307
308                 compute_header_size ();
309         }
310         
311         if ((ret = initialize_peakfile (new_file, _path))) {
312                 error << string_compose (_("FileSource: cannot initialize peakfile for %1 as %2"), _path, peakpath) << endmsg;
313         }
314
315   out:
316         if (ret) {
317
318                 if (fd >= 0) {
319                         close (fd);
320                 }
321
322                 if (new_file) {
323                         unlink (_path.c_str());
324                 }
325         }
326
327         return ret;
328
329 }
330
331 FileSource::~FileSource ()
332 {
333         GoingAway (this); /* EMIT SIGNAL */
334         
335         if (fd >= 0) {
336
337                 if (remove_at_unref || (is_empty (_path) && allow_remove_if_empty)) {
338                         unlink (_path.c_str());
339                         unlink (peakpath.c_str());
340                 }
341
342                 close (fd);
343         } 
344 }
345
346 void
347 FileSource::set_allow_remove_if_empty (bool yn)
348 {
349         allow_remove_if_empty = yn;
350 }
351
352 int
353 FileSource::set_name (string newname, bool destructive)
354 {
355         Glib::Mutex::Lock lm (_lock);
356         string oldpath = _path;
357         string newpath = Session::change_audio_path_by_name (oldpath, _name, newname, destructive);
358
359         if (newpath.empty()) {
360                 error << string_compose (_("programming error: %1"), "cannot generate a changed audio path") << endmsg;
361                 return -1;
362         }
363
364         if (rename (oldpath.c_str(), newpath.c_str()) != 0) {
365                 error << string_compose (_("cannot rename audio file for %1 to %2"), _name, newpath) << endmsg;
366                 return -1;
367         }
368
369         _name = Glib::path_get_basename (newpath);
370         _path = newpath;
371
372         return rename_peakfile (peak_path (_path));
373 }
374
375 string
376 FileSource::peak_path (string audio_path)
377 {
378         return Session::peak_path_from_audio_path (audio_path);
379 }
380
381 int
382 FileSource::discover_chunks (bool silent)
383 {
384         WAVEChunk rw;
385         off64_t end;
386         off64_t offset;
387         char null_terminated_id[5];
388         bool doswap = false;
389         
390         if ((end = lseek (fd, 0, SEEK_END)) < 0) {
391                 error << _("FileSource: cannot seek to end of file") << endmsg;
392                 return -1;
393         }
394
395         if (::pread64 (fd, &rw, sizeof (rw), 0) != sizeof (rw)) {
396                 error << _("FileSource: cannot read RIFF/WAVE chunk from file") << endmsg;
397                 return -1;
398         }
399
400         if (memcmp (rw.id, "RIFF", 4) == 0 && memcmp (rw.text, "WAVE", 4) == 0) {
401                 header.bigendian = false;
402         }
403         else if (memcmp(rw.id, "RIFX", 4) == 0 && memcmp (rw.text, "WAVE", 4) == 0) {
404                 header.bigendian = true;
405         }
406         else {
407                 if (!silent) {
408                         error << string_compose (_("FileSource %1: not a RIFF/WAVE file"), _path) << endmsg;
409                 }
410                 return -1;
411         }
412
413         null_terminated_id[4] = '\0';
414
415         /* OK, its a RIFF/WAVE file. Find each chunk */
416
417         doswap = header.bigendian != WE_ARE_BIGENDIAN;
418         
419         if (doswap) {
420                 swap_endian(rw);
421         }
422
423         
424         
425         memcpy (null_terminated_id, rw.id, 4);
426         chunk_info.push_back (ChunkInfo (null_terminated_id, rw.size, 0));
427
428         offset = sizeof (rw);
429
430         while (offset < end) {
431
432                 GenericChunk this_chunk;
433                 
434                 if (::pread64 (fd, &this_chunk, sizeof (this_chunk), offset) != sizeof (this_chunk)) {
435                         error << _("FileSource: can't read a chunk") << endmsg;
436                         return -1;
437                 }
438
439                 if (doswap) {
440                         swap_endian(this_chunk);
441                 }
442
443                 memcpy (null_terminated_id, this_chunk.id, 4);
444
445                 /* do sanity check and possible correction to legacy ardour RIFF wavs
446                    created on big endian platforms. after swapping, the size field will not be
447                    in range for the fmt chunk
448                 */
449                 if ((memcmp(null_terminated_id, "fmt ", 4) == 0 || memcmp(null_terminated_id, "bext", 4) == 0)
450                      && !header.bigendian && (this_chunk.size > 700 || this_chunk.size < 0))
451                 {
452                         warning << _("filesource: correcting mis-written RIFF file to become a RIFX: ") << name() << endmsg;
453                         
454                         memcpy (&rw.id, "RIFX", 4);
455                         ::pwrite64 (fd, &rw.id, 4, 0);
456                         header.bigendian = true;
457                         // fix wave chunk already read
458                         swap_endian(rw);
459                         
460                         doswap = header.bigendian != WE_ARE_BIGENDIAN;
461
462                         // now reset offset and continue the loop
463                         // to reread all the chunks
464                         chunk_info.clear();
465                         memcpy (null_terminated_id, rw.id, 4);
466                         chunk_info.push_back (ChunkInfo (null_terminated_id, rw.size, 0));
467                         offset = sizeof (rw);
468                         continue;
469                 }
470                                 
471
472                 if (end != 44)
473                         if ((memcmp(null_terminated_id, "data", 4) == 0))
474                                 if ((this_chunk.size == 0) || (this_chunk.size > (end - offset)))
475                                         this_chunk.size = end - offset;
476                 
477                 chunk_info.push_back (ChunkInfo (null_terminated_id, this_chunk.size, offset));
478
479                 /* skip to the next chunk */
480
481                 offset += sizeof(GenericChunk) + this_chunk.size;
482         }
483
484         return 0;
485 }
486
487 void
488 FileSource::swap_endian (GenericChunk & chunk) const
489 {
490         chunk.size = Swap_32(chunk.size);
491 }
492
493 void
494 FileSource::swap_endian (FMTChunk & chunk) const
495 {
496         chunk.size = Swap_32(chunk.size);
497
498         chunk.formatTag = Swap_16(chunk.formatTag);
499         chunk.nChannels = Swap_16(chunk.nChannels);
500         chunk.nSamplesPerSec = Swap_32(chunk.nSamplesPerSec);
501         chunk.nAvgBytesPerSec = Swap_32(chunk.nAvgBytesPerSec);
502         chunk.nBlockAlign = Swap_16(chunk.nBlockAlign);
503         chunk.nBitsPerSample = Swap_16(chunk.nBitsPerSample);
504 }
505
506 void
507 FileSource::swap_endian (BroadcastChunk & chunk) const
508 {
509         chunk.size = Swap_32(chunk.size);
510
511         chunk.time_reference_low = Swap_32(chunk.time_reference_low);
512         chunk.time_reference_high = Swap_32(chunk.time_reference_high);
513         chunk.version = Swap_16(chunk.version);
514 }
515
516 void FileSource::swap_endian (Sample *buf, jack_nframes_t cnt) const
517 {
518         for (jack_nframes_t n=0; n < cnt; ++n) {
519                 uint32_t * tmp = (uint32_t *) &buf[n];
520                 *tmp = Swap_32(*tmp);
521         }
522 }
523
524
525 FileSource::ChunkInfo*
526 FileSource::lookup_chunk (string what)
527 {
528         for (vector<ChunkInfo>::iterator i = chunk_info.begin(); i != chunk_info.end(); ++i) {
529                 if ((*i).name == what) {
530                         return &*i;
531                 }
532         }
533         return 0;
534 }
535
536 int
537 FileSource::fill_header (jack_nframes_t rate)
538 {
539         /* RIFF/WAVE */
540
541         if (WE_ARE_BIGENDIAN) {
542                 memcpy (header.wave.id, "RIFX", 4);
543                 header.bigendian = true;
544         }
545         else {
546                 memcpy (header.wave.id, "RIFF", 4);
547                 header.bigendian = false;
548         }
549         header.wave.size = 0; /* file size */
550         memcpy (header.wave.text, "WAVE", 4);
551
552         /* BROADCAST WAVE EXTENSION */
553         
554         if (is_bwf) {
555
556                 /* fill the entire BWF header with nulls */
557
558                 memset (&header.bext, 0, sizeof (header.bext));
559
560                 memcpy (header.bext.id, "bext", 4);
561
562                 snprintf (header.bext.description, sizeof (header.bext.description), "%s", "ambiguity is clearer than precision.");
563
564                 struct passwd *pwinfo;
565                 struct utsname utsinfo;
566
567                 if ((pwinfo = getpwuid (getuid())) == 0) {
568                         error << string_compose(_("FileSource: cannot get user information for BWF header (%1)"), strerror(errno)) << endmsg;
569                         return -1;
570                 }
571                 if (uname (&utsinfo)) {
572                         error << string_compose(_("FileSource: cannot get host information for BWF header (%1)"), strerror(errno)) << endmsg;
573                         return -1;
574                 }
575
576                 snprintf (header.bext.originator, sizeof (header.bext.originator), "ardour:%s:%s:%s:%s:%s)", 
577                           pwinfo->pw_gecos,
578                           utsinfo.nodename,
579                           utsinfo.sysname,
580                           utsinfo.release,
581                           utsinfo.version);
582
583                 header.bext.version = 1;  
584                 
585                 /* XXX do something about this field */
586
587                 snprintf (header.bext.umid, sizeof (header.bext.umid), "%s", "fnord");
588
589                 /* add some coding history */
590
591                 char buf[64];
592
593                 /* encode: PCM,rate,mono,24bit,ardour-version
594                    
595                    Note that because we use JACK, there is no way to tell
596                    what the original bit depth of the signal was.
597                  */
598                 
599                 snprintf (buf, sizeof(buf), "F=%u,A=PCM,M=mono,W=24,T=ardour-%d.%d.%d", 
600                           rate,
601                           libardour_major_version,
602                           libardour_minor_version,
603                           libardour_micro_version);
604
605                 header.coding_history.push_back (buf);
606
607                 /* initial size reflects coding history + "\r\n" */
608
609                 header.bext.size = sizeof (BroadcastChunk) - sizeof (GenericChunk) + strlen (buf) + 2;
610         }
611         
612         memcpy (header.format.id, "fmt ", 4);
613         header.format.size = sizeof (FMTChunk) - sizeof (GenericChunk);
614
615         if (_sample_format == FormatInt24) {
616                 header.format.formatTag = 1; // PCM
617                 header.format.nBlockAlign = 3;
618                 header.format.nBitsPerSample = 24;
619         }
620         else {
621                 header.format.formatTag = 3; /* little-endian IEEE float format */
622                 header.format.nBlockAlign = 4;
623                 header.format.nBitsPerSample = 32;
624         }
625         header.format.nChannels = 1; /* mono */
626         header.format.nSamplesPerSec = rate;
627         header.format.nAvgBytesPerSec = rate * _sample_size;
628         
629         /* DATA */
630
631         memcpy (header.data.id, "data", 4);
632         header.data.size = 0;
633         
634         return 0;
635 }
636
637 void
638 FileSource::compute_header_size ()
639 {
640         off64_t end_of_file;
641         int32_t coding_history_size = 0;
642                 
643         end_of_file = lseek (fd, 0, SEEK_END);
644
645         if (is_bwf) {
646                 
647                 /* include the coding history */
648                 
649                 for (vector<string>::iterator i = header.coding_history.begin(); i != header.coding_history.end(); ++i) {
650                         coding_history_size += (*i).length() + 2; // include "\r\n";
651                 }
652                 
653                 header.bext.size = sizeof (BroadcastChunk) - sizeof (GenericChunk) + coding_history_size;
654                 data_offset = bwf_header_size + coding_history_size;
655                 
656         } else {
657                 data_offset = wave_header_size;
658         }
659
660         if (end_of_file == 0) {
661
662                 /* newfile condition */
663                 
664                 if (is_bwf) {
665                         /* include "WAVE" then all the chunk sizes (bext, fmt, data) */ 
666                         header.wave.size = 4 + sizeof (BroadcastChunk) + coding_history_size + sizeof (FMTChunk) + sizeof (GenericChunk);
667                 } else {
668                         /* include "WAVE" then all the chunk sizes (fmt, data) */
669                         header.wave.size = 4 + sizeof (FMTChunk) + sizeof (GenericChunk);
670                 }
671
672                 header.data.size = 0;
673
674         } else {
675
676                 header.wave.size = end_of_file - 8; /* size of initial RIFF+size pseudo-chunk */
677                 header.data.size = end_of_file - data_offset;
678         }
679 }
680
681 int
682 FileSource::update_header (jack_nframes_t when, struct tm& now, time_t tnow)
683 {
684         Glib::Mutex::Lock lm (_lock);
685
686         if (is_bwf) {
687                 /* random code is 9 digits */
688
689                 int random_code = random() % 999999999;
690
691                 snprintf (header.bext.originator_reference, sizeof (header.bext.originator_reference), "%2s%3s%12s%02d%02d%02d%9d",
692                           bwf_country_code,
693                           bwf_organization_code,
694                           bwf_serial_number,
695                           now.tm_hour,
696                           now.tm_min,
697                           now.tm_sec,
698                           random_code);
699                           
700                 snprintf (header.bext.origination_date, sizeof (header.bext.origination_date), "%4d-%02d-%02d",
701                           1900 + now.tm_year,
702                           now.tm_mon,
703                           now.tm_mday);
704
705                 snprintf (header.bext.origination_time, sizeof (header.bext.origination_time), "%02d-%02d-%02d",
706                           now.tm_hour,
707                           now.tm_min,
708                           now.tm_sec);
709
710                 header.bext.time_reference_high = 0;
711                 header.bext.time_reference_low = when;
712         }
713
714         compute_header_size ();
715
716         if (write_header()) {
717                 error << string_compose(_("FileSource[%1]: cannot update data size: %2"), _path, strerror (errno)) << endmsg;
718                 return -1;
719         }
720
721         stamp (tnow);
722
723         return 0;
724 }
725
726 int
727 FileSource::read_header (bool silent)
728 {
729         /* we already have the chunk info, so just load up whatever we have */
730
731         ChunkInfo* info;
732         
733         if (header.bigendian == false && (info = lookup_chunk ("RIFF")) == 0) {
734                 error << _("FileSource: can't find RIFF chunk info") << endmsg;
735                 return -1;
736         }
737         else if (header.bigendian == true && (info = lookup_chunk ("RIFX")) == 0) {
738                 error << _("FileSource: can't find RIFX chunk info") << endmsg;
739                 return -1;
740         }
741         
742         
743         /* just fill this chunk/header ourselves, disk i/o is stupid */
744
745         if (header.bigendian) {
746                 memcpy (header.wave.id, "RIFX", 4);
747         }
748         else {
749                 memcpy (header.wave.id, "RIFF", 4);
750         }
751         header.wave.size = 0;
752         memcpy (header.wave.text, "WAVE", 4);
753
754         if ((info = lookup_chunk ("bext")) != 0) {
755
756                 is_bwf = true;
757                 
758                 if (::pread64 (fd, &header.bext, sizeof (header.bext), info->offset) != sizeof (header.bext)) {
759                         error << _("FileSource: can't read RIFF chunk") << endmsg;
760                         return -1;
761                 }
762
763                 if (read_broadcast_data (*info)) {
764                         return -1;
765                 }
766         }
767
768         if ((info = lookup_chunk ("fmt ")) == 0) {
769                 error << _("FileSource: can't find format chunk info") << endmsg;
770                 return -1;
771         }
772
773         if (::pread64 (fd, &header.format, sizeof (header.format), info->offset) != sizeof (header.format)) {
774                 error << _("FileSource: can't read format chunk") << endmsg;
775                 return -1;
776         }
777
778         if (header.bigendian != WE_ARE_BIGENDIAN) {
779                 swap_endian (header.format);
780         }
781         
782         if ((info = lookup_chunk ("data")) == 0) {
783                 error << _("FileSource: can't find data chunk info") << endmsg;
784                 return -1;
785         }
786
787         if (::pread64 (fd, &header.data, sizeof (header.data), info->offset) != sizeof (header.data)) {
788                 error << _("FileSource: can't read data chunk") << endmsg;
789                 return -1;
790         }
791
792         if (header.bigendian != WE_ARE_BIGENDIAN) {
793                 swap_endian (header.data);
794         }
795
796         return 0;
797 }
798
799 int
800 FileSource::read_broadcast_data (ChunkInfo& info)
801 {
802         int32_t coding_history_size;
803
804         if (::pread64 (fd, (char *) &header.bext, sizeof (header.bext), info.offset + sizeof (GenericChunk)) != sizeof (header.bext)) {
805                 error << string_compose(_("FileSource: cannot read Broadcast Wave data from existing audio file \"%1\" (%2)"),
806                                  _path, strerror (errno)) << endmsg;
807                 return -1;
808         }
809
810         if (header.bigendian != WE_ARE_BIGENDIAN) {
811                 swap_endian (header.bext);
812         }
813         
814         if (info.size > sizeof (header.bext)) {
815
816                 coding_history_size = info.size - (sizeof (header.bext) - sizeof (GenericChunk));
817                 
818                 char data[coding_history_size];
819                 
820                 if (::pread64 (fd, data, coding_history_size, info.offset + sizeof (BroadcastChunk)) != coding_history_size) {
821                         error << string_compose(_("FileSource: cannot read Broadcast Wave coding history from audio file \"%1\" (%2)"),
822                                          _path, strerror (errno)) << endmsg;
823                         return -1;
824                 }
825                 
826                 /* elements of the coding history are divided by \r\n */
827                 
828                 char *p = data;
829                 char *end = data + coding_history_size;
830                 string tmp;
831
832                 while (p < end) {
833                         if (*p == '\r' && (p+1) != end && *(p+1) == '\n') {
834                                 if (tmp.length()) {
835                                         header.coding_history.push_back (tmp);
836                                         tmp = "";
837                                 }
838                                 p += 2;
839                         } else {
840                                 tmp += *p;
841                                 p++;
842                         }
843                 }
844         }
845
846         return 0;
847 }
848
849 int
850 FileSource::check_header (jack_nframes_t rate, bool silent)
851 {
852         if (header.format.formatTag == 1 && header.format.nBitsPerSample == 24) {
853                 // 24 bit PCM
854                 _sample_format = FormatInt24;
855                 _sample_size = 3;
856         } else if (header.format.formatTag == 3) {
857                 /* IEEE float */                
858                 _sample_format = FormatFloat;
859                 _sample_size = 4;
860         }
861         else {
862                 if (!silent) {
863                         error << string_compose(_("FileSource \"%1\" does not use valid sample format.\n"   
864                                            "This is probably a programming error."), _path) << endmsg;
865                 }
866                 return -1;
867         }
868         
869         /* compute the apparent length of the data */
870
871         data_offset = 0;
872
873         for (vector<ChunkInfo>::iterator i = chunk_info.begin(); i != chunk_info.end();) {
874                 vector<ChunkInfo>::iterator n;
875
876                 n = i;
877                 ++n;
878
879                 if ((*i).name == "data") {
880
881                         data_offset = (*i).offset + sizeof (GenericChunk);
882
883                         if (n == chunk_info.end()) {
884                                 off64_t end_of_file;
885                                 end_of_file = lseek (fd, 0, SEEK_END);
886
887                                 _length = end_of_file - data_offset;
888
889                         } else {
890                                 _length = (*n).offset - data_offset;
891                         }
892
893                         _length /= sizeof (Sample);
894
895                         break;
896                 }
897                 
898                 i = n;
899         }
900
901         if (data_offset == 0) {
902                 error << string_compose(_("FileSource \"%1\" has no \"data\" chunk"), _path) << endmsg;
903                 return -1;
904         }
905
906         if (_length * sizeof (Sample) != (jack_nframes_t) header.data.size) {
907                 warning << string_compose(_("%1: data length in header (%2) differs from implicit size in file (%3)"),
908                                    _path, header.data.size, _length * sizeof (Sample)) << endmsg;
909         }
910
911 //      if ((jack_nframes_t) header.format.nSamplesPerSec != rate) {
912 //              warning << string_compose(_("\"%1\" has a sample rate of %2 instead of %3 as used by this session"),
913 //                                 _path, header.format.nSamplesPerSec, rate) << endmsg;
914 //      }
915
916         return 0;
917 }
918
919 float
920 FileSource::sample_rate () const
921 {
922         return header.format.nSamplesPerSec;
923 }
924
925 int
926 FileSource::write_header()
927 {
928         off64_t pos;
929
930         /* write RIFF/WAVE boilerplate */
931
932         pos = 0;
933
934         WAVEChunk wchunk = header.wave;
935  
936         if (header.bigendian != WE_ARE_BIGENDIAN) {
937                 swap_endian(wchunk);
938         }
939         
940         if (::pwrite64 (fd, (char *) &wchunk, sizeof (wchunk), pos) != sizeof (wchunk)) {
941                 error << string_compose(_("FileSource: cannot write WAVE chunk: %1"), strerror (errno)) << endmsg;
942                 return -1;
943         }
944         
945         pos += sizeof (header.wave);
946         
947         if (is_bwf) {
948
949                 /* write broadcast chunk data without copy history */
950
951                 BroadcastChunk bchunk = header.bext;
952                 if (header.bigendian != WE_ARE_BIGENDIAN) {
953                         swap_endian (bchunk);
954                 }
955                 
956                 if (::pwrite64 (fd, (char *) &bchunk, sizeof (bchunk), pos) != sizeof (bchunk)) {
957                         return -1;
958                 }
959
960                 pos += sizeof (header.bext);
961
962                 /* write copy history */
963
964                 for (vector<string>::iterator i = header.coding_history.begin(); i != header.coding_history.end(); ++i) {
965                         string x;
966                         
967                         x = *i;
968                         x += "\r\n";
969                         
970                         if (::pwrite64 (fd, x.c_str(), x.length(), pos) != (int32_t) x.length()) {
971                                 return -1;
972                         }
973                         
974                         pos += x.length();
975                 }
976         }
977
978         /* write fmt and data chunks */
979         FMTChunk fchunk = header.format;
980         if (header.bigendian != WE_ARE_BIGENDIAN) {
981                 swap_endian (fchunk);
982         }
983         
984         if (::pwrite64 (fd, (char *) &fchunk, sizeof (fchunk), pos) != sizeof (fchunk)) {
985                 error << string_compose(_("FileSource: cannot write format chunk: %1"), strerror (errno)) << endmsg;
986                 return -1;
987         }
988
989         pos += sizeof (header.format);
990
991         GenericChunk dchunk = header.data;
992         if (header.bigendian != WE_ARE_BIGENDIAN) {
993                 swap_endian (dchunk);
994         }
995  
996         if (::pwrite64 (fd, (char *) &dchunk, sizeof (dchunk), pos) != sizeof (dchunk)) {
997                 error << string_compose(_("FileSource: cannot data chunk: %1"), strerror (errno)) << endmsg;
998                 return -1;
999         }
1000
1001         return 0;
1002 }
1003
1004 void
1005 FileSource::mark_for_remove ()
1006 {
1007         remove_at_unref = true;
1008 }
1009
1010 jack_nframes_t
1011 FileSource::read (Sample *dst, jack_nframes_t start, jack_nframes_t cnt, char * workbuf) const
1012 {
1013         Glib::Mutex::Lock lm (_lock);
1014         return read_unlocked (dst, start, cnt, workbuf);
1015 }
1016
1017 jack_nframes_t
1018 FileSource::read_unlocked (Sample *dst, jack_nframes_t start, jack_nframes_t cnt, char * workbuf) const
1019 {
1020         jack_nframes_t file_cnt;
1021
1022         if (start > _length) {
1023
1024                 /* read starts beyond end of data, just memset to zero */
1025                 
1026                 file_cnt = 0;
1027
1028         } else if (start + cnt > _length) {
1029                 
1030                 /* read ends beyond end of data, read some, memset the rest */
1031                 
1032                 file_cnt = _length - start;
1033
1034         } else {
1035                 
1036                 /* read is entirely within data */
1037
1038                 file_cnt = cnt;
1039         }
1040
1041         if (file_cnt) {
1042                 if (file_read(dst, start, file_cnt, workbuf) != (ssize_t) file_cnt) {
1043                         return 0;
1044                 }
1045         }
1046
1047         if (file_cnt != cnt) {
1048                 jack_nframes_t delta = cnt - file_cnt;
1049                 memset (dst+file_cnt, 0, sizeof (Sample) * delta);
1050         }
1051         
1052         return cnt;
1053 }
1054
1055 jack_nframes_t
1056 FileSource::write (Sample *data, jack_nframes_t cnt, char * workbuf)
1057 {
1058         {
1059                 Glib::Mutex::Lock lm (_lock);
1060                 
1061                 jack_nframes_t oldlen;
1062                 int32_t frame_pos = _length;
1063                 
1064                 if (file_write(data, frame_pos, cnt, workbuf) != (ssize_t) cnt) {
1065                         return 0;
1066                 }
1067
1068                 oldlen = _length;
1069                 _length += cnt;
1070
1071                 if (_build_peakfiles) {
1072                         PeakBuildRecord *pbr = 0;
1073
1074                         if (pending_peak_builds.size()) {
1075                                 pbr = pending_peak_builds.back();
1076                         }
1077                         
1078                         if (pbr && pbr->frame + pbr->cnt == oldlen) {
1079                                 
1080                                 /* the last PBR extended to the start of the current write,
1081                                    so just extend it again.
1082                                 */
1083
1084                                 pbr->cnt += cnt;
1085                         } else {
1086                                 pending_peak_builds.push_back (new PeakBuildRecord (oldlen, cnt));
1087                         }
1088                         
1089                         _peaks_built = false;
1090                 }
1091
1092         }
1093
1094
1095         if (_build_peakfiles) {
1096                 queue_for_peaks (*this);
1097         }
1098
1099         return cnt;
1100 }
1101
1102 ssize_t
1103 FileSource::write_float(Sample *data, jack_nframes_t framepos, jack_nframes_t cnt, char * workbuf)
1104 {
1105         int32_t byte_cnt = cnt * _sample_size;
1106         int32_t byte_pos = data_offset + (framepos * _sample_size);
1107         ssize_t retval;
1108         
1109         if ((retval = ::pwrite64 (fd, (char *) data, byte_cnt, byte_pos)) != (ssize_t) byte_cnt) {
1110                 error << string_compose(_("FileSource: \"%1\" bad write (%2)"), _path, strerror (errno)) << endmsg;
1111                 if (retval > 0) {
1112                         return retval / _sample_size;
1113                 }
1114                 else {
1115                         return retval;
1116                 }
1117         }
1118
1119         _write_data_count = byte_cnt;
1120         
1121         return cnt;
1122 }
1123
1124 ssize_t
1125 FileSource::read_float (Sample *dst, jack_nframes_t start, jack_nframes_t cnt, char * workbuf) const
1126 {
1127         ssize_t nread;
1128         ssize_t byte_cnt = (ssize_t) cnt * sizeof (Sample);
1129         int readfd;
1130
1131         /* open, read, close */
1132
1133         if ((readfd = open64 (_path.c_str(), O_RDONLY)) < 0) {
1134                 error << string_compose(_("FileSource: could not open \"%1\": (%2)"), _path, strerror (errno)) << endmsg;
1135                 return 0;
1136         }
1137         
1138         nread = ::pread64 (readfd, (char *) dst, byte_cnt, data_offset + (start * _sample_size));
1139         close (readfd);
1140
1141         if (nread != byte_cnt) {
1142
1143                 cerr << "FileSource: \""
1144                      << _path
1145                      << "\" bad read at frame "
1146                      << start
1147                      << ", of "
1148                      << cnt
1149                      << " (bytes="
1150                      << byte_cnt
1151                      << ") frames [length = " << _length 
1152                      << " eor = " << start + cnt << "] ("
1153                      << strerror (errno)
1154                      << ") (read "
1155                      << nread / sizeof (Sample)
1156                      << " (bytes=" <<nread
1157                      << ")) pos was"
1158                      << data_offset
1159                      << '+'
1160                      << start << '*' << sizeof(Sample)
1161                      << " = " << data_offset + (start * sizeof(Sample))
1162                      << endl;
1163                 
1164                 if (nread > 0) {
1165                         return nread / _sample_size;
1166                 } else {
1167                         return nread;
1168                 }
1169         }
1170
1171         if (header.bigendian != WE_ARE_BIGENDIAN) {
1172                 swap_endian(dst, cnt);
1173         }
1174         
1175         _read_data_count = byte_cnt;
1176
1177         return cnt;
1178 }
1179
1180 ssize_t
1181 FileSource::write_pcm_24(Sample *data, jack_nframes_t framepos, jack_nframes_t cnt, char * workbuf)
1182 {
1183         int32_t byte_cnt = cnt * _sample_size;
1184         int32_t byte_pos = data_offset + (framepos * _sample_size);
1185         ssize_t retval;
1186         
1187         // convert to int24
1188         if (header.bigendian) {
1189                 pcm_f2bet_clip_array (data, workbuf, cnt);
1190         } else {
1191                 pcm_f2let_clip_array (data, workbuf, cnt);
1192         }
1193         
1194         if ((retval = ::pwrite64 (fd, (char *) workbuf, byte_cnt, byte_pos)) != (ssize_t) byte_cnt) {
1195                 error << string_compose(_("FileSource: \"%1\" bad write (%2)"), _path, strerror (errno)) << endmsg;
1196                 if (retval > 0) {
1197                         return retval / _sample_size;
1198                 }
1199                 else {
1200                         return retval;
1201                 }
1202         }
1203
1204         return (ssize_t) cnt;
1205 }
1206
1207 ssize_t
1208 FileSource::read_pcm_24 (Sample *dst, jack_nframes_t start, jack_nframes_t cnt, char * workbuf) const
1209 {
1210         ssize_t nread;
1211         ssize_t byte_cnt = (ssize_t) cnt * _sample_size;
1212         int readfd;
1213
1214         /* open, read, close */
1215
1216         if ((readfd = open64 (_path.c_str(), O_RDONLY)) < 0) {
1217                 error << string_compose(_("FileSource: could not open \"%1\": (%2)"), _path, strerror (errno)) << endmsg;
1218                 return 0;
1219         }
1220
1221         nread = ::pread64 (readfd, (char *) workbuf, byte_cnt, data_offset + (start * _sample_size));
1222         close (readfd);
1223
1224         if (nread != byte_cnt) {
1225
1226                 cerr << "May be OK - FileSource: \""
1227                      << _path
1228                      << "\" bad 24bit read at frame "
1229                      << start
1230                      << ", of "
1231                      << cnt
1232                      << " (bytes="
1233                      << byte_cnt
1234                      << ") frames [length = " << _length 
1235                      << " eor = " << start + cnt << "] ("
1236                      << strerror (errno)
1237                      << ") (read "
1238                      << nread / sizeof (Sample)
1239                      << " (bytes=" <<nread
1240                      << ")) pos was"
1241                      << data_offset
1242                      << '+'
1243                      << start << '*' << sizeof(Sample)
1244                      << " = " << data_offset + (start * sizeof(Sample))
1245                      << endl;
1246
1247                 if (nread > 0) {
1248                         return nread / _sample_size;
1249                 }
1250                 else {
1251                         return nread;
1252                 }
1253         }
1254
1255         // convert from 24bit->float
1256         
1257         if (header.bigendian) {
1258                 pcm_bet2f_array (workbuf, cnt, dst);
1259         } else {
1260                 pcm_let2f_array (workbuf, cnt, dst);
1261         }
1262         
1263         _read_data_count = byte_cnt;
1264
1265         return (ssize_t) cnt;
1266 }
1267
1268
1269 bool
1270 FileSource::is_empty (string path)
1271 {
1272         struct stat statbuf;
1273
1274         stat (path.c_str(), &statbuf);
1275         
1276         /* its a bit of a problem if an audio file happens
1277            to be a regular WAVE file with just enough data
1278            to match the size of an empty BWF. hmmm. not very
1279            likely however - that represents a duration of
1280            less than 1msec at typical sample rates.  
1281         */
1282
1283         /* NOTE: 698 bytes is the size of a BWF header structure *plus* our minimal coding history */
1284
1285         return (statbuf.st_size == 0 || statbuf.st_size == wave_header_size || statbuf.st_size == 698);
1286 }
1287
1288 void
1289 FileSource::mark_streaming_write_completed ()
1290 {
1291         Glib::Mutex::Lock lm (_lock);
1292
1293         next_peak_clear_should_notify = true;
1294
1295         if (_peaks_built || pending_peak_builds.empty()) {
1296                 _peaks_built = true;
1297                  PeaksReady (); /* EMIT SIGNAL */
1298         }
1299 }
1300
1301 void
1302 FileSource::mark_take (string id)
1303 {
1304         _take_id = id;
1305 }
1306
1307 int
1308 FileSource::move_to_trash (const string trash_dir_name)
1309 {
1310         string newpath;
1311
1312         /* don't move the file across filesystems, just
1313            stick it in the `trash_dir_name' directory
1314            on whichever filesystem it was already on.
1315         */
1316
1317         // XXX Portability
1318
1319         newpath = Glib::path_get_dirname (_path);
1320         newpath = Glib::path_get_dirname (newpath);
1321
1322         newpath += '/';
1323         newpath += trash_dir_name;
1324         newpath += '/';
1325         newpath += Glib::path_get_basename (_path);
1326
1327         if (access (newpath.c_str(), F_OK) == 0) {
1328
1329                 /* the new path already exists, try versioning */
1330                 
1331                 char buf[PATH_MAX+1];
1332                 int version = 1;
1333                 string newpath_v;
1334
1335                 snprintf (buf, sizeof (buf), "%s.%d", newpath.c_str(), version);
1336                 newpath_v = buf;
1337
1338                 while (access (newpath_v.c_str(), F_OK) == 0 && version < 999) {
1339                         snprintf (buf, sizeof (buf), "%s.%d", newpath.c_str(), ++version);
1340                         newpath_v = buf;
1341                 }
1342                 
1343                 if (version == 999) {
1344                         error << string_compose (_("there are already 1000 files with names like %1; versioning discontinued"),
1345                                           newpath)
1346                               << endmsg;
1347                 } else {
1348                         newpath = newpath_v;
1349                 }
1350
1351         } else {
1352
1353                 /* it doesn't exist, or we can't read it or something */
1354
1355         }
1356
1357         if (::rename (_path.c_str(), newpath.c_str()) != 0) {
1358                 error << string_compose (_("cannot rename audio file source from %1 to %2 (%3)"),
1359                                   _path, newpath, strerror (errno))
1360                       << endmsg;
1361                 return -1;
1362         }
1363
1364         if (::unlink (peakpath.c_str()) != 0) {
1365                 error << string_compose (_("cannot remove peakfile %1 for %2 (%3)"),
1366                                   peakpath, _path, strerror (errno))
1367                       << endmsg;
1368                 /* try to back out */
1369                 rename (newpath.c_str(), _path.c_str());
1370                 return -1;
1371         }
1372             
1373         _path = newpath;
1374         peakpath = "";
1375         remove_at_unref = false;
1376         
1377         return 0;
1378 }
1379
1380 string
1381 prepare_string(string& str)
1382 {
1383         string prepared;
1384         
1385         for (uint32_t i = 0; i < str.size(); ++i){
1386                 char c = str[i];
1387                 if (isdigit(c) || isalpha(c)){
1388                         prepared += c;
1389                 } else {
1390                         prepared += '\\';
1391                         prepared += c;
1392                 }
1393         }
1394
1395         return prepared;
1396 }
1397
1398 int
1399 FileSource::repair (string path, jack_nframes_t rate)
1400 {
1401         FILE* in;
1402         char buf[700];
1403         char* ptr;
1404         struct stat statbuf;
1405         size_t i;
1406         int ret = -1;
1407         bool bigend = false;
1408         bool doswap = false;
1409         
1410         if (stat (path.c_str(), &statbuf)) {
1411                 return -1;
1412         }
1413
1414         if (statbuf.st_size <= (off_t) sizeof (buf)) {
1415                 /* nothing was ever written to the file, so there is nothing
1416                    really to do.
1417                 */
1418                 return 0;
1419         }
1420
1421         if ((in = fopen (path.c_str(), "r+")) == NULL) {
1422                 return -1;
1423         }
1424
1425         if (fread (buf, sizeof (buf), 1, in) != 1) {
1426                 goto out;
1427         }
1428         
1429         if ((memcmp (&buf[0], "RIFF", 4) && memcmp (&buf[0], "RIFX", 4)) || memcmp (&buf[8], "WAVE", 4)) {
1430                 /* no header. too dangerous to proceed */
1431                 goto out;
1432         } 
1433
1434         if (memcmp (&buf[0], "RIFX", 4)==0) {
1435                 bigend = true;
1436         }
1437
1438         doswap = bigend != WE_ARE_BIGENDIAN;
1439         
1440         /* reset the size of the RIFF chunk header */
1441
1442         if (doswap) {
1443                 *((int32_t *)&buf[4]) = Swap_32((int32_t)(statbuf.st_size - 8));
1444         }
1445         else {
1446                 *((int32_t *)&buf[4]) = statbuf.st_size - 8;
1447         }
1448
1449         /* find data chunk and reset the size */
1450
1451         ptr = buf;
1452
1453         for (i = 0; i < sizeof (buf); ) {
1454
1455                 if (memcmp (ptr, "fmt ", 4) == 0) {
1456                         
1457                         FMTChunk fmt;
1458
1459                         memcpy (&fmt, ptr, sizeof (fmt));
1460                         if (doswap) {
1461                                 swap_endian(fmt);
1462                         }
1463                         
1464                         fmt.nSamplesPerSec = rate;
1465                         fmt.nAvgBytesPerSec = rate * 4;
1466                         
1467                         /* put it back */
1468                         if (doswap) {
1469                                 swap_endian(fmt);
1470                         }
1471
1472                         memcpy (ptr, &fmt, sizeof (fmt));
1473                         ptr += sizeof (fmt);
1474                         i += sizeof (fmt);
1475
1476                 } else if (memcmp (ptr, "data", 4) == 0) {
1477                         GenericChunk dchunk;
1478                         memcpy(&dchunk, ptr, sizeof(dchunk));
1479
1480                         if(doswap) {
1481                                 swap_endian(dchunk);
1482                         }
1483
1484                         dchunk.size = statbuf.st_size - i - 8;
1485
1486                         if (doswap) {
1487                                 swap_endian(dchunk);
1488                         }
1489                         memcpy (ptr, &dchunk, sizeof (dchunk));
1490                         break;
1491
1492                 } else {
1493                         ++ptr;
1494                         ++i;
1495                 }
1496         }
1497
1498         /* now flush it back to disk */
1499         
1500         rewind (in);
1501
1502         if (fwrite (buf, sizeof (buf), 1, in) != 1) {
1503                 goto out;
1504         }
1505
1506         ret = 0;
1507         fflush (in);
1508
1509   out:
1510         fclose (in);
1511         return ret;
1512 }
1513