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