Tidy up PeaksReady locking slightly and emit it during done_with_peakfile_writes...
[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 || ((nframes_t) statbuf.st_size < ((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                 framepos_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 int
726 AudioSource::compute_and_write_peaks (Sample* buf, framepos_t first_frame, framecnt_t cnt,
727                                       bool force, bool intermediate_peaks_ready)
728 {
729         return compute_and_write_peaks (buf, first_frame, cnt, force, intermediate_peaks_ready, _FPP);
730 }
731
732 int
733 AudioSource::compute_and_write_peaks (Sample* buf, framepos_t first_frame, framecnt_t cnt,
734                                       bool force, bool intermediate_peaks_ready, framecnt_t fpp)
735 {
736         Sample* buf2 = 0;
737         framecnt_t to_do;
738         uint32_t  peaks_computed;
739         PeakData* peakbuf = 0;
740         int ret = -1;
741         framepos_t current_frame;
742         framecnt_t frames_done;
743         const size_t blocksize = (128 * 1024);
744         off_t first_peak_byte;
745
746         if (_peakfile_descriptor == 0) {
747                 prepare_for_peakfile_writes ();
748         }
749
750   restart:
751         if (peak_leftover_cnt) {
752
753                 if (first_frame != peak_leftover_frame + peak_leftover_cnt) {
754
755                         /* uh-oh, ::seek() since the last ::compute_and_write_peaks(),
756                            and we have leftovers. flush a single peak (since the leftovers
757                            never represent more than that, and restart.
758                         */
759
760                         PeakData x;
761
762                         x.min = peak_leftovers[0];
763                         x.max = peak_leftovers[0];
764
765                         off_t byte = (peak_leftover_frame / fpp) * sizeof (PeakData);
766
767                         if (::pwrite (_peakfile_fd, &x, sizeof (PeakData), byte) != sizeof (PeakData)) {
768                                 error << string_compose(_("%1: could not write peak file data (%2)"), _name, strerror (errno)) << endmsg;
769                                 goto out;
770                         }
771
772                         _peak_byte_max = max (_peak_byte_max, (off_t) (byte + sizeof(PeakData)));
773
774                         {
775                                 Glib::Mutex::Lock lm (_peaks_ready_lock);
776                                 PeakRangeReady (peak_leftover_frame, peak_leftover_cnt); /* EMIT SIGNAL */
777                                 if (intermediate_peaks_ready) {
778                                         PeaksReady (); /* EMIT SIGNAL */
779                                 }
780                         }
781
782                         /* left overs are done */
783
784                         peak_leftover_cnt = 0;
785                         goto restart;
786                 }
787
788                 /* else ... had leftovers, but they immediately preceed the new data, so just
789                    merge them and compute.
790                 */
791
792                 /* make a new contiguous buffer containing leftovers and the new stuff */
793
794                 to_do = cnt + peak_leftover_cnt;
795                 buf2 = new Sample[to_do];
796
797                 /* the remnants */
798                 memcpy (buf2, peak_leftovers, peak_leftover_cnt * sizeof (Sample));
799
800                 /* the new stuff */
801                 memcpy (buf2+peak_leftover_cnt, buf, cnt * sizeof (Sample));
802
803                 /* no more leftovers */
804                 peak_leftover_cnt = 0;
805
806                 /* use the temporary buffer */
807                 buf = buf2;
808
809                 /* make sure that when we write into the peakfile, we startup where we left off */
810
811                 first_frame = peak_leftover_frame;
812
813         } else {
814                 to_do = cnt;
815         }
816
817         peakbuf = new PeakData[(to_do/fpp)+1];
818         peaks_computed = 0;
819         current_frame = first_frame;
820         frames_done = 0;
821
822         while (to_do) {
823
824                 /* if some frames were passed in (i.e. we're not flushing leftovers)
825                    and there are less than fpp to do, save them till
826                    next time
827                 */
828
829                 if (force && (to_do < fpp)) {
830                         /* keep the left overs around for next time */
831
832                         if (peak_leftover_size < to_do) {
833                                 delete [] peak_leftovers;
834                                 peak_leftovers = new Sample[to_do];
835                                 peak_leftover_size = to_do;
836                         }
837                         memcpy (peak_leftovers, buf, to_do * sizeof (Sample));
838                         peak_leftover_cnt = to_do;
839                         peak_leftover_frame = current_frame;
840
841                         /* done for now */
842
843                         break;
844                 }
845
846                 framecnt_t this_time = min (fpp, to_do);
847
848                 peakbuf[peaks_computed].max = buf[0];
849                 peakbuf[peaks_computed].min = buf[0];
850
851                 ARDOUR::find_peaks (buf+1, this_time-1, &peakbuf[peaks_computed].min, &peakbuf[peaks_computed].max);
852
853                 peaks_computed++;
854                 buf += this_time;
855                 to_do -= this_time;
856                 frames_done += this_time;
857                 current_frame += this_time;
858         }
859
860         first_peak_byte = (first_frame / fpp) * sizeof (PeakData);
861
862         if (can_truncate_peaks()) {
863
864                 /* on some filesystems (ext3, at least) this helps to reduce fragmentation of
865                    the peakfiles. its not guaranteed to do so, and even on ext3 (as of december 2006)
866                    it does not cause single-extent allocation even for peakfiles of
867                    less than BLOCKSIZE bytes.  only call ftruncate if we'll make the file larger.
868                 */
869
870                 off_t endpos = lseek (_peakfile_fd, 0, SEEK_END);
871                 off_t target_length = blocksize * ((first_peak_byte + blocksize + 1) / blocksize);
872
873                 if (endpos < target_length) {
874                         (void) ftruncate (_peakfile_fd, target_length);
875                         /* error doesn't actually matter though, so continue on without testing */
876                 }
877         }
878
879         if (::pwrite (_peakfile_fd, peakbuf, sizeof (PeakData) * peaks_computed, first_peak_byte) != (ssize_t) (sizeof (PeakData) * peaks_computed)) {
880                 error << string_compose(_("%1: could not write peak file data (%2)"), _name, strerror (errno)) << endmsg;
881                 goto out;
882         }
883
884         _peak_byte_max = max (_peak_byte_max, (off_t) (first_peak_byte + sizeof(PeakData)*peaks_computed));
885
886         if (frames_done) {
887                 Glib::Mutex::Lock lm (_peaks_ready_lock);
888                 PeakRangeReady (first_frame, frames_done); /* EMIT SIGNAL */
889                 if (intermediate_peaks_ready) {
890                         PeaksReady (); /* EMIT SIGNAL */
891                 }
892         }
893
894         ret = 0;
895
896   out:
897         delete [] peakbuf;
898         delete [] buf2;
899
900         return ret;
901 }
902
903 void
904 AudioSource::truncate_peakfile ()
905 {
906         if (_peakfile_descriptor == 0) {
907                 error << string_compose (_("programming error: %1"), "AudioSource::truncate_peakfile() called without open peakfile descriptor")
908                       << endmsg;
909                 return;
910         }
911
912         /* truncate the peakfile down to its natural length if necessary */
913
914         off_t end = lseek (_peakfile_fd, 0, SEEK_END);
915
916         if (end > _peak_byte_max) {
917                 (void) ftruncate (_peakfile_fd, _peak_byte_max);
918         }
919 }
920
921 framecnt_t
922 AudioSource::available_peaks (double zoom_factor) const
923 {
924         if (zoom_factor < _FPP) {
925                 return length(_timeline_position); // peak data will come from the audio file
926         }
927
928         /* peak data comes from peakfile, but the filesize might not represent
929            the valid data due to ftruncate optimizations, so use _peak_byte_max state.
930            XXX - there might be some atomicity issues here, we should probably add a lock,
931            but _peak_byte_max only monotonically increases after initialization.
932         */
933
934         off_t end = _peak_byte_max;
935
936         return (end/sizeof(PeakData)) * _FPP;
937 }
938
939 void
940 AudioSource::dec_read_data_count (nframes_t cnt)
941 {
942         uint32_t val = cnt * sizeof (Sample);
943
944         if (val < _read_data_count) {
945                 _read_data_count -= val;
946         } else { 
947                 _read_data_count = 0;
948         }
949 }
950
951 void
952 AudioSource::mark_streaming_write_completed ()
953 {
954         Glib::Mutex::Lock lm (_peaks_ready_lock);
955
956         if (_peaks_built) {
957                 PeaksReady (); /* EMIT SIGNAL */
958         }
959 }