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