Merge with trunk R2978.
[ardour.git] / libs / ardour / audiosource.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 */
19
20 #include <sys/stat.h>
21 #include <unistd.h>
22 #include <fcntl.h>
23 #include <poll.h>
24 #include <float.h>
25 #include <utime.h>
26 #include <cerrno>
27 #include <ctime>
28 #include <cmath>
29 #include <iomanip>
30 #include <fstream>
31 #include <algorithm>
32 #include <vector>
33
34 #include <glibmm/fileutils.h>
35 #include <glibmm/miscutils.h>
36
37 #include <pbd/xml++.h>
38 #include <pbd/pthread_utils.h>
39
40 #include <ardour/audiosource.h>
41 #include <ardour/cycle_timer.h>
42 #include <ardour/session.h>
43 #include <ardour/transient_detector.h>
44
45 #include "i18n.h"
46
47 using namespace std;
48 using namespace ARDOUR;
49 using namespace PBD;
50 using Glib::ustring;
51
52 bool AudioSource::_build_missing_peakfiles = false;
53 bool AudioSource::_build_peakfiles = false;
54
55 #define _FPP 256
56
57 AudioSource::AudioSource (Session& s, ustring name)
58         : Source (s, name, DataType::AUDIO)
59 {
60         _peaks_built = false;
61         _peak_byte_max = 0;
62         peakfile = -1;
63         _read_data_count = 0;
64         _write_data_count = 0;
65         peak_leftover_cnt = 0;
66         peak_leftover_size = 0;
67         peak_leftovers = 0;
68 }
69
70 AudioSource::AudioSource (Session& s, const XMLNode& node) 
71         : Source (s, node)
72 {
73         _peaks_built = false;
74         _peak_byte_max = 0;
75         peakfile = -1;
76         _read_data_count = 0;
77         _write_data_count = 0;
78         peak_leftover_cnt = 0;
79         peak_leftover_size = 0;
80         peak_leftovers = 0;
81
82         if (set_state (node)) {
83                 throw failed_constructor();
84         }
85 }
86
87 AudioSource::~AudioSource ()
88 {
89         /* shouldn't happen but make sure we don't leak file descriptors anyway */
90         
91         if (peak_leftover_cnt) {
92                 cerr << "AudioSource destroyed with leftover peak data pending" << endl;
93         }
94
95         if (peakfile >= 0) {
96                 ::close (peakfile);
97         }
98
99         if (peak_leftovers) {
100                 delete [] peak_leftovers;
101         }
102 }
103
104 XMLNode&
105 AudioSource::get_state ()
106 {
107         XMLNode& node (Source::get_state());
108
109         if (_captured_for.length()) {
110                 node.add_property ("captured-for", _captured_for);
111         }
112
113         return node;
114 }
115
116 int
117 AudioSource::set_state (const XMLNode& node)
118 {
119         const XMLProperty* prop;
120
121         Source::set_state (node);
122
123         if ((prop = node.property ("captured-for")) != 0) {
124                 _captured_for = prop->value();
125         }
126
127         return 0;
128 }
129
130 /***********************************************************************
131   PEAK FILE STUFF
132  ***********************************************************************/
133
134 bool
135 AudioSource::peaks_ready (sigc::slot<void> the_slot, sigc::connection& conn) const
136 {
137         bool ret;
138         Glib::Mutex::Lock lm (_peaks_ready_lock);
139
140         /* check to see if the peak data is ready. if not
141            connect the slot while still holding the lock.
142         */
143
144         if (!(ret = _peaks_built)) {
145                 conn = PeaksReady.connect (the_slot);
146         }
147
148         return ret;
149 }
150
151 void
152 AudioSource::touch_peakfile ()
153 {
154         struct stat statbuf;
155
156         if (stat (peakpath.c_str(), &statbuf) != 0 || statbuf.st_size == 0) {
157                 return;
158         }
159         
160         struct utimbuf tbuf;
161         
162         tbuf.actime = statbuf.st_atime;
163         tbuf.modtime = time ((time_t) 0);
164         
165         utime (peakpath.c_str(), &tbuf);
166 }
167
168 int
169 AudioSource::rename_peakfile (ustring newpath)
170 {
171         /* caller must hold _lock */
172
173         ustring oldpath = peakpath;
174
175         if (access (oldpath.c_str(), F_OK) == 0) {
176                 if (rename (oldpath.c_str(), newpath.c_str()) != 0) {
177                         error << string_compose (_("cannot rename peakfile for %1 from %2 to %3 (%4)"), _name, oldpath, newpath, strerror (errno)) << endmsg;
178                         return -1;
179                 }
180         }
181
182         peakpath = newpath;
183
184         return 0;
185 }
186
187 int
188 AudioSource::initialize_peakfile (bool newfile, ustring audio_path)
189 {
190         struct stat statbuf;
191
192         peakpath = peak_path (audio_path);
193
194         /* if the peak file should be there, but isn't .... */
195         
196         if (!newfile && !Glib::file_test (peakpath.c_str(), Glib::FILE_TEST_EXISTS)) {
197                 peakpath = find_broken_peakfile (peakpath, audio_path);
198         }
199
200         if (stat (peakpath.c_str(), &statbuf)) {
201                 if (errno != ENOENT) {
202                         /* it exists in the peaks dir, but there is some kind of error */
203                         
204                         error << string_compose(_("AudioSource: cannot stat peakfile \"%1\""), peakpath) << endmsg;
205                         return -1;
206                 }
207
208                 /* peakfile does not exist */
209                 
210                 _peaks_built = false;
211                 
212         } else {
213                 
214                 /* we found it in the peaks dir, so check it out */
215                 
216                 if (statbuf.st_size == 0) {
217                         // empty
218                         _peaks_built = false;
219                 } else {
220                         // Check if the audio file has changed since the peakfile was built.
221                         struct stat stat_file;
222                         int err = stat (audio_path.c_str(), &stat_file);
223                         
224                         if (!err && stat_file.st_mtime > statbuf.st_mtime){
225                                 _peaks_built = false;
226                                 _peak_byte_max = 0;
227                         } else {
228                                 _peaks_built = true;
229                                 _peak_byte_max = statbuf.st_size;
230                         }
231                 }
232         }
233
234         if (!newfile && !_peaks_built && _build_missing_peakfiles && _build_peakfiles) {
235                 build_peaks_from_scratch ();
236         } 
237         
238         return 0;
239 }
240
241 nframes_t
242 AudioSource::read (Sample *dst, nframes_t start, nframes_t cnt) const
243 {
244         Glib::Mutex::Lock lm (_lock);
245         return read_unlocked (dst, start, cnt);
246 }
247
248 nframes_t
249 AudioSource::write (Sample *dst, nframes_t cnt)
250 {
251         Glib::Mutex::Lock lm (_lock);
252         return write_unlocked (dst, cnt);
253 }
254
255 int
256 AudioSource::read_peaks (PeakData *peaks, nframes_t npeaks, nframes_t start, nframes_t cnt, double samples_per_visual_peak) const
257 {
258         return read_peaks_with_fpp (peaks, npeaks, start, cnt, samples_per_visual_peak, _FPP);
259 }
260
261 int 
262 AudioSource::read_peaks_with_fpp (PeakData *peaks, nframes_t npeaks, nframes_t start, nframes_t cnt, 
263                                   double samples_per_visual_peak, nframes_t samples_per_file_peak) const
264 {
265         Glib::Mutex::Lock lm (_lock);
266         double scale;
267         double expected_peaks;
268         PeakData::PeakDatum xmax;
269         PeakData::PeakDatum xmin;
270         int32_t to_read;
271         uint32_t nread;
272         nframes_t zero_fill = 0;
273         int ret = -1;
274         PeakData* staging = 0;
275         Sample* raw_staging = 0;
276         int _peakfile = -1;
277
278         expected_peaks = (cnt / (double) samples_per_file_peak);
279         scale = npeaks/expected_peaks;
280
281 #undef DEBUG_READ_PEAKS
282 #ifdef DEBUG_READ_PEAKS
283         cerr << "======>RP: npeaks = " << npeaks 
284              << " start = " << start 
285              << " cnt = " << cnt 
286              << " len = " << _length 
287              << "   samples_per_visual_peak =" << samples_per_visual_peak 
288              << " expected was " << expected_peaks << " ... scale = " << scale
289              << " PD ptr = " << peaks
290              <<endl;
291         
292 #endif
293
294         /* fix for near-end-of-file conditions */
295
296         if (cnt > _length - start) {
297                 // cerr << "too close to end @ " << _length << " given " << start << " + " << cnt << endl;
298                 cnt = _length - start;
299                 nframes_t old = npeaks;
300                 npeaks = min ((nframes_t) floor (cnt / samples_per_visual_peak), npeaks);
301                 zero_fill = old - npeaks;
302         }
303
304         // cerr << "actual npeaks = " << npeaks << " zf = " << zero_fill << endl;
305         
306         if (npeaks == cnt) {
307
308 #ifdef DEBUG_READ_PEAKS
309                 cerr << "RAW DATA\n";
310 #endif          
311                 /* no scaling at all, just get the sample data and duplicate it for
312                    both max and min peak values.
313                 */
314
315                 Sample* raw_staging = new Sample[cnt];
316                 
317                 if (read_unlocked (raw_staging, start, cnt) != cnt) {
318                         error << _("cannot read sample data for unscaled peak computation") << endmsg;
319                         return -1;
320                 }
321
322                 for (nframes_t i = 0; i < npeaks; ++i) {
323                         peaks[i].max = raw_staging[i];
324                         peaks[i].min = raw_staging[i];
325                 }
326
327                 delete [] raw_staging;
328                 return 0;
329         }
330
331         if (scale == 1.0) {
332
333                 off_t first_peak_byte = (start / samples_per_file_peak) * sizeof (PeakData);
334
335                 /* open, read, close */
336
337                 if ((_peakfile = ::open (peakpath.c_str(), O_RDONLY, 0664)) < 0) {
338                         error << string_compose(_("AudioSource: cannot open peakpath (a) \"%1\" (%2)"), peakpath, strerror (errno)) << endmsg;
339                         return -1;
340                 }
341
342 #ifdef DEBUG_READ_PEAKS
343                 cerr << "DIRECT PEAKS\n";
344 #endif
345                 
346                 nread = ::pread (_peakfile, peaks, sizeof (PeakData)* npeaks, first_peak_byte);
347                 close (_peakfile);
348
349                 if (nread != sizeof (PeakData) * npeaks) {
350                         cerr << "AudioSource["
351                              << _name
352                              << "]: cannot read peaks from peakfile! (read only " 
353                              << nread
354                              << " not " 
355                              << npeaks
356                               << "at sample " 
357                              << start
358                              << " = byte "
359                              << first_peak_byte
360                              << ')'
361                              << endl;
362                         return -1;
363                 }
364
365                 if (zero_fill) {
366                         memset (&peaks[npeaks], 0, sizeof (PeakData) * zero_fill);
367                 }
368
369                 return 0;
370         }
371
372
373         nframes_t tnp;
374
375         if (scale < 1.0) {
376
377 #ifdef DEBUG_READ_PEAKS
378                 cerr << "DOWNSAMPLE\n";
379 #endif          
380                 /* the caller wants:
381
382                     - more frames-per-peak (lower resolution) than the peakfile, or to put it another way,
383                     - less peaks than the peakfile holds for the same range
384
385                     So, read a block into a staging area, and then downsample from there.
386
387                     to avoid confusion, I'll refer to the requested peaks as visual_peaks and the peakfile peaks as stored_peaks  
388                 */
389
390                 const uint32_t chunksize = (uint32_t) min (expected_peaks, 65536.0);
391                 
392                 staging = new PeakData[chunksize];
393                 
394                 /* compute the rounded up frame position  */
395         
396                 nframes_t current_frame = start;
397                 nframes_t current_stored_peak = (nframes_t) ceil (current_frame / (double) samples_per_file_peak);
398                 uint32_t       next_visual_peak  = (uint32_t) ceil (current_frame / samples_per_visual_peak);
399                 double         next_visual_peak_frame = next_visual_peak * samples_per_visual_peak;
400                 uint32_t       stored_peak_before_next_visual_peak = (nframes_t) next_visual_peak_frame / samples_per_file_peak;
401                 uint32_t       nvisual_peaks = 0;
402                 uint32_t       stored_peaks_read = 0;
403                 uint32_t       i = 0;
404
405                 /* handle the case where the initial visual peak is on a pixel boundary */
406
407                 current_stored_peak = min (current_stored_peak, stored_peak_before_next_visual_peak);
408
409                 /* open ... close during out: handling */
410
411                 if ((_peakfile = ::open (peakpath.c_str(), O_RDONLY, 0664)) < 0) {
412                         error << string_compose(_("AudioSource: cannot open peakpath (b) \"%1\" (%2)"), peakpath, strerror (errno)) << endmsg;
413                         return 0;
414                 }
415
416                 while (nvisual_peaks < npeaks) {
417
418                         if (i == stored_peaks_read) {
419
420                                 uint32_t       start_byte = current_stored_peak * sizeof(PeakData);
421                                 tnp = min ((_length/samples_per_file_peak - current_stored_peak), (nframes_t) expected_peaks);
422                                 to_read = min (chunksize, tnp);
423                                 
424 #ifdef DEBUG_READ_PEAKS
425                                 cerr << "read " << sizeof (PeakData) * to_read << " from peakfile @ " << start_byte << endl;
426 #endif
427                                 
428                                 if ((nread = ::pread (_peakfile, staging, sizeof (PeakData) * to_read, start_byte))
429                                     != sizeof (PeakData) * to_read) {
430
431                                         off_t fend = lseek (_peakfile, 0, SEEK_END);
432                                         
433                                         cerr << "AudioSource["
434                                              << _name
435                                              << "]: cannot read peak data from peakfile ("
436                                              << (nread / sizeof(PeakData))
437                                              << " peaks instead of "
438                                              << to_read
439                                              << ") ("
440                                              << strerror (errno)
441                                              << ')'
442                                              << " at start_byte = " << start_byte 
443                                              << " _length = " << _length << " versus len = " << fend
444                                              << " expected maxpeaks = " << (_length - current_frame)/samples_per_file_peak
445                                              << " npeaks was " << npeaks
446                                              << endl;
447                                         goto out;
448                                 }
449                                 
450                                 i = 0;
451                                 stored_peaks_read = nread / sizeof(PeakData);
452                         }
453                         
454                         xmax = -1.0;
455                         xmin = 1.0;
456
457                         while ((i < stored_peaks_read) && (current_stored_peak <= stored_peak_before_next_visual_peak)) {
458
459                                 xmax = max (xmax, staging[i].max);
460                                 xmin = min (xmin, staging[i].min);
461                                 ++i;
462                                 ++current_stored_peak;
463                                 --expected_peaks;
464                         }
465
466                         peaks[nvisual_peaks].max = xmax;
467                         peaks[nvisual_peaks].min = xmin;
468                         ++nvisual_peaks;
469                         ++next_visual_peak;
470
471                         //next_visual_peak_frame = min ((next_visual_peak * samples_per_visual_peak), (next_visual_peak_frame+samples_per_visual_peak) );
472                         next_visual_peak_frame =  min ((double) start+cnt, (next_visual_peak_frame+samples_per_visual_peak) );
473                         stored_peak_before_next_visual_peak = (uint32_t) next_visual_peak_frame / samples_per_file_peak; 
474                 }
475
476                 if (zero_fill) {
477                         memset (&peaks[npeaks], 0, sizeof (PeakData) * zero_fill);
478                 }
479                 
480                 ret = 0;
481
482         } else {
483                 
484 #ifdef DEBUG_READ_PEAKS
485                 cerr << "UPSAMPLE\n";
486 #endif
487                 /* the caller wants 
488
489                      - less frames-per-peak (more resolution)
490                      - more peaks than stored in the Peakfile
491
492                    So, fetch data from the raw source, and generate peak
493                    data on the fly.
494                 */
495
496                 nframes_t frames_read = 0;
497                 nframes_t current_frame = start;
498                 nframes_t i = 0;
499                 nframes_t nvisual_peaks = 0;
500                 nframes_t chunksize = (nframes_t) min (cnt, (nframes_t) 4096);
501                 raw_staging = new Sample[chunksize];
502                 
503                 nframes_t frame_pos = start;
504                 double pixel_pos = floor (frame_pos / samples_per_visual_peak);
505                 double next_pixel_pos = ceil (frame_pos / samples_per_visual_peak);
506                 double pixels_per_frame = 1.0 / samples_per_visual_peak;
507
508                 xmin = 1.0;
509                 xmax = -1.0;
510
511                 while (nvisual_peaks < npeaks) {
512
513                         if (i == frames_read) {
514                                 
515                                 to_read = min (chunksize, (_length - current_frame));
516
517                                 if (to_read == 0) {
518                                         /* XXX ARGH .. out by one error ... need to figure out why this happens
519                                            and fix it rather than do this band-aid move.
520                                         */
521                                         zero_fill = npeaks - nvisual_peaks;
522                                         break;
523                                 }
524
525                                 if ((frames_read = read_unlocked (raw_staging, current_frame, to_read)) == 0) {
526                                         error << string_compose(_("AudioSource[%1]: peak read - cannot read %2 samples at offset %3 of %4 (%5)"),
527                                                                 _name, to_read, current_frame, _length, strerror (errno)) 
528                                               << endmsg;
529                                         goto out;
530                                 }
531                                         
532                                 i = 0;
533                         }
534                         
535                         xmax = max (xmax, raw_staging[i]);
536                         xmin = min (xmin, raw_staging[i]);
537                         ++i;
538                         ++current_frame;
539                         pixel_pos += pixels_per_frame;
540
541                         if (pixel_pos >= next_pixel_pos) {
542
543                                 peaks[nvisual_peaks].max = xmax;
544                                 peaks[nvisual_peaks].min = xmin;
545                                 ++nvisual_peaks;
546                                 xmin = 1.0;
547                                 xmax = -1.0;
548
549                                 next_pixel_pos = ceil (pixel_pos + 0.5);
550                         }
551                 }
552                 
553                 if (zero_fill) {
554                         memset (&peaks[npeaks], 0, sizeof (PeakData) * zero_fill);
555                 }
556
557                 ret = 0;
558         }
559
560   out:
561         if (_peakfile >= 0) {
562                 close (_peakfile);
563         }
564
565         if (staging) {
566                 delete [] staging;
567         } 
568
569         if (raw_staging) {
570                 delete [] raw_staging;
571         }
572
573 #ifdef DEBUG_READ_PEAKS
574         cerr << "RP DONE\n";
575 #endif
576
577         return ret;
578 }
579
580 #undef DEBUG_PEAK_BUILD
581
582 int
583 AudioSource::build_peaks_from_scratch ()
584 {
585         nframes_t current_frame;
586         nframes_t cnt;
587         Sample* buf = 0;
588         nframes_t frames_read;
589         nframes_t frames_to_read;
590         const nframes_t bufsize = 65536; // 256kB per disk read for mono data is about ideal
591
592         int ret = -1;
593
594         {
595                 /* hold lock while building peaks */
596
597                 Glib::Mutex::Lock lp (_lock);
598                 
599                 if (prepare_for_peakfile_writes ()) {
600                         goto out;
601                 }
602                 
603                 current_frame = 0;
604                 cnt = _length;
605                 _peaks_built = false;
606                 buf = new Sample[bufsize];
607                 
608                 while (cnt) {
609                         
610                         frames_to_read = min (bufsize, cnt);
611
612                         if ((frames_read = read_unlocked (buf, current_frame, frames_to_read)) != frames_to_read) {
613                                 error << string_compose(_("%1: could not write read raw data for peak computation (%2)"), _name, strerror (errno)) << endmsg;
614                                 done_with_peakfile_writes (false);
615                                 goto out;
616                         }
617
618                         if (compute_and_write_peaks (buf, current_frame, frames_read, true, false, _FPP)) {
619                                 break;
620                         }
621                         
622                         current_frame += frames_read;
623                         cnt -= frames_read;
624                 }
625
626                 if (cnt == 0) {
627                         /* success */
628                         truncate_peakfile();
629                 } 
630
631                 done_with_peakfile_writes ((cnt == 0));
632         }
633         
634         {
635                 Glib::Mutex::Lock lm (_peaks_ready_lock);
636                 
637                 if (_peaks_built) {
638                         PeaksReady (); /* EMIT SIGNAL */
639                         ret = 0;
640                 }
641         }
642
643   out:
644         if (ret) {
645                 unlink (peakpath.c_str());
646         }
647
648         if (buf) {
649                 delete [] buf;
650         }
651
652         return ret;
653 }
654
655 int
656 AudioSource::prepare_for_peakfile_writes ()
657 {
658         if ((peakfile = ::open (peakpath.c_str(), O_RDWR|O_CREAT, 0664)) < 0) {
659                 error << string_compose(_("AudioSource: cannot open peakpath (c) \"%1\" (%2)"), peakpath, strerror (errno)) << endmsg;
660                 return -1;
661         }
662         return 0;
663 }
664
665 void
666 AudioSource::done_with_peakfile_writes (bool done)
667 {
668         if (peak_leftover_cnt) {
669                 compute_and_write_peaks (0, 0, 0, true, false, _FPP);
670         }
671         
672         if (done) {
673                 _peaks_built = true;
674         }
675
676         if (peakfile >= 0) {
677                 close (peakfile);
678                 peakfile = -1;
679         }
680 }
681
682 int
683 AudioSource::compute_and_write_peaks (Sample* buf, nframes_t first_frame, nframes_t cnt, bool force, bool intermediate_peaks_ready)
684 {
685         return compute_and_write_peaks (buf, first_frame, cnt, force, intermediate_peaks_ready, _FPP);
686 }
687
688 int
689 AudioSource::compute_and_write_peaks (Sample* buf, nframes_t first_frame, nframes_t cnt, bool force, 
690                                       bool intermediate_peaks_ready, nframes_t fpp)
691 {
692         Sample* buf2 = 0;
693         nframes_t to_do;
694         uint32_t  peaks_computed;
695         PeakData* peakbuf = 0;
696         int ret = -1;
697         nframes_t current_frame;
698         nframes_t frames_done;
699         const size_t blocksize = (128 * 1024);
700         off_t first_peak_byte;
701
702         if (peakfile < 0) {
703                 prepare_for_peakfile_writes ();
704         }
705
706   restart:
707         if (peak_leftover_cnt) {
708
709                 if (first_frame != peak_leftover_frame + peak_leftover_cnt) {
710
711                         /* uh-oh, ::seek() since the last ::compute_and_write_peaks(), 
712                            and we have leftovers. flush a single peak (since the leftovers
713                            never represent more than that, and restart.
714                         */
715                         
716                         PeakData x;
717                         
718                         x.min = peak_leftovers[0];
719                         x.max = peak_leftovers[0];
720
721                         off_t byte = (peak_leftover_frame / fpp) * sizeof (PeakData);
722
723                         if (::pwrite (peakfile, &x, sizeof (PeakData), byte) != sizeof (PeakData)) {
724                                 error << string_compose(_("%1: could not write peak file data (%2)"), _name, strerror (errno)) << endmsg;
725                                 goto out;
726                         }
727
728                         _peak_byte_max = max (_peak_byte_max, (off_t) (byte + sizeof(PeakData)));
729
730                         { 
731                                 Glib::Mutex::Lock lm (_peaks_ready_lock);
732                                 PeakRangeReady (peak_leftover_frame, peak_leftover_cnt); /* EMIT SIGNAL */
733                                 if (intermediate_peaks_ready) {
734                                         PeaksReady (); /* EMIT SIGNAL */
735                                 } 
736                         }
737
738                         /* left overs are done */
739
740                         peak_leftover_cnt = 0;
741                         goto restart;
742                 }
743
744                 /* else ... had leftovers, but they immediately preceed the new data, so just
745                    merge them and compute.
746                 */
747
748                 /* make a new contiguous buffer containing leftovers and the new stuff */
749
750                 to_do = cnt + peak_leftover_cnt;
751                 buf2 = new Sample[to_do];
752
753                 /* the remnants */
754                 memcpy (buf2, peak_leftovers, peak_leftover_cnt * sizeof (Sample));
755
756                 /* the new stuff */
757                 memcpy (buf2+peak_leftover_cnt, buf, cnt * sizeof (Sample));
758
759                 /* no more leftovers */
760                 peak_leftover_cnt = 0;
761
762                 /* use the temporary buffer */
763                 buf = buf2;
764
765                 /* make sure that when we write into the peakfile, we startup where we left off */
766
767                 first_frame = peak_leftover_frame;
768                 
769         } else {
770                 to_do = cnt;
771         }
772
773         peakbuf = new PeakData[(to_do/fpp)+1];
774         peaks_computed = 0;
775         current_frame = first_frame;
776         frames_done = 0;
777
778         while (to_do) {
779
780                 /* if some frames were passed in (i.e. we're not flushing leftovers)
781                    and there are less than fpp to do, save them till
782                    next time
783                 */
784
785                 if (force && (to_do < fpp)) {
786                         /* keep the left overs around for next time */
787
788                         if (peak_leftover_size < to_do) {
789                                 delete [] peak_leftovers;
790                                 peak_leftovers = new Sample[to_do];
791                                 peak_leftover_size = to_do;
792                         }
793                         memcpy (peak_leftovers, buf, to_do * sizeof (Sample));
794                         peak_leftover_cnt = to_do;
795                         peak_leftover_frame = current_frame;
796
797                         /* done for now */
798
799                         break;
800                 }
801                         
802                 nframes_t this_time = min (fpp, to_do);
803
804                 peakbuf[peaks_computed].max = buf[0];
805                 peakbuf[peaks_computed].min = buf[0];
806
807                 ARDOUR::find_peaks (buf+1, this_time-1, &peakbuf[peaks_computed].min, &peakbuf[peaks_computed].max);
808
809                 peaks_computed++;
810                 buf += this_time;
811                 to_do -= this_time;
812                 frames_done += this_time;
813                 current_frame += this_time;
814         }
815                 
816         first_peak_byte = (first_frame / fpp) * sizeof (PeakData);
817
818         if (can_truncate_peaks()) {
819
820                 /* on some filesystems (ext3, at least) this helps to reduce fragmentation of
821                    the peakfiles. its not guaranteed to do so, and even on ext3 (as of december 2006)
822                    it does not cause single-extent allocation even for peakfiles of 
823                    less than BLOCKSIZE bytes.  only call ftruncate if we'll make the file larger.
824                 */
825                 
826                 off_t endpos = lseek (peakfile, 0, SEEK_END);
827                 off_t target_length = blocksize * ((first_peak_byte + blocksize + 1) / blocksize);
828                 
829                 if (endpos < target_length) {
830                         ftruncate (peakfile, target_length);
831                         /* error doesn't actually matter though, so continue on without testing */
832                 }
833         }
834
835         if (::pwrite (peakfile, peakbuf, sizeof (PeakData) * peaks_computed, first_peak_byte) != (ssize_t) (sizeof (PeakData) * peaks_computed)) {
836                 error << string_compose(_("%1: could not write peak file data (%2)"), _name, strerror (errno)) << endmsg;
837                 goto out;
838         }
839
840         _peak_byte_max = max (_peak_byte_max, (off_t) (first_peak_byte + sizeof(PeakData)*peaks_computed));     
841
842         if (frames_done) {
843                 Glib::Mutex::Lock lm (_peaks_ready_lock);
844                 PeakRangeReady (first_frame, frames_done); /* EMIT SIGNAL */
845                 if (intermediate_peaks_ready) {
846                         PeaksReady (); /* EMIT SIGNAL */
847                 }
848         }
849
850         ret = 0;
851
852   out:
853         delete [] peakbuf;
854         if (buf2) {
855                 delete [] buf2;
856         }
857         return ret;
858 }
859
860 void
861 AudioSource::truncate_peakfile ()
862 {
863         if (peakfile < 0) {
864                 error << string_compose (_("programming error: %1"), "AudioSource::truncate_peakfile() called without open peakfile descriptor")
865                       << endmsg;
866                 return;
867         }
868
869         /* truncate the peakfile down to its natural length if necessary */
870
871         off_t end = lseek (peakfile, 0, SEEK_END);
872         
873         if (end > _peak_byte_max) {
874                 ftruncate (peakfile, _peak_byte_max);
875         }
876 }
877
878 bool
879 AudioSource::file_changed (ustring path)
880 {
881         struct stat stat_file;
882         struct stat stat_peak;
883
884         int e1 = stat (path.c_str(), &stat_file);
885         int e2 = stat (peak_path(path).c_str(), &stat_peak);
886         
887         if (!e1 && !e2 && stat_file.st_mtime > stat_peak.st_mtime){
888                 return true;
889         } else {
890                 return false;
891         }
892 }
893
894 nframes_t
895 AudioSource::available_peaks (double zoom_factor) const
896 {
897         off_t end;
898
899         if (zoom_factor < _FPP) {
900                 return length(); // peak data will come from the audio file
901         } 
902         
903         /* peak data comes from peakfile, but the filesize might not represent
904            the valid data due to ftruncate optimizations, so use _peak_byte_max state.
905            XXX - there might be some atomicity issues here, we should probably add a lock,
906            but _peak_byte_max only monotonically increases after initialization.
907         */
908
909         end = _peak_byte_max;
910
911         return (end/sizeof(PeakData)) * _FPP;
912 }
913
914 void
915 AudioSource::update_length (nframes_t pos, nframes_t cnt)
916 {
917         if (pos + cnt > _length) {
918                 _length = pos+cnt;
919         }
920 }
921
922 int
923 AudioSource::load_transients (const string& path)
924 {
925         ifstream file (path.c_str());
926
927         if (!file) {
928                 return -1;
929         }
930         
931         transients.clear ();
932
933         stringstream strstr;
934         double val;
935
936         while (file.good()) {
937                 file >> val;
938
939                 if (!file.fail()) {
940                         nframes64_t frame = (nframes64_t) floor (val * _session.frame_rate());
941                         transients.push_back (frame);
942                 }
943         }
944
945         return 0;
946 }
947
948 string 
949 AudioSource::get_transients_path () const
950 {
951         vector<string> parts;
952         string s;
953
954         /* old sessions may not have the analysis directory */
955         
956         _session.ensure_subdirs ();
957
958         s = _session.analysis_dir ();
959         parts.push_back (s);
960
961         s = _id.to_s();
962         s += '.';
963         s += X_("transients");
964         parts.push_back (s);
965         
966         return Glib::build_filename (parts);
967 }
968