fd481c973009f2cfb0912e42e2e32c3a596c00b8
[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, boost::signals2::connection& connect_here_if_not) 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                 connect_here_if_not = PeaksReady.connect (doThisWhenReady);
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 nframes_t
269 AudioSource::read (Sample *dst, sframes_t start, nframes_t cnt, int /*channel*/) const
270 {
271         Glib::Mutex::Lock lm (_lock);
272         return read_unlocked (dst, start, cnt);
273 }
274
275 nframes_t
276 AudioSource::write (Sample *dst, nframes_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, nframes_t npeaks, sframes_t start, nframes_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, nframes_t npeaks, sframes_t start, nframes_t cnt,
296                                   double samples_per_visual_peak, nframes_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         nframes_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                 nframes_t old = npeaks;
333                 npeaks = min ((nframes_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 (nframes_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         nframes_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 uint32_t chunksize = (uint32_t) min (expected_peaks, 65536.0);
424
425                 staging = new PeakData[chunksize];
426
427                 /* compute the rounded up frame position  */
428
429                 nframes_t current_frame = start;
430                 nframes_t current_stored_peak = (nframes_t) ceil (current_frame / (double) samples_per_file_peak);
431                 uint32_t       next_visual_peak  = (uint32_t) ceil (current_frame / samples_per_visual_peak);
432                 double         next_visual_peak_frame = next_visual_peak * samples_per_visual_peak;
433                 uint32_t       stored_peak_before_next_visual_peak = (nframes_t) next_visual_peak_frame / samples_per_file_peak;
434                 uint32_t       nvisual_peaks = 0;
435                 uint32_t       stored_peaks_read = 0;
436                 uint32_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                         return 0;
447                 }
448
449                 while (nvisual_peaks < npeaks) {
450
451                         if (i == stored_peaks_read) {
452
453                                 uint32_t       start_byte = current_stored_peak * sizeof(PeakData);
454                                 tnp = min ((nframes_t)(_length/samples_per_file_peak - current_stored_peak), (nframes_t) expected_peaks);
455                                 to_read = min (chunksize, tnp);
456
457 #ifdef DEBUG_READ_PEAKS
458                                 cerr << "read " << sizeof (PeakData) * to_read << " from peakfile @ " << start_byte << endl;
459 #endif
460
461                                 if ((nread = ::pread (_peakfile, staging, sizeof (PeakData) * to_read, start_byte))
462                                     != sizeof (PeakData) * to_read) {
463
464                                         off_t fend = lseek (_peakfile, 0, SEEK_END);
465
466                                         cerr << "AudioSource["
467                                              << _name
468                                              << "]: cannot read peak data from peakfile ("
469                                              << (nread / sizeof(PeakData))
470                                              << " peaks instead of "
471                                              << to_read
472                                              << ") ("
473                                              << strerror (errno)
474                                              << ')'
475                                              << " at start_byte = " << start_byte
476                                              << " _length = " << _length << " versus len = " << fend
477                                              << " expected maxpeaks = " << (_length - current_frame)/samples_per_file_peak
478                                              << " npeaks was " << npeaks
479                                              << endl;
480                                         goto out;
481                                 }
482
483                                 i = 0;
484                                 stored_peaks_read = nread / sizeof(PeakData);
485                         }
486
487                         xmax = -1.0;
488                         xmin = 1.0;
489
490                         while ((i < stored_peaks_read) && (current_stored_peak <= stored_peak_before_next_visual_peak)) {
491
492                                 xmax = max (xmax, staging[i].max);
493                                 xmin = min (xmin, staging[i].min);
494                                 ++i;
495                                 ++current_stored_peak;
496                                 --expected_peaks;
497                         }
498
499                         peaks[nvisual_peaks].max = xmax;
500                         peaks[nvisual_peaks].min = xmin;
501                         ++nvisual_peaks;
502                         ++next_visual_peak;
503
504                         //next_visual_peak_frame = min ((next_visual_peak * samples_per_visual_peak), (next_visual_peak_frame+samples_per_visual_peak) );
505                         next_visual_peak_frame =  min ((double) start+cnt, (next_visual_peak_frame+samples_per_visual_peak) );
506                         stored_peak_before_next_visual_peak = (uint32_t) next_visual_peak_frame / samples_per_file_peak;
507                 }
508
509                 if (zero_fill) {
510                         memset (&peaks[npeaks], 0, sizeof (PeakData) * zero_fill);
511                 }
512
513                 ret = 0;
514
515         } else {
516
517 #ifdef DEBUG_READ_PEAKS
518                 cerr << "UPSAMPLE\n";
519 #endif
520                 /* the caller wants
521
522                      - less frames-per-peak (more resolution)
523                      - more peaks than stored in the Peakfile
524
525                    So, fetch data from the raw source, and generate peak
526                    data on the fly.
527                 */
528
529                 nframes_t frames_read = 0;
530                 nframes_t current_frame = start;
531                 nframes_t i = 0;
532                 nframes_t nvisual_peaks = 0;
533                 nframes_t chunksize = (nframes_t) min (cnt, (nframes_t) 4096);
534                 raw_staging = new Sample[chunksize];
535
536                 nframes_t frame_pos = start;
537                 double pixel_pos = floor (frame_pos / samples_per_visual_peak);
538                 double next_pixel_pos = ceil (frame_pos / samples_per_visual_peak);
539                 double pixels_per_frame = 1.0 / samples_per_visual_peak;
540
541                 xmin = 1.0;
542                 xmax = -1.0;
543
544                 while (nvisual_peaks < npeaks) {
545
546                         if (i == frames_read) {
547
548                                 to_read = min (chunksize, nframes_t(_length - current_frame));
549
550                                 if (to_read == 0) {
551                                         /* XXX ARGH .. out by one error ... need to figure out why this happens
552                                            and fix it rather than do this band-aid move.
553                                         */
554                                         zero_fill = npeaks - nvisual_peaks;
555                                         npeaks -= zero_fill;
556                                         break;
557                                 }
558
559                                 if ((frames_read = read_unlocked (raw_staging, current_frame, to_read)) == 0) {
560                                         error << string_compose(_("AudioSource[%1]: peak read - cannot read %2 samples at offset %3 of %4 (%5)"),
561                                                                 _name, to_read, current_frame, _length, strerror (errno))
562                                               << endmsg;
563                                         goto out;
564                                 }
565
566                                 i = 0;
567                         }
568
569                         xmax = max (xmax, raw_staging[i]);
570                         xmin = min (xmin, raw_staging[i]);
571                         ++i;
572                         ++current_frame;
573                         pixel_pos += pixels_per_frame;
574
575                         if (pixel_pos >= next_pixel_pos) {
576
577                                 peaks[nvisual_peaks].max = xmax;
578                                 peaks[nvisual_peaks].min = xmin;
579                                 ++nvisual_peaks;
580                                 xmin = 1.0;
581                                 xmax = -1.0;
582
583                                 next_pixel_pos = ceil (pixel_pos + 0.5);
584                         }
585                 }
586
587                 if (zero_fill) {
588                         memset (&peaks[npeaks], 0, sizeof (PeakData) * zero_fill);
589                 }
590
591                 ret = 0;
592         }
593
594   out:
595         if (_peakfile >= 0) {
596                 close (_peakfile);
597         }
598
599         delete [] staging;
600         delete [] raw_staging;
601
602 #ifdef DEBUG_READ_PEAKS
603         cerr << "RP DONE\n";
604 #endif
605
606         return ret;
607 }
608
609 #undef DEBUG_PEAK_BUILD
610
611 int
612 AudioSource::build_peaks_from_scratch ()
613 {
614         nframes_t current_frame;
615         nframes_t cnt;
616         Sample* buf = 0;
617         nframes_t frames_read;
618         nframes_t frames_to_read;
619         const nframes_t bufsize = 65536; // 256kB per disk read for mono data is about ideal
620
621         int ret = -1;
622
623         {
624                 /* hold lock while building peaks */
625
626                 Glib::Mutex::Lock lp (_lock);
627
628                 if (prepare_for_peakfile_writes ()) {
629                         goto out;
630                 }
631
632                 current_frame = 0;
633                 cnt = _length;
634                 _peaks_built = false;
635                 buf = new Sample[bufsize];
636
637                 while (cnt) {
638
639                         frames_to_read = min (bufsize, cnt);
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, sframes_t first_frame, nframes_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, sframes_t first_frame, nframes_t cnt,
718                 bool force, bool intermediate_peaks_ready, nframes_t fpp)
719 {
720         Sample* buf2 = 0;
721         nframes_t to_do;
722         uint32_t  peaks_computed;
723         PeakData* peakbuf = 0;
724         int ret = -1;
725         nframes_t current_frame;
726         nframes_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                 nframes_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 nframes_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