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