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