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