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