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