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