fix a few warnings from newer versions of gcc
[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                 delete peakfile_descriptor;
402
403                 if (nread != sizeof (PeakData) * npeaks) {
404                         cerr << "AudioSource["
405                              << _name
406                              << "]: cannot read peaks from peakfile! (read only "
407                              << nread
408                              << " not "
409                              << npeaks
410                               << "at sample "
411                              << start
412                              << " = byte "
413                              << first_peak_byte
414                              << ')'
415                              << endl;
416                         delete peakfile_descriptor;
417                         return -1;
418                 }
419
420                 if (zero_fill) {
421                         memset (&peaks[npeaks], 0, sizeof (PeakData) * zero_fill);
422                 }
423
424                 delete peakfile_descriptor;
425                 return 0;
426         }
427
428
429         framecnt_t tnp;
430
431         if (scale < 1.0) {
432
433 #ifdef DEBUG_READ_PEAKS
434                 cerr << "DOWNSAMPLE\n";
435 #endif
436                 /* the caller wants:
437
438                     - more frames-per-peak (lower resolution) than the peakfile, or to put it another way,
439                     - less peaks than the peakfile holds for the same range
440
441                     So, read a block into a staging area, and then downsample from there.
442
443                     to avoid confusion, I'll refer to the requested peaks as visual_peaks and the peakfile peaks as stored_peaks
444                 */
445
446                 const framecnt_t chunksize = (framecnt_t) min (expected_peaks, 65536.0);
447
448                 staging = new PeakData[chunksize];
449
450                 /* compute the rounded up frame position  */
451
452                 framepos_t current_frame = start;
453                 framepos_t current_stored_peak = (framepos_t) ceil (current_frame / (double) samples_per_file_peak);
454                 framepos_t next_visual_peak  = (framepos_t) ceil (current_frame / samples_per_visual_peak);
455                 double     next_visual_peak_frame = next_visual_peak * samples_per_visual_peak;
456                 framepos_t stored_peak_before_next_visual_peak = (framepos_t) next_visual_peak_frame / samples_per_file_peak;
457                 framecnt_t nvisual_peaks = 0;
458                 framecnt_t stored_peaks_read = 0;
459                 framecnt_t i = 0;
460
461                 /* handle the case where the initial visual peak is on a pixel boundary */
462
463                 current_stored_peak = min (current_stored_peak, stored_peak_before_next_visual_peak);
464
465                 /* open ... close during out: handling */
466
467                 if ((peakfile_fd = peakfile_descriptor->allocate ()) < 0) {
468                         error << string_compose(_("AudioSource: cannot open peakpath (b) \"%1\" (%2)"), peakpath, strerror (errno)) << endmsg;
469                         delete peakfile_descriptor;
470                         delete [] staging;
471                         return 0;
472                 }
473
474                 while (nvisual_peaks < npeaks) {
475
476                         if (i == stored_peaks_read) {
477
478                                 uint32_t       start_byte = current_stored_peak * sizeof(PeakData);
479                                 tnp = min ((framecnt_t)(_length/samples_per_file_peak - current_stored_peak), (framecnt_t) expected_peaks);
480                                 to_read = min (chunksize, tnp);
481
482 #ifdef DEBUG_READ_PEAKS
483                                 cerr << "read " << sizeof (PeakData) * to_read << " from peakfile @ " << start_byte << endl;
484 #endif
485
486                                 if ((nread = ::pread (peakfile_fd, staging, sizeof (PeakData) * to_read, start_byte))
487                                     != sizeof (PeakData) * to_read) {
488
489                                         off_t fend = lseek (peakfile_fd, 0, SEEK_END);
490
491                                         cerr << "AudioSource["
492                                              << _name
493                                              << "]: cannot read peak data from peakfile ("
494                                              << (nread / sizeof(PeakData))
495                                              << " peaks instead of "
496                                              << to_read
497                                              << ") ("
498                                              << strerror (errno)
499                                              << ')'
500                                              << " at start_byte = " << start_byte
501                                              << " _length = " << _length << " versus len = " << fend
502                                              << " expected maxpeaks = " << (_length - current_frame)/samples_per_file_peak
503                                              << " npeaks was " << npeaks
504                                              << endl;
505                                         goto out;
506                                 }
507
508                                 i = 0;
509                                 stored_peaks_read = nread / sizeof(PeakData);
510                         }
511
512                         xmax = -1.0;
513                         xmin = 1.0;
514
515                         while ((i < stored_peaks_read) && (current_stored_peak <= stored_peak_before_next_visual_peak)) {
516
517                                 xmax = max (xmax, staging[i].max);
518                                 xmin = min (xmin, staging[i].min);
519                                 ++i;
520                                 ++current_stored_peak;
521                                 --expected_peaks;
522                         }
523
524                         peaks[nvisual_peaks].max = xmax;
525                         peaks[nvisual_peaks].min = xmin;
526                         ++nvisual_peaks;
527                         ++next_visual_peak;
528
529                         //next_visual_peak_frame = min ((next_visual_peak * samples_per_visual_peak), (next_visual_peak_frame+samples_per_visual_peak) );
530                         next_visual_peak_frame =  min ((double) start+cnt, (next_visual_peak_frame+samples_per_visual_peak) );
531                         stored_peak_before_next_visual_peak = (uint32_t) next_visual_peak_frame / samples_per_file_peak;
532                 }
533
534                 if (zero_fill) {
535                         memset (&peaks[npeaks], 0, sizeof (PeakData) * zero_fill);
536                 }
537
538                 ret = 0;
539
540         } else {
541
542 #ifdef DEBUG_READ_PEAKS
543                 cerr << "UPSAMPLE\n";
544 #endif
545                 /* the caller wants
546
547                      - less frames-per-peak (more resolution)
548                      - more peaks than stored in the Peakfile
549
550                    So, fetch data from the raw source, and generate peak
551                    data on the fly.
552                 */
553
554                 framecnt_t frames_read = 0;
555                 framepos_t current_frame = start;
556                 framecnt_t i = 0;
557                 framecnt_t nvisual_peaks = 0;
558                 framecnt_t chunksize = (framecnt_t) min (cnt, (framecnt_t) 4096);
559                 raw_staging = new Sample[chunksize];
560
561                 framepos_t frame_pos = start;
562                 double pixel_pos = floor (frame_pos / samples_per_visual_peak);
563                 double next_pixel_pos = ceil (frame_pos / samples_per_visual_peak);
564                 double pixels_per_frame = 1.0 / samples_per_visual_peak;
565
566                 xmin = 1.0;
567                 xmax = -1.0;
568
569                 while (nvisual_peaks < npeaks) {
570
571                         if (i == frames_read) {
572
573                                 to_read = min (chunksize, (framecnt_t)(_length - current_frame));
574
575                                 if (current_frame >= _length) {
576
577                                         /* hmm, error condition - we've reached the end of the file
578                                            without generating all the peak data. cook up a zero-filled
579                                            data buffer and then use it. this is simpler than
580                                            adjusting zero_fill and npeaks and then breaking out of
581                                            this loop early
582                                         */
583
584                                         memset (raw_staging, 0, sizeof (Sample) * chunksize);
585
586                                 } else {
587
588                                         to_read = min (chunksize, (_length - current_frame));
589
590
591                                         if ((frames_read = read_unlocked (raw_staging, current_frame, to_read)) == 0) {
592                                                 error << string_compose(_("AudioSource[%1]: peak read - cannot read %2 samples at offset %3 of %4 (%5)"),
593                                                                         _name, to_read, current_frame, _length, strerror (errno))
594                                                       << endmsg;
595                                                 goto out;
596                                         }
597                                 }
598
599                                 i = 0;
600                         }
601
602                         xmax = max (xmax, raw_staging[i]);
603                         xmin = min (xmin, raw_staging[i]);
604                         ++i;
605                         ++current_frame;
606                         pixel_pos += pixels_per_frame;
607
608                         if (pixel_pos >= next_pixel_pos) {
609
610                                 peaks[nvisual_peaks].max = xmax;
611                                 peaks[nvisual_peaks].min = xmin;
612                                 ++nvisual_peaks;
613                                 xmin = 1.0;
614                                 xmax = -1.0;
615
616                                 next_pixel_pos = ceil (pixel_pos + 0.5);
617                         }
618                 }
619
620                 if (zero_fill) {
621                         memset (&peaks[npeaks], 0, sizeof (PeakData) * zero_fill);
622                 }
623
624                 ret = 0;
625         }
626
627   out:
628         delete peakfile_descriptor;
629
630         delete [] staging;
631         delete [] raw_staging;
632
633 #ifdef DEBUG_READ_PEAKS
634         cerr << "RP DONE\n";
635 #endif
636
637         return ret;
638 }
639
640 #undef DEBUG_PEAK_BUILD
641
642 int
643 AudioSource::build_peaks_from_scratch ()
644 {
645         Sample* buf = 0;
646
647         const framecnt_t bufsize = 65536; // 256kB per disk read for mono data is about ideal
648
649         int ret = -1;
650
651         {
652                 /* hold lock while building peaks */
653
654                 Glib::Mutex::Lock lp (_lock);
655
656                 if (prepare_for_peakfile_writes ()) {
657                         goto out;
658                 }
659
660                 framecnt_t current_frame = 0;
661                 framecnt_t cnt = _length;
662
663                 _peaks_built = false;
664                 buf = new Sample[bufsize];
665
666                 while (cnt) {
667
668                         framecnt_t frames_to_read = min (bufsize, cnt);
669                         framecnt_t frames_read;
670                         
671                         if ((frames_read = read_unlocked (buf, current_frame, frames_to_read)) != frames_to_read) {
672                                 error << string_compose(_("%1: could not write read raw data for peak computation (%2)"), _name, strerror (errno)) << endmsg;
673                                 done_with_peakfile_writes (false);
674                                 goto out;
675                         }
676
677                         if (compute_and_write_peaks (buf, current_frame, frames_read, true, false, _FPP)) {
678                                 break;
679                         }
680
681                         current_frame += frames_read;
682                         cnt -= frames_read;
683                 }
684
685                 if (cnt == 0) {
686                         /* success */
687                         truncate_peakfile();
688                 }
689
690                 done_with_peakfile_writes ((cnt == 0));
691                 if (cnt == 0) {
692                         ret = 0;
693                 }
694         }
695
696   out:
697         if (ret) {
698                 unlink (peakpath.c_str());
699         }
700
701         delete [] buf;
702
703         return ret;
704 }
705
706 int
707 AudioSource::prepare_for_peakfile_writes ()
708 {
709         _peakfile_descriptor = new FdFileDescriptor (peakpath, true, 0664);
710         if ((_peakfile_fd = _peakfile_descriptor->allocate()) < 0) {
711                 error << string_compose(_("AudioSource: cannot open peakpath (c) \"%1\" (%2)"), peakpath, strerror (errno)) << endmsg;
712                 return -1;
713         }
714         return 0;
715 }
716
717 void
718 AudioSource::done_with_peakfile_writes (bool done)
719 {
720         if (peak_leftover_cnt) {
721                 compute_and_write_peaks (0, 0, 0, true, false, _FPP);
722         }
723
724         if (done) {
725                 Glib::Mutex::Lock lm (_peaks_ready_lock);
726                 _peaks_built = true;
727                 PeaksReady (); /* EMIT SIGNAL */
728         }
729
730         delete _peakfile_descriptor;
731         _peakfile_descriptor = 0;
732 }
733
734 /** @param first_frame Offset from the source start of the first frame to process */
735 int
736 AudioSource::compute_and_write_peaks (Sample* buf, framecnt_t first_frame, framecnt_t cnt,
737                                       bool force, bool intermediate_peaks_ready)
738 {
739         return compute_and_write_peaks (buf, first_frame, cnt, force, intermediate_peaks_ready, _FPP);
740 }
741
742 int
743 AudioSource::compute_and_write_peaks (Sample* buf, framecnt_t first_frame, framecnt_t cnt,
744                                       bool force, bool intermediate_peaks_ready, framecnt_t fpp)
745 {
746         Sample* buf2 = 0;
747         framecnt_t to_do;
748         uint32_t  peaks_computed;
749         PeakData* peakbuf = 0;
750         int ret = -1;
751         framepos_t current_frame;
752         framecnt_t frames_done;
753         const size_t blocksize = (128 * 1024);
754         off_t first_peak_byte;
755
756         if (_peakfile_descriptor == 0) {
757                 prepare_for_peakfile_writes ();
758         }
759
760   restart:
761         if (peak_leftover_cnt) {
762
763                 if (first_frame != peak_leftover_frame + peak_leftover_cnt) {
764
765                         /* uh-oh, ::seek() since the last ::compute_and_write_peaks(),
766                            and we have leftovers. flush a single peak (since the leftovers
767                            never represent more than that, and restart.
768                         */
769
770                         PeakData x;
771
772                         x.min = peak_leftovers[0];
773                         x.max = peak_leftovers[0];
774
775                         off_t byte = (peak_leftover_frame / fpp) * sizeof (PeakData);
776
777                         if (::pwrite (_peakfile_fd, &x, sizeof (PeakData), byte) != sizeof (PeakData)) {
778                                 error << string_compose(_("%1: could not write peak file data (%2)"), _name, strerror (errno)) << endmsg;
779                                 goto out;
780                         }
781
782                         _peak_byte_max = max (_peak_byte_max, (off_t) (byte + sizeof(PeakData)));
783
784                         {
785                                 Glib::Mutex::Lock lm (_peaks_ready_lock);
786                                 PeakRangeReady (peak_leftover_frame, peak_leftover_cnt); /* EMIT SIGNAL */
787                                 if (intermediate_peaks_ready) {
788                                         PeaksReady (); /* EMIT SIGNAL */
789                                 }
790                         }
791
792                         /* left overs are done */
793
794                         peak_leftover_cnt = 0;
795                         goto restart;
796                 }
797
798                 /* else ... had leftovers, but they immediately preceed the new data, so just
799                    merge them and compute.
800                 */
801
802                 /* make a new contiguous buffer containing leftovers and the new stuff */
803
804                 to_do = cnt + peak_leftover_cnt;
805                 buf2 = new Sample[to_do];
806
807                 /* the remnants */
808                 memcpy (buf2, peak_leftovers, peak_leftover_cnt * sizeof (Sample));
809
810                 /* the new stuff */
811                 memcpy (buf2+peak_leftover_cnt, buf, cnt * sizeof (Sample));
812
813                 /* no more leftovers */
814                 peak_leftover_cnt = 0;
815
816                 /* use the temporary buffer */
817                 buf = buf2;
818
819                 /* make sure that when we write into the peakfile, we startup where we left off */
820
821                 first_frame = peak_leftover_frame;
822
823         } else {
824                 to_do = cnt;
825         }
826
827         peakbuf = new PeakData[(to_do/fpp)+1];
828         peaks_computed = 0;
829         current_frame = first_frame;
830         frames_done = 0;
831
832         while (to_do) {
833
834                 /* if some frames were passed in (i.e. we're not flushing leftovers)
835                    and there are less than fpp to do, save them till
836                    next time
837                 */
838
839                 if (force && (to_do < fpp)) {
840                         /* keep the left overs around for next time */
841
842                         if (peak_leftover_size < to_do) {
843                                 delete [] peak_leftovers;
844                                 peak_leftovers = new Sample[to_do];
845                                 peak_leftover_size = to_do;
846                         }
847                         memcpy (peak_leftovers, buf, to_do * sizeof (Sample));
848                         peak_leftover_cnt = to_do;
849                         peak_leftover_frame = current_frame;
850
851                         /* done for now */
852
853                         break;
854                 }
855
856                 framecnt_t this_time = min (fpp, to_do);
857
858                 peakbuf[peaks_computed].max = buf[0];
859                 peakbuf[peaks_computed].min = buf[0];
860
861                 ARDOUR::find_peaks (buf+1, this_time-1, &peakbuf[peaks_computed].min, &peakbuf[peaks_computed].max);
862
863                 peaks_computed++;
864                 buf += this_time;
865                 to_do -= this_time;
866                 frames_done += this_time;
867                 current_frame += this_time;
868         }
869
870         first_peak_byte = (first_frame / fpp) * sizeof (PeakData);
871
872         if (can_truncate_peaks()) {
873
874                 /* on some filesystems (ext3, at least) this helps to reduce fragmentation of
875                    the peakfiles. its not guaranteed to do so, and even on ext3 (as of december 2006)
876                    it does not cause single-extent allocation even for peakfiles of
877                    less than BLOCKSIZE bytes.  only call ftruncate if we'll make the file larger.
878                 */
879
880                 off_t endpos = lseek (_peakfile_fd, 0, SEEK_END);
881                 off_t target_length = blocksize * ((first_peak_byte + blocksize + 1) / blocksize);
882
883                 if (endpos < target_length) {
884                         if (ftruncate (_peakfile_fd, target_length)) {
885                                 /* error doesn't actually matter so continue on without testing */
886                         }
887                 }
888         }
889
890         if (::pwrite (_peakfile_fd, peakbuf, sizeof (PeakData) * peaks_computed, first_peak_byte) != (ssize_t) (sizeof (PeakData) * peaks_computed)) {
891                 error << string_compose(_("%1: could not write peak file data (%2)"), _name, strerror (errno)) << endmsg;
892                 goto out;
893         }
894
895         _peak_byte_max = max (_peak_byte_max, (off_t) (first_peak_byte + sizeof(PeakData)*peaks_computed));
896
897         if (frames_done) {
898                 Glib::Mutex::Lock lm (_peaks_ready_lock);
899                 PeakRangeReady (first_frame, frames_done); /* EMIT SIGNAL */
900                 if (intermediate_peaks_ready) {
901                         PeaksReady (); /* EMIT SIGNAL */
902                 }
903         }
904
905         ret = 0;
906
907   out:
908         delete [] peakbuf;
909         delete [] buf2;
910
911         return ret;
912 }
913
914 void
915 AudioSource::truncate_peakfile ()
916 {
917         if (_peakfile_descriptor == 0) {
918                 error << string_compose (_("programming error: %1"), "AudioSource::truncate_peakfile() called without open peakfile descriptor")
919                       << endmsg;
920                 return;
921         }
922
923         /* truncate the peakfile down to its natural length if necessary */
924
925         off_t end = lseek (_peakfile_fd, 0, SEEK_END);
926
927         if (end > _peak_byte_max) {
928                 if (ftruncate (_peakfile_fd, _peak_byte_max)) {
929                         error << string_compose (_("could not truncate peakfile %1 to %2 (error: %3)"),
930                                                  peakpath, _peak_byte_max, errno) << endmsg;
931                 }
932         }
933 }
934
935 framecnt_t
936 AudioSource::available_peaks (double zoom_factor) const
937 {
938         if (zoom_factor < _FPP) {
939                 return length(_timeline_position); // peak data will come from the audio file
940         }
941
942         /* peak data comes from peakfile, but the filesize might not represent
943            the valid data due to ftruncate optimizations, so use _peak_byte_max state.
944            XXX - there might be some atomicity issues here, we should probably add a lock,
945            but _peak_byte_max only monotonically increases after initialization.
946         */
947
948         off_t end = _peak_byte_max;
949
950         return (end/sizeof(PeakData)) * _FPP;
951 }
952
953 void
954 AudioSource::mark_streaming_write_completed ()
955 {
956         Glib::Mutex::Lock lm (_peaks_ready_lock);
957
958         if (_peaks_built) {
959                 PeaksReady (); /* EMIT SIGNAL */
960         }
961 }
962
963 void
964 AudioSource::allocate_working_buffers (framecnt_t framerate)
965 {
966         Glib::Mutex::Lock lm (_level_buffer_lock);
967
968
969         /* Note: we don't need any buffers allocated until
970            a level 1 audiosource is created, at which
971            time we'll call ::ensure_buffers_for_level()
972            with the right value and do the right thing.
973         */
974
975         if (!_mixdown_buffers.empty()) {
976                 ensure_buffers_for_level_locked ( _mixdown_buffers.size(), framerate);
977         }
978 }
979
980 void
981 AudioSource::ensure_buffers_for_level (uint32_t level, framecnt_t frame_rate)
982 {
983         Glib::Mutex::Lock lm (_level_buffer_lock);
984         ensure_buffers_for_level_locked (level, frame_rate);
985 }
986
987 void
988 AudioSource::ensure_buffers_for_level_locked (uint32_t level, framecnt_t frame_rate)
989 {
990         framecnt_t nframes = (framecnt_t) floor (Config->get_audio_playback_buffer_seconds() * frame_rate);
991
992         _mixdown_buffers.clear ();
993         _gain_buffers.clear ();
994
995         while (_mixdown_buffers.size() < level) {
996                 _mixdown_buffers.push_back (boost::shared_ptr<Sample> (new Sample[nframes]));
997                 _gain_buffers.push_back (boost::shared_ptr<gain_t> (new gain_t[nframes]));
998         }
999 }