f3206412f89331019b65567697e9376ab2ef894d
[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, Connection& 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 (to_read == 0) {
552                                         /* XXX ARGH .. out by one error ... need to figure out why this happens
553                                            and fix it rather than do this band-aid move.
554                                         */
555                                         zero_fill = npeaks - nvisual_peaks;
556                                         npeaks -= zero_fill;
557                                         break;
558                                 }
559
560                                 if ((frames_read = read_unlocked (raw_staging, current_frame, to_read)) == 0) {
561                                         error << string_compose(_("AudioSource[%1]: peak read - cannot read %2 samples at offset %3 of %4 (%5)"),
562                                                                 _name, to_read, current_frame, _length, strerror (errno))
563                                               << endmsg;
564                                         goto out;
565                                 }
566
567                                 i = 0;
568                         }
569
570                         xmax = max (xmax, raw_staging[i]);
571                         xmin = min (xmin, raw_staging[i]);
572                         ++i;
573                         ++current_frame;
574                         pixel_pos += pixels_per_frame;
575
576                         if (pixel_pos >= next_pixel_pos) {
577
578                                 peaks[nvisual_peaks].max = xmax;
579                                 peaks[nvisual_peaks].min = xmin;
580                                 ++nvisual_peaks;
581                                 xmin = 1.0;
582                                 xmax = -1.0;
583
584                                 next_pixel_pos = ceil (pixel_pos + 0.5);
585                         }
586                 }
587
588                 if (zero_fill) {
589                         memset (&peaks[npeaks], 0, sizeof (PeakData) * zero_fill);
590                 }
591
592                 ret = 0;
593         }
594
595   out:
596         if (_peakfile >= 0) {
597                 close (_peakfile);
598         }
599
600         delete [] staging;
601         delete [] raw_staging;
602
603 #ifdef DEBUG_READ_PEAKS
604         cerr << "RP DONE\n";
605 #endif
606
607         return ret;
608 }
609
610 #undef DEBUG_PEAK_BUILD
611
612 int
613 AudioSource::build_peaks_from_scratch ()
614 {
615         Sample* buf = 0;
616
617         const framecnt_t bufsize = 65536; // 256kB per disk read for mono data is about ideal
618
619         int ret = -1;
620
621         {
622                 /* hold lock while building peaks */
623
624                 Glib::Mutex::Lock lp (_lock);
625
626                 if (prepare_for_peakfile_writes ()) {
627                         goto out;
628                 }
629
630                 framepos_t current_frame = 0;
631                 framecnt_t cnt = _length;
632
633                 _peaks_built = false;
634                 buf = new Sample[bufsize];
635
636                 while (cnt) {
637
638                         framecnt_t frames_to_read = min (bufsize, cnt);
639                         framecnt_t frames_read;
640
641                         if ((frames_read = read_unlocked (buf, current_frame, frames_to_read)) != frames_to_read) {
642                                 error << string_compose(_("%1: could not write read raw data for peak computation (%2)"), _name, strerror (errno)) << endmsg;
643                                 done_with_peakfile_writes (false);
644                                 goto out;
645                         }
646
647                         if (compute_and_write_peaks (buf, current_frame, frames_read, true, false, _FPP)) {
648                                 break;
649                         }
650
651                         current_frame += frames_read;
652                         cnt -= frames_read;
653                 }
654
655                 if (cnt == 0) {
656                         /* success */
657                         truncate_peakfile();
658                 }
659
660                 done_with_peakfile_writes ((cnt == 0));
661         }
662
663         {
664                 Glib::Mutex::Lock lm (_peaks_ready_lock);
665
666                 if (_peaks_built) {
667                         PeaksReady (); /* EMIT SIGNAL */
668                         ret = 0;
669                 }
670         }
671
672   out:
673         if (ret) {
674                 unlink (peakpath.c_str());
675         }
676
677         delete [] buf;
678
679         return ret;
680 }
681
682 int
683 AudioSource::prepare_for_peakfile_writes ()
684 {
685         if ((peakfile = ::open (peakpath.c_str(), O_RDWR|O_CREAT, 0664)) < 0) {
686                 error << string_compose(_("AudioSource: cannot open peakpath (c) \"%1\" (%2)"), peakpath, strerror (errno)) << endmsg;
687                 return -1;
688         }
689         return 0;
690 }
691
692 void
693 AudioSource::done_with_peakfile_writes (bool done)
694 {
695         if (peak_leftover_cnt) {
696                 compute_and_write_peaks (0, 0, 0, true, false, _FPP);
697         }
698
699         if (done) {
700                 _peaks_built = true;
701         }
702
703         if (peakfile >= 0) {
704                 close (peakfile);
705                 peakfile = -1;
706         }
707 }
708
709 int
710 AudioSource::compute_and_write_peaks (Sample* buf, framepos_t first_frame, framecnt_t cnt,
711                                       bool force, bool intermediate_peaks_ready)
712 {
713         return compute_and_write_peaks (buf, first_frame, cnt, force, intermediate_peaks_ready, _FPP);
714 }
715
716 int
717 AudioSource::compute_and_write_peaks (Sample* buf, framepos_t first_frame, framecnt_t cnt,
718                                       bool force, bool intermediate_peaks_ready, framecnt_t fpp)
719 {
720         Sample* buf2 = 0;
721         framecnt_t to_do;
722         uint32_t  peaks_computed;
723         PeakData* peakbuf = 0;
724         int ret = -1;
725         framepos_t current_frame;
726         framecnt_t frames_done;
727         const size_t blocksize = (128 * 1024);
728         off_t first_peak_byte;
729
730         if (peakfile < 0) {
731                 prepare_for_peakfile_writes ();
732         }
733
734   restart:
735         if (peak_leftover_cnt) {
736
737                 if (first_frame != peak_leftover_frame + peak_leftover_cnt) {
738
739                         /* uh-oh, ::seek() since the last ::compute_and_write_peaks(),
740                            and we have leftovers. flush a single peak (since the leftovers
741                            never represent more than that, and restart.
742                         */
743
744                         PeakData x;
745
746                         x.min = peak_leftovers[0];
747                         x.max = peak_leftovers[0];
748
749                         off_t byte = (peak_leftover_frame / fpp) * sizeof (PeakData);
750
751                         if (::pwrite (peakfile, &x, sizeof (PeakData), byte) != sizeof (PeakData)) {
752                                 error << string_compose(_("%1: could not write peak file data (%2)"), _name, strerror (errno)) << endmsg;
753                                 goto out;
754                         }
755
756                         _peak_byte_max = max (_peak_byte_max, (off_t) (byte + sizeof(PeakData)));
757
758                         {
759                                 Glib::Mutex::Lock lm (_peaks_ready_lock);
760                                 PeakRangeReady (peak_leftover_frame, peak_leftover_cnt); /* EMIT SIGNAL */
761                                 if (intermediate_peaks_ready) {
762                                         PeaksReady (); /* EMIT SIGNAL */
763                                 }
764                         }
765
766                         /* left overs are done */
767
768                         peak_leftover_cnt = 0;
769                         goto restart;
770                 }
771
772                 /* else ... had leftovers, but they immediately preceed the new data, so just
773                    merge them and compute.
774                 */
775
776                 /* make a new contiguous buffer containing leftovers and the new stuff */
777
778                 to_do = cnt + peak_leftover_cnt;
779                 buf2 = new Sample[to_do];
780
781                 /* the remnants */
782                 memcpy (buf2, peak_leftovers, peak_leftover_cnt * sizeof (Sample));
783
784                 /* the new stuff */
785                 memcpy (buf2+peak_leftover_cnt, buf, cnt * sizeof (Sample));
786
787                 /* no more leftovers */
788                 peak_leftover_cnt = 0;
789
790                 /* use the temporary buffer */
791                 buf = buf2;
792
793                 /* make sure that when we write into the peakfile, we startup where we left off */
794
795                 first_frame = peak_leftover_frame;
796
797         } else {
798                 to_do = cnt;
799         }
800
801         peakbuf = new PeakData[(to_do/fpp)+1];
802         peaks_computed = 0;
803         current_frame = first_frame;
804         frames_done = 0;
805
806         while (to_do) {
807
808                 /* if some frames were passed in (i.e. we're not flushing leftovers)
809                    and there are less than fpp to do, save them till
810                    next time
811                 */
812
813                 if (force && (to_do < fpp)) {
814                         /* keep the left overs around for next time */
815
816                         if (peak_leftover_size < to_do) {
817                                 delete [] peak_leftovers;
818                                 peak_leftovers = new Sample[to_do];
819                                 peak_leftover_size = to_do;
820                         }
821                         memcpy (peak_leftovers, buf, to_do * sizeof (Sample));
822                         peak_leftover_cnt = to_do;
823                         peak_leftover_frame = current_frame;
824
825                         /* done for now */
826
827                         break;
828                 }
829
830                 framecnt_t this_time = min (fpp, to_do);
831
832                 peakbuf[peaks_computed].max = buf[0];
833                 peakbuf[peaks_computed].min = buf[0];
834
835                 ARDOUR::find_peaks (buf+1, this_time-1, &peakbuf[peaks_computed].min, &peakbuf[peaks_computed].max);
836
837                 peaks_computed++;
838                 buf += this_time;
839                 to_do -= this_time;
840                 frames_done += this_time;
841                 current_frame += this_time;
842         }
843
844         first_peak_byte = (first_frame / fpp) * sizeof (PeakData);
845
846         if (can_truncate_peaks()) {
847
848                 /* on some filesystems (ext3, at least) this helps to reduce fragmentation of
849                    the peakfiles. its not guaranteed to do so, and even on ext3 (as of december 2006)
850                    it does not cause single-extent allocation even for peakfiles of
851                    less than BLOCKSIZE bytes.  only call ftruncate if we'll make the file larger.
852                 */
853
854                 off_t endpos = lseek (peakfile, 0, SEEK_END);
855                 off_t target_length = blocksize * ((first_peak_byte + blocksize + 1) / blocksize);
856
857                 if (endpos < target_length) {
858                         ftruncate (peakfile, target_length);
859                         /* error doesn't actually matter though, so continue on without testing */
860                 }
861         }
862
863         if (::pwrite (peakfile, peakbuf, sizeof (PeakData) * peaks_computed, first_peak_byte) != (ssize_t) (sizeof (PeakData) * peaks_computed)) {
864                 error << string_compose(_("%1: could not write peak file data (%2)"), _name, strerror (errno)) << endmsg;
865                 goto out;
866         }
867
868         _peak_byte_max = max (_peak_byte_max, (off_t) (first_peak_byte + sizeof(PeakData)*peaks_computed));
869
870         if (frames_done) {
871                 Glib::Mutex::Lock lm (_peaks_ready_lock);
872                 PeakRangeReady (first_frame, frames_done); /* EMIT SIGNAL */
873                 if (intermediate_peaks_ready) {
874                         PeaksReady (); /* EMIT SIGNAL */
875                 }
876         }
877
878         ret = 0;
879
880   out:
881         delete [] peakbuf;
882         delete [] buf2;
883
884         return ret;
885 }
886
887 void
888 AudioSource::truncate_peakfile ()
889 {
890         if (peakfile < 0) {
891                 error << string_compose (_("programming error: %1"), "AudioSource::truncate_peakfile() called without open peakfile descriptor")
892                       << endmsg;
893                 return;
894         }
895
896         /* truncate the peakfile down to its natural length if necessary */
897
898         off_t end = lseek (peakfile, 0, SEEK_END);
899
900         if (end > _peak_byte_max) {
901                 ftruncate (peakfile, _peak_byte_max);
902         }
903 }
904
905 framecnt_t
906 AudioSource::available_peaks (double zoom_factor) const
907 {
908         if (zoom_factor < _FPP) {
909                 return length(_timeline_position); // peak data will come from the audio file
910         }
911
912         /* peak data comes from peakfile, but the filesize might not represent
913            the valid data due to ftruncate optimizations, so use _peak_byte_max state.
914            XXX - there might be some atomicity issues here, we should probably add a lock,
915            but _peak_byte_max only monotonically increases after initialization.
916         */
917
918         off_t end = _peak_byte_max;
919
920         return (end/sizeof(PeakData)) * _FPP;
921 }
922