08f9c553ce654e158de08e9c3de7abd465170660
[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/audio_diskstream.h"
42 #include "ardour/cycle_timer.h"
43 #include "ardour/session.h"
44 #include "ardour/transient_detector.h"
45 #include "ardour/runtime_functions.h"
46
47 #include "i18n.h"
48
49 using namespace std;
50 using namespace ARDOUR;
51 using namespace PBD;
52
53 Glib::StaticMutex AudioSource::_level_buffer_lock = GLIBMM_STATIC_MUTEX_INIT;
54 vector<boost::shared_ptr<Sample> > AudioSource::_mixdown_buffers;
55 vector<boost::shared_ptr<gain_t> > AudioSource::_gain_buffers;
56 size_t AudioSource::_working_buffers_size = 0;
57 bool AudioSource::_build_missing_peakfiles = false;
58
59 /** true if we want peakfiles (e.g. if we are displaying a GUI) */
60 bool AudioSource::_build_peakfiles = false;
61
62 #define _FPP 256
63
64 AudioSource::AudioSource (Session& s, string name)
65         : Source (s, DataType::AUDIO, name)
66         , _length (0)
67 {
68         _peaks_built = false;
69         _peak_byte_max = 0;
70         _peakfile_descriptor = 0;
71         peak_leftover_cnt = 0;
72         peak_leftover_size = 0;
73         peak_leftovers = 0;
74 }
75
76 AudioSource::AudioSource (Session& s, const XMLNode& node)
77         : Source (s, node)
78         , _length (0)
79 {
80
81         _peaks_built = false;
82         _peak_byte_max = 0;
83         _peakfile_descriptor = 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         if (!(ret = _peaks_built)) {
170                 *connect_here_if_not = new ScopedConnection;
171                 PeaksReady.connect (**connect_here_if_not, MISSING_INVALIDATOR, doThisWhenReady, event_loop);
172         }
173
174         return ret;
175 }
176
177 void
178 AudioSource::touch_peakfile ()
179 {
180         struct stat statbuf;
181
182         if (stat (peakpath.c_str(), &statbuf) != 0 || statbuf.st_size == 0) {
183                 return;
184         }
185
186         struct utimbuf tbuf;
187
188         tbuf.actime = statbuf.st_atime;
189         tbuf.modtime = time ((time_t) 0);
190
191         utime (peakpath.c_str(), &tbuf);
192 }
193
194 int
195 AudioSource::rename_peakfile (string newpath)
196 {
197         /* caller must hold _lock */
198
199         string oldpath = peakpath;
200
201         if (Glib::file_test (oldpath, Glib::FILE_TEST_EXISTS)) {
202                 if (rename (oldpath.c_str(), newpath.c_str()) != 0) {
203                         error << string_compose (_("cannot rename peakfile for %1 from %2 to %3 (%4)"), _name, oldpath, newpath, strerror (errno)) << endmsg;
204                         return -1;
205                 }
206         }
207
208         peakpath = newpath;
209
210         return 0;
211 }
212
213 int
214 AudioSource::initialize_peakfile (bool newfile, string audio_path)
215 {
216         struct stat statbuf;
217
218         peakpath = peak_path (audio_path);
219
220         /* if the peak file should be there, but isn't .... */
221
222         if (!newfile && !Glib::file_test (peakpath.c_str(), Glib::FILE_TEST_EXISTS)) {
223                 peakpath = find_broken_peakfile (peakpath, audio_path);
224         }
225
226         if (stat (peakpath.c_str(), &statbuf)) {
227                 if (errno != ENOENT) {
228                         /* it exists in the peaks dir, but there is some kind of error */
229
230                         error << string_compose(_("AudioSource: cannot stat peakfile \"%1\""), peakpath) << endmsg;
231                         return -1;
232                 }
233
234                 /* peakfile does not exist */
235
236                 _peaks_built = false;
237
238         } else {
239
240                 /* we found it in the peaks dir, so check it out */
241
242                 if (statbuf.st_size == 0 || (statbuf.st_size < (off_t) ((length(_timeline_position) / _FPP) * sizeof (PeakData)))) {
243                         // empty
244                         _peaks_built = false;
245                 } else {
246                         // Check if the audio file has changed since the peakfile was built.
247                         struct stat stat_file;
248                         int err = stat (audio_path.c_str(), &stat_file);
249
250                         if (err) {
251
252                                 /* no audio path - nested source or we can't
253                                    read it or ... whatever, use the peakfile as-is.
254                                 */
255
256                                 _peaks_built = true;
257                                 _peak_byte_max = statbuf.st_size;
258
259                         } else {
260
261                                 /* allow 6 seconds slop on checking peak vs. file times because of various
262                                    disk action "races"
263                                 */
264
265                                 if (stat_file.st_mtime > statbuf.st_mtime && (stat_file.st_mtime - statbuf.st_mtime > 6)) {
266                                         _peaks_built = false;
267                                         _peak_byte_max = 0;
268                                 } else {
269                                         _peaks_built = true;
270                                         _peak_byte_max = statbuf.st_size;
271                                 }
272                         }
273                 }
274         }
275
276         if (!newfile && !_peaks_built && _build_missing_peakfiles && _build_peakfiles) {
277                 build_peaks_from_scratch ();
278         }
279
280         return 0;
281 }
282
283 framecnt_t
284 AudioSource::read (Sample *dst, framepos_t start, framecnt_t cnt, int /*channel*/) const
285 {
286         assert (cnt >= 0);
287         
288         Glib::Mutex::Lock lm (_lock);
289         return read_unlocked (dst, start, cnt);
290 }
291
292 framecnt_t
293 AudioSource::write (Sample *dst, framecnt_t cnt)
294 {
295         Glib::Mutex::Lock lm (_lock);
296         /* any write makes the fill not removable */
297         _flags = Flag (_flags & ~Removable);
298         return write_unlocked (dst, cnt);
299 }
300
301 int
302 AudioSource::read_peaks (PeakData *peaks, framecnt_t npeaks, framepos_t start, framecnt_t cnt, double samples_per_visual_peak) const
303 {
304         return read_peaks_with_fpp (peaks, npeaks, start, cnt, samples_per_visual_peak, _FPP);
305 }
306
307 /** @param peaks Buffer to write peak data.
308  *  @param npeaks Number of peaks to write.
309  */
310
311 int
312 AudioSource::read_peaks_with_fpp (PeakData *peaks, framecnt_t npeaks, framepos_t start, framecnt_t cnt,
313                                   double samples_per_visual_peak, framecnt_t samples_per_file_peak) const
314 {
315         Glib::Mutex::Lock lm (_lock);
316         double scale;
317         double expected_peaks;
318         PeakData::PeakDatum xmax;
319         PeakData::PeakDatum xmin;
320         int32_t to_read;
321         uint32_t nread;
322         framecnt_t zero_fill = 0;
323         int ret = -1;
324         PeakData* staging = 0;
325         Sample* raw_staging = 0;
326
327         FdFileDescriptor* peakfile_descriptor = new FdFileDescriptor (peakpath, false, 0664);
328         int peakfile_fd = -1;
329
330         expected_peaks = (cnt / (double) samples_per_file_peak);
331         scale = npeaks/expected_peaks;
332
333 #undef DEBUG_READ_PEAKS
334 #ifdef DEBUG_READ_PEAKS
335         cerr << "======>RP: npeaks = " << npeaks
336              << " start = " << start
337              << " cnt = " << cnt
338              << " len = " << _length
339              << "   samples_per_visual_peak =" << samples_per_visual_peak
340              << " expected was " << expected_peaks << " ... scale = " << scale
341              << " PD ptr = " << peaks
342              <<endl;
343
344 #endif
345
346         /* fix for near-end-of-file conditions */
347
348         if (cnt > _length - start) {
349                 // cerr << "too close to end @ " << _length << " given " << start << " + " << cnt << endl;
350                 cnt = _length - start;
351                 framecnt_t old = npeaks;
352                 npeaks = min ((framecnt_t) floor (cnt / samples_per_visual_peak), npeaks);
353                 zero_fill = old - npeaks;
354         }
355
356         // cerr << "actual npeaks = " << npeaks << " zf = " << zero_fill << endl;
357
358         if (npeaks == cnt) {
359
360 #ifdef DEBUG_READ_PEAKS
361                 cerr << "RAW DATA\n";
362 #endif
363                 /* no scaling at all, just get the sample data and duplicate it for
364                    both max and min peak values.
365                 */
366
367                 Sample* raw_staging = new Sample[cnt];
368
369                 if (read_unlocked (raw_staging, start, cnt) != cnt) {
370                         error << _("cannot read sample data for unscaled peak computation") << endmsg;
371                         return -1;
372                 }
373
374                 for (framecnt_t i = 0; i < npeaks; ++i) {
375                         peaks[i].max = raw_staging[i];
376                         peaks[i].min = raw_staging[i];
377                 }
378
379                 delete peakfile_descriptor;
380                 delete [] raw_staging;
381                 return 0;
382         }
383
384         if (scale == 1.0) {
385
386                 off_t first_peak_byte = (start / samples_per_file_peak) * sizeof (PeakData);
387
388                 /* open, read, close */
389
390                 if ((peakfile_fd = peakfile_descriptor->allocate ()) < 0) {
391                         error << string_compose(_("AudioSource: cannot open peakpath (a) \"%1\" (%2)"), peakpath, strerror (errno)) << endmsg;
392                         delete peakfile_descriptor;
393                         return -1;
394                 }
395
396 #ifdef DEBUG_READ_PEAKS
397                 cerr << "DIRECT PEAKS\n";
398 #endif
399
400                 nread = ::pread (peakfile_fd, peaks, sizeof (PeakData)* npeaks, first_peak_byte);
401
402                 if (nread != sizeof (PeakData) * npeaks) {
403                         cerr << "AudioSource["
404                              << _name
405                              << "]: cannot read peaks from peakfile! (read only "
406                              << nread
407                              << " not "
408                              << npeaks
409                               << "at sample "
410                              << start
411                              << " = byte "
412                              << first_peak_byte
413                              << ')'
414                              << endl;
415                         delete peakfile_descriptor;
416                         return -1;
417                 }
418
419                 if (zero_fill) {
420                         memset (&peaks[npeaks], 0, sizeof (PeakData) * zero_fill);
421                 }
422
423                 delete peakfile_descriptor;
424                 return 0;
425         }
426
427
428         framecnt_t tnp;
429
430         if (scale < 1.0) {
431
432 #ifdef DEBUG_READ_PEAKS
433                 cerr << "DOWNSAMPLE\n";
434 #endif
435                 /* the caller wants:
436
437                     - more frames-per-peak (lower resolution) than the peakfile, or to put it another way,
438                     - less peaks than the peakfile holds for the same range
439
440                     So, read a block into a staging area, and then downsample from there.
441
442                     to avoid confusion, I'll refer to the requested peaks as visual_peaks and the peakfile peaks as stored_peaks
443                 */
444
445                 const framecnt_t chunksize = (framecnt_t) min (expected_peaks, 65536.0);
446
447                 staging = new PeakData[chunksize];
448
449                 /* compute the rounded up frame position  */
450
451                 framepos_t current_frame = start;
452                 framepos_t current_stored_peak = (framepos_t) ceil (current_frame / (double) samples_per_file_peak);
453                 framepos_t next_visual_peak  = (framepos_t) ceil (current_frame / samples_per_visual_peak);
454                 double     next_visual_peak_frame = next_visual_peak * samples_per_visual_peak;
455                 framepos_t stored_peak_before_next_visual_peak = (framepos_t) next_visual_peak_frame / samples_per_file_peak;
456                 framecnt_t nvisual_peaks = 0;
457                 framecnt_t stored_peaks_read = 0;
458                 framecnt_t i = 0;
459
460                 /* handle the case where the initial visual peak is on a pixel boundary */
461
462                 current_stored_peak = min (current_stored_peak, stored_peak_before_next_visual_peak);
463
464                 /* open ... close during out: handling */
465
466                 if ((peakfile_fd = peakfile_descriptor->allocate ()) < 0) {
467                         error << string_compose(_("AudioSource: cannot open peakpath (b) \"%1\" (%2)"), peakpath, strerror (errno)) << endmsg;
468                         delete peakfile_descriptor;
469                         delete [] staging;
470                         return 0;
471                 }
472
473                 while (nvisual_peaks < npeaks) {
474
475                         if (i == stored_peaks_read) {
476
477                                 uint32_t       start_byte = current_stored_peak * sizeof(PeakData);
478                                 tnp = min ((framecnt_t)(_length/samples_per_file_peak - current_stored_peak), (framecnt_t) expected_peaks);
479                                 to_read = min (chunksize, tnp);
480
481 #ifdef DEBUG_READ_PEAKS
482                                 cerr << "read " << sizeof (PeakData) * to_read << " from peakfile @ " << start_byte << endl;
483 #endif
484
485                                 if ((nread = ::pread (peakfile_fd, staging, sizeof (PeakData) * to_read, start_byte))
486                                     != sizeof (PeakData) * to_read) {
487
488                                         off_t fend = lseek (peakfile_fd, 0, SEEK_END);
489
490                                         cerr << "AudioSource["
491                                              << _name
492                                              << "]: cannot read peak data from peakfile ("
493                                              << (nread / sizeof(PeakData))
494                                              << " peaks instead of "
495                                              << to_read
496                                              << ") ("
497                                              << strerror (errno)
498                                              << ')'
499                                              << " at start_byte = " << start_byte
500                                              << " _length = " << _length << " versus len = " << fend
501                                              << " expected maxpeaks = " << (_length - current_frame)/samples_per_file_peak
502                                              << " npeaks was " << npeaks
503                                              << endl;
504                                         goto out;
505                                 }
506
507                                 i = 0;
508                                 stored_peaks_read = nread / sizeof(PeakData);
509                         }
510
511                         xmax = -1.0;
512                         xmin = 1.0;
513
514                         while ((i < stored_peaks_read) && (current_stored_peak <= stored_peak_before_next_visual_peak)) {
515
516                                 xmax = max (xmax, staging[i].max);
517                                 xmin = min (xmin, staging[i].min);
518                                 ++i;
519                                 ++current_stored_peak;
520                                 --expected_peaks;
521                         }
522
523                         peaks[nvisual_peaks].max = xmax;
524                         peaks[nvisual_peaks].min = xmin;
525                         ++nvisual_peaks;
526                         ++next_visual_peak;
527
528                         //next_visual_peak_frame = min ((next_visual_peak * samples_per_visual_peak), (next_visual_peak_frame+samples_per_visual_peak) );
529                         next_visual_peak_frame =  min ((double) start+cnt, (next_visual_peak_frame+samples_per_visual_peak) );
530                         stored_peak_before_next_visual_peak = (uint32_t) next_visual_peak_frame / samples_per_file_peak;
531                 }
532
533                 if (zero_fill) {
534                         memset (&peaks[npeaks], 0, sizeof (PeakData) * zero_fill);
535                 }
536
537                 ret = 0;
538
539         } else {
540
541 #ifdef DEBUG_READ_PEAKS
542                 cerr << "UPSAMPLE\n";
543 #endif
544                 /* the caller wants
545
546                      - less frames-per-peak (more resolution)
547                      - more peaks than stored in the Peakfile
548
549                    So, fetch data from the raw source, and generate peak
550                    data on the fly.
551                 */
552
553                 framecnt_t frames_read = 0;
554                 framepos_t current_frame = start;
555                 framecnt_t i = 0;
556                 framecnt_t nvisual_peaks = 0;
557                 framecnt_t chunksize = (framecnt_t) min (cnt, (framecnt_t) 4096);
558                 raw_staging = new Sample[chunksize];
559
560                 framepos_t frame_pos = start;
561                 double pixel_pos = floor (frame_pos / samples_per_visual_peak);
562                 double next_pixel_pos = ceil (frame_pos / samples_per_visual_peak);
563                 double pixels_per_frame = 1.0 / samples_per_visual_peak;
564
565                 xmin = 1.0;
566                 xmax = -1.0;
567
568                 while (nvisual_peaks < npeaks) {
569
570                         if (i == frames_read) {
571
572                                 to_read = min (chunksize, (framecnt_t)(_length - current_frame));
573
574                                 if (current_frame >= _length) {
575
576                                         /* hmm, error condition - we've reached the end of the file
577                                            without generating all the peak data. cook up a zero-filled
578                                            data buffer and then use it. this is simpler than
579                                            adjusting zero_fill and npeaks and then breaking out of
580                                            this loop early
581                                         */
582
583                                         memset (raw_staging, 0, sizeof (Sample) * chunksize);
584
585                                 } else {
586
587                                         to_read = min (chunksize, (_length - current_frame));
588
589
590                                         if ((frames_read = read_unlocked (raw_staging, current_frame, to_read)) == 0) {
591                                                 error << string_compose(_("AudioSource[%1]: peak read - cannot read %2 samples at offset %3 of %4 (%5)"),
592                                                                         _name, to_read, current_frame, _length, strerror (errno))
593                                                       << endmsg;
594                                                 goto out;
595                                         }
596                                 }
597
598                                 i = 0;
599                         }
600
601                         xmax = max (xmax, raw_staging[i]);
602                         xmin = min (xmin, raw_staging[i]);
603                         ++i;
604                         ++current_frame;
605                         pixel_pos += pixels_per_frame;
606
607                         if (pixel_pos >= next_pixel_pos) {
608
609                                 peaks[nvisual_peaks].max = xmax;
610                                 peaks[nvisual_peaks].min = xmin;
611                                 ++nvisual_peaks;
612                                 xmin = 1.0;
613                                 xmax = -1.0;
614
615                                 next_pixel_pos = ceil (pixel_pos + 0.5);
616                         }
617                 }
618
619                 if (zero_fill) {
620                         memset (&peaks[npeaks], 0, sizeof (PeakData) * zero_fill);
621                 }
622
623                 ret = 0;
624         }
625
626   out:
627         delete peakfile_descriptor;
628
629         delete [] staging;
630         delete [] raw_staging;
631
632 #ifdef DEBUG_READ_PEAKS
633         cerr << "RP DONE\n";
634 #endif
635
636         return ret;
637 }
638
639 #undef DEBUG_PEAK_BUILD
640
641 int
642 AudioSource::build_peaks_from_scratch ()
643 {
644         Sample* buf = 0;
645
646         const framecnt_t bufsize = 65536; // 256kB per disk read for mono data is about ideal
647
648         int ret = -1;
649
650         {
651                 /* hold lock while building peaks */
652
653                 Glib::Mutex::Lock lp (_lock);
654
655                 if (prepare_for_peakfile_writes ()) {
656                         goto out;
657                 }
658
659                 framecnt_t current_frame = 0;
660                 framecnt_t cnt = _length;
661
662                 _peaks_built = false;
663                 buf = new Sample[bufsize];
664
665                 while (cnt) {
666
667                         framecnt_t frames_to_read = min (bufsize, cnt);
668                         framecnt_t frames_read;
669                         
670                         if ((frames_read = read_unlocked (buf, current_frame, frames_to_read)) != frames_to_read) {
671                                 error << string_compose(_("%1: could not write read raw data for peak computation (%2)"), _name, strerror (errno)) << endmsg;
672                                 done_with_peakfile_writes (false);
673                                 goto out;
674                         }
675
676                         if (compute_and_write_peaks (buf, current_frame, frames_read, true, false, _FPP)) {
677                                 break;
678                         }
679
680                         current_frame += frames_read;
681                         cnt -= frames_read;
682                 }
683
684                 if (cnt == 0) {
685                         /* success */
686                         truncate_peakfile();
687                 }
688
689                 done_with_peakfile_writes ((cnt == 0));
690                 if (cnt == 0) {
691                         ret = 0;
692                 }
693         }
694
695   out:
696         if (ret) {
697                 unlink (peakpath.c_str());
698         }
699
700         delete [] buf;
701
702         return ret;
703 }
704
705 int
706 AudioSource::prepare_for_peakfile_writes ()
707 {
708         _peakfile_descriptor = new FdFileDescriptor (peakpath, true, 0664);
709         if ((_peakfile_fd = _peakfile_descriptor->allocate()) < 0) {
710                 error << string_compose(_("AudioSource: cannot open peakpath (c) \"%1\" (%2)"), peakpath, strerror (errno)) << endmsg;
711                 return -1;
712         }
713         return 0;
714 }
715
716 void
717 AudioSource::done_with_peakfile_writes (bool done)
718 {
719         if (peak_leftover_cnt) {
720                 compute_and_write_peaks (0, 0, 0, true, false, _FPP);
721         }
722
723         if (done) {
724                 Glib::Mutex::Lock lm (_peaks_ready_lock);
725                 _peaks_built = true;
726                 PeaksReady (); /* EMIT SIGNAL */
727         }
728
729         delete _peakfile_descriptor;
730         _peakfile_descriptor = 0;
731 }
732
733 /** @param first_frame Offset from the source start of the first frame to process */
734 int
735 AudioSource::compute_and_write_peaks (Sample* buf, framecnt_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, framecnt_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                         if (ftruncate (_peakfile_fd, target_length)) {
884                                 /* error doesn't actually matter so continue on without testing */
885                         }
886                 }
887         }
888
889         if (::pwrite (_peakfile_fd, peakbuf, sizeof (PeakData) * peaks_computed, first_peak_byte) != (ssize_t) (sizeof (PeakData) * peaks_computed)) {
890                 error << string_compose(_("%1: could not write peak file data (%2)"), _name, strerror (errno)) << endmsg;
891                 goto out;
892         }
893
894         _peak_byte_max = max (_peak_byte_max, (off_t) (first_peak_byte + sizeof(PeakData)*peaks_computed));
895
896         if (frames_done) {
897                 Glib::Mutex::Lock lm (_peaks_ready_lock);
898                 PeakRangeReady (first_frame, frames_done); /* EMIT SIGNAL */
899                 if (intermediate_peaks_ready) {
900                         PeaksReady (); /* EMIT SIGNAL */
901                 }
902         }
903
904         ret = 0;
905
906   out:
907         delete [] peakbuf;
908         delete [] buf2;
909
910         return ret;
911 }
912
913 void
914 AudioSource::truncate_peakfile ()
915 {
916         if (_peakfile_descriptor == 0) {
917                 error << string_compose (_("programming error: %1"), "AudioSource::truncate_peakfile() called without open peakfile descriptor")
918                       << endmsg;
919                 return;
920         }
921
922         /* truncate the peakfile down to its natural length if necessary */
923
924         off_t end = lseek (_peakfile_fd, 0, SEEK_END);
925
926         if (end > _peak_byte_max) {
927                 if (ftruncate (_peakfile_fd, _peak_byte_max)) {
928                         error << string_compose (_("could not truncate peakfile %1 to %2 (error: %3)"),
929                                                  peakpath, _peak_byte_max, errno) << endmsg;
930                 }
931         }
932 }
933
934 framecnt_t
935 AudioSource::available_peaks (double zoom_factor) const
936 {
937         if (zoom_factor < _FPP) {
938                 return length(_timeline_position); // peak data will come from the audio file
939         }
940
941         /* peak data comes from peakfile, but the filesize might not represent
942            the valid data due to ftruncate optimizations, so use _peak_byte_max state.
943            XXX - there might be some atomicity issues here, we should probably add a lock,
944            but _peak_byte_max only monotonically increases after initialization.
945         */
946
947         off_t end = _peak_byte_max;
948
949         return (end/sizeof(PeakData)) * _FPP;
950 }
951
952 void
953 AudioSource::mark_streaming_write_completed ()
954 {
955         Glib::Mutex::Lock lm (_peaks_ready_lock);
956
957         if (_peaks_built) {
958                 PeaksReady (); /* EMIT SIGNAL */
959         }
960 }
961
962 void
963 AudioSource::allocate_working_buffers (framecnt_t framerate)
964 {
965         Glib::Mutex::Lock lm (_level_buffer_lock);
966
967
968         /* Note: we don't need any buffers allocated until
969            a level 1 audiosource is created, at which
970            time we'll call ::ensure_buffers_for_level()
971            with the right value and do the right thing.
972         */
973
974         if (!_mixdown_buffers.empty()) {
975                 ensure_buffers_for_level_locked ( _mixdown_buffers.size(), framerate);
976         }
977 }
978
979 void
980 AudioSource::ensure_buffers_for_level (uint32_t level, framecnt_t frame_rate)
981 {
982         Glib::Mutex::Lock lm (_level_buffer_lock);
983         ensure_buffers_for_level_locked (level, frame_rate);
984 }
985
986 void
987 AudioSource::ensure_buffers_for_level_locked (uint32_t level, framecnt_t frame_rate)
988 {
989         framecnt_t nframes = (framecnt_t) floor (Config->get_audio_playback_buffer_seconds() * frame_rate);
990
991         _mixdown_buffers.clear ();
992         _gain_buffers.clear ();
993
994         while (_mixdown_buffers.size() < level) {
995                 _mixdown_buffers.push_back (boost::shared_ptr<Sample> (new Sample[nframes]));
996                 _gain_buffers.push_back (boost::shared_ptr<gain_t> (new gain_t[nframes]));
997         }
998 }