debug instrumentation for locate time
[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 #ifdef COMPILER_MSVC
21 #include <sys/utime.h>
22 #else
23 #include <unistd.h>
24 #include <utime.h>
25 #endif
26 #include <sys/stat.h>
27 #include <fcntl.h>
28 #include <float.h>
29 #include <cerrno>
30 #include <ctime>
31 #include <cmath>
32 #include <iomanip>
33 #include <algorithm>
34 #include <vector>
35
36 #ifdef PLATFORM_WINDOWS
37 #include <windows.h>
38
39 #else
40 #include <sys/mman.h>
41
42 #endif
43
44 #include <glib.h>
45 #include "pbd/gstdio_compat.h"
46
47 #include <boost/scoped_ptr.hpp>
48
49 #include <glibmm/fileutils.h>
50 #include <glibmm/miscutils.h>
51
52 #include "pbd/file_utils.h"
53 #include "pbd/scoped_file_descriptor.h"
54 #include "pbd/xml++.h"
55
56 #include "ardour/audiosource.h"
57 #include "ardour/rc_configuration.h"
58 #include "ardour/runtime_functions.h"
59 #include "ardour/session.h"
60
61 #include "pbd/i18n.h"
62
63 #include "ardour/debug.h"
64
65 using namespace std;
66 using namespace ARDOUR;
67 using namespace PBD;
68
69 Glib::Threads::Mutex AudioSource::_level_buffer_lock;
70 vector<boost::shared_array<Sample> > AudioSource::_mixdown_buffers;
71 vector<boost::shared_array<gain_t> > AudioSource::_gain_buffers;
72 bool AudioSource::_build_missing_peakfiles = false;
73
74 /** true if we want peakfiles (e.g. if we are displaying a GUI) */
75 bool AudioSource::_build_peakfiles = false;
76
77 #define _FPP 256
78
79 AudioSource::AudioSource (Session& s, const string& name)
80         : Source (s, DataType::AUDIO, name)
81         , _length (0)
82         , _peak_byte_max (0)
83         , _peaks_built (false)
84         , _peakfile_fd (-1)
85         , peak_leftover_cnt (0)
86         , peak_leftover_size (0)
87         , peak_leftovers (0)
88         , _first_run (true)
89         , _last_scale (0.0)
90         , _last_map_off (0)
91         , _last_raw_map_length (0)
92 {
93 }
94
95 AudioSource::AudioSource (Session& s, const XMLNode& node)
96         : Source (s, node)
97         , _length (0)
98         , _peak_byte_max (0)
99         , _peaks_built (false)
100         , _peakfile_fd (-1)
101         , peak_leftover_cnt (0)
102         , peak_leftover_size (0)
103         , peak_leftovers (0)
104         , _first_run (true)
105         , _last_scale (0.0)
106         , _last_map_off (0)
107         , _last_raw_map_length (0)
108 {
109         if (set_state (node, Stateful::loading_state_version)) {
110                 throw failed_constructor();
111         }
112 }
113
114 AudioSource::~AudioSource ()
115 {
116         /* shouldn't happen but make sure we don't leak file descriptors anyway */
117
118         if (peak_leftover_cnt) {
119                 cerr << "AudioSource destroyed with leftover peak data pending" << endl;
120         }
121
122         if ((-1) != _peakfile_fd) {
123                 close (_peakfile_fd);
124                 _peakfile_fd = -1;
125         }
126
127         delete [] peak_leftovers;
128 }
129
130 XMLNode&
131 AudioSource::get_state ()
132 {
133         XMLNode& node (Source::get_state());
134
135         if (_captured_for.length()) {
136                 node.set_property ("captured-for", _captured_for);
137         }
138
139         return node;
140 }
141
142 int
143 AudioSource::set_state (const XMLNode& node, int /*version*/)
144 {
145         node.get_property ("captured-for", _captured_for);
146         return 0;
147 }
148
149 bool
150 AudioSource::empty () const
151 {
152         return _length == 0;
153 }
154
155 framecnt_t
156 AudioSource::length (framepos_t /*pos*/) const
157 {
158         return _length;
159 }
160
161 void
162 AudioSource::update_length (framecnt_t len)
163 {
164         if (len > _length) {
165                 _length = len;
166         }
167 }
168
169
170 /***********************************************************************
171   PEAK FILE STUFF
172  ***********************************************************************/
173
174 /** Checks to see if peaks are ready.  If so, we return true.  If not, we return false, and
175  *  things are set up so that doThisWhenReady is called when the peaks are ready.
176  *  A new PBD::ScopedConnection is created for the associated connection and written to
177  *  *connect_here_if_not.
178  *
179  *  @param doThisWhenReady Function to call when peaks are ready (if they are not already).
180  *  @param connect_here_if_not Address to write new ScopedConnection to.
181  *  @param event_loop Event loop for doThisWhenReady to be called in.
182  */
183 bool
184 AudioSource::peaks_ready (boost::function<void()> doThisWhenReady, ScopedConnection** connect_here_if_not, EventLoop* event_loop) const
185 {
186         bool ret;
187         Glib::Threads::Mutex::Lock lm (_peaks_ready_lock);
188
189         if (!(ret = _peaks_built)) {
190                 *connect_here_if_not = new ScopedConnection;
191                 PeaksReady.connect (**connect_here_if_not, MISSING_INVALIDATOR, doThisWhenReady, event_loop);
192         }
193
194         return ret;
195 }
196
197 void
198 AudioSource::touch_peakfile ()
199 {
200         GStatBuf statbuf;
201
202         if (g_stat (_peakpath.c_str(), &statbuf) != 0 || statbuf.st_size == 0) {
203                 return;
204         }
205
206         struct utimbuf tbuf;
207
208         tbuf.actime = statbuf.st_atime;
209         tbuf.modtime = time ((time_t*) 0);
210
211         g_utime (_peakpath.c_str(), &tbuf);
212 }
213
214 int
215 AudioSource::rename_peakfile (string newpath)
216 {
217         /* caller must hold _lock */
218
219         string oldpath = _peakpath;
220
221         if (Glib::file_test (oldpath, Glib::FILE_TEST_EXISTS)) {
222                 if (g_rename (oldpath.c_str(), newpath.c_str()) != 0) {
223                         error << string_compose (_("cannot rename peakfile for %1 from %2 to %3 (%4)"), _name, oldpath, newpath, strerror (errno)) << endmsg;
224                         return -1;
225                 }
226         }
227
228         _peakpath = newpath;
229
230         return 0;
231 }
232
233 int
234 AudioSource::initialize_peakfile (const string& audio_path, const bool in_session)
235 {
236         Glib::Threads::Mutex::Lock lm (_initialize_peaks_lock);
237         GStatBuf statbuf;
238
239         _peakpath = construct_peak_filepath (audio_path, in_session);
240
241         if (!empty() && !Glib::file_test (_peakpath.c_str(), Glib::FILE_TEST_EXISTS)) {
242                 string oldpeak = construct_peak_filepath (audio_path, in_session, true);
243                 DEBUG_TRACE(DEBUG::Peaks, string_compose ("Looking for old peak file %1 for Audio file %2\n", oldpeak, audio_path));
244                 if (Glib::file_test (oldpeak.c_str(), Glib::FILE_TEST_EXISTS)) {
245                         // TODO use hard-link if possible
246                         DEBUG_TRACE(DEBUG::Peaks, string_compose ("Copy old peakfile %1 to %2\n", oldpeak, _peakpath));
247                         PBD::copy_file (oldpeak, _peakpath);
248                 }
249         }
250
251         DEBUG_TRACE(DEBUG::Peaks, string_compose ("Initialize Peakfile %1 for Audio file %2\n", _peakpath, audio_path));
252
253         if (g_stat (_peakpath.c_str(), &statbuf)) {
254                 if (errno != ENOENT) {
255                         /* it exists in the peaks dir, but there is some kind of error */
256
257                         error << string_compose(_("AudioSource: cannot stat peakfile \"%1\""), _peakpath) << endmsg;
258                         return -1;
259                 }
260
261                 DEBUG_TRACE(DEBUG::Peaks, string_compose("Peakfile %1 does not exist\n", _peakpath));
262
263                 _peaks_built = false;
264
265         } else {
266
267                 /* we found it in the peaks dir, so check it out */
268
269                 if (statbuf.st_size == 0 || (statbuf.st_size < (off_t) ((length(_timeline_position) / _FPP) * sizeof (PeakData)))) {
270                         DEBUG_TRACE(DEBUG::Peaks, string_compose("Peakfile %1 is empty\n", _peakpath));
271                         _peaks_built = false;
272                 } else {
273                         // Check if the audio file has changed since the peakfile was built.
274                         GStatBuf stat_file;
275                         int err = g_stat (audio_path.c_str(), &stat_file);
276
277                         if (err) {
278
279                                 /* no audio path - nested source or we can't
280                                    read it or ... whatever, use the peakfile as-is.
281                                 */
282                                 DEBUG_TRACE(DEBUG::Peaks, string_compose("Error when calling stat on Peakfile %1\n", _peakpath));
283
284                                 _peaks_built = true;
285                                 _peak_byte_max = statbuf.st_size;
286
287                         } else {
288
289                                 /* allow 6 seconds slop on checking peak vs. file times because of various
290                                    disk action "races"
291                                 */
292
293                                 if (stat_file.st_mtime > statbuf.st_mtime && (stat_file.st_mtime - statbuf.st_mtime > 6)) {
294                                         _peaks_built = false;
295                                         _peak_byte_max = 0;
296                                 } else {
297                                         _peaks_built = true;
298                                         _peak_byte_max = statbuf.st_size;
299                                 }
300                         }
301                 }
302         }
303
304         if (!empty() && !_peaks_built && _build_missing_peakfiles && _build_peakfiles) {
305                 build_peaks_from_scratch ();
306         }
307
308         return 0;
309 }
310
311 framecnt_t
312 AudioSource::read (Sample *dst, framepos_t start, framecnt_t cnt, int /*channel*/) const
313 {
314         assert (cnt >= 0);
315
316         Glib::Threads::Mutex::Lock lm (_lock);
317         return read_unlocked (dst, start, cnt);
318 }
319
320 framecnt_t
321 AudioSource::write (Sample *dst, framecnt_t cnt)
322 {
323         Glib::Threads::Mutex::Lock lm (_lock);
324         /* any write makes the file not removable */
325         _flags = Flag (_flags & ~Removable);
326         return write_unlocked (dst, cnt);
327 }
328
329 int
330 AudioSource::read_peaks (PeakData *peaks, framecnt_t npeaks, framepos_t start, framecnt_t cnt, double samples_per_visual_peak) const
331 {
332         return read_peaks_with_fpp (peaks, npeaks, start, cnt, samples_per_visual_peak, _FPP);
333 }
334
335 /** @param peaks Buffer to write peak data.
336  *  @param npeaks Number of peaks to write.
337  */
338
339 int
340 AudioSource::read_peaks_with_fpp (PeakData *peaks, framecnt_t npeaks, framepos_t start, framecnt_t cnt,
341                                   double samples_per_visual_peak, framecnt_t samples_per_file_peak) const
342 {
343         Glib::Threads::Mutex::Lock lm (_lock);
344         double scale;
345         double expected_peaks;
346         PeakData::PeakDatum xmax;
347         PeakData::PeakDatum xmin;
348         int32_t to_read;
349 #ifdef PLATFORM_WINDOWS
350         SYSTEM_INFO system_info;
351         GetSystemInfo (&system_info);
352         const int bufsize = system_info.dwAllocationGranularity;;
353 #else
354         const int bufsize = sysconf(_SC_PAGESIZE);
355 #endif
356         framecnt_t read_npeaks = npeaks;
357         framecnt_t zero_fill = 0;
358
359         GStatBuf statbuf;
360
361         expected_peaks = (cnt / (double) samples_per_file_peak);
362         if (g_stat (_peakpath.c_str(), &statbuf) != 0) {
363                 error << string_compose (_("Cannot open peakfile @ %1 for size check (%2)"), _peakpath, strerror (errno)) << endmsg;
364                 return -1;
365         }
366
367         if (!_captured_for.empty()) {
368
369                 /* _captured_for is only set after a capture pass is
370                  * complete. so we know that capturing is finished for this
371                  * file, and now we can check actual size of the peakfile is at
372                  * least large enough for all the data in the audio file. if it
373                  * is too short, assume that a crash or other error truncated
374                  * it, and rebuild it from scratch.
375                  *
376                  * XXX this may not work for destructive recording, but we
377                  * might decided to get rid of that anyway.
378                  *
379                  */
380
381                 const off_t expected_file_size = (_length / (double) samples_per_file_peak) * sizeof (PeakData);
382
383                 if (statbuf.st_size < expected_file_size) {
384                         warning << string_compose (_("peak file %1 is truncated from %2 to %3"), _peakpath, expected_file_size, statbuf.st_size) << endmsg;
385                         lm.release(); // build_peaks_from_scratch() takes _lock
386                         const_cast<AudioSource*>(this)->build_peaks_from_scratch ();
387                         lm.acquire ();
388                         if (g_stat (_peakpath.c_str(), &statbuf) != 0) {
389                                 error << string_compose (_("Cannot open peakfile @ %1 for size check (%2) after rebuild"), _peakpath, strerror (errno)) << endmsg;
390                         }
391                         if (statbuf.st_size < expected_file_size) {
392                                 fatal << "peak file is still truncated after rebuild" << endmsg;
393                                 /*NOTREACHED*/
394                         }
395                 }
396         }
397
398         ScopedFileDescriptor sfd (g_open (_peakpath.c_str(), O_RDONLY, 0444));
399
400         if (sfd < 0) {
401                 error << string_compose (_("Cannot open peakfile @ %1 for reading (%2)"), _peakpath, strerror (errno)) << endmsg;
402                 return -1;
403         }
404
405         scale = npeaks/expected_peaks;
406
407
408         DEBUG_TRACE (DEBUG::Peaks, string_compose (" ======>RP: npeaks = %1 start = %2 cnt = %3 len = %4 samples_per_visual_peak = %5 expected was %6 ... scale =  %7 PD ptr = %8\n"
409                         , npeaks, start, cnt, _length, samples_per_visual_peak, expected_peaks, scale, peaks));
410
411         /* fix for near-end-of-file conditions */
412
413         if (cnt > _length - start) {
414                 // cerr << "too close to end @ " << _length << " given " << start << " + " << cnt << " (" << _length - start << ")" << endl;
415                 cnt = _length - start;
416                 read_npeaks = min ((framecnt_t) floor (cnt / samples_per_visual_peak), npeaks);
417                 zero_fill = npeaks - read_npeaks;
418                 expected_peaks = (cnt / (double) samples_per_file_peak);
419                 scale = npeaks/expected_peaks;
420         }
421
422         // cerr << "actual npeaks = " << read_npeaks << " zf = " << zero_fill << endl;
423
424         if (npeaks == cnt) {
425
426                 DEBUG_TRACE (DEBUG::Peaks, "RAW DATA\n");
427
428                 /* no scaling at all, just get the sample data and duplicate it for
429                    both max and min peak values.
430                 */
431
432                 boost::scoped_array<Sample> raw_staging(new Sample[cnt]);
433
434                 if (read_unlocked (raw_staging.get(), start, cnt) != cnt) {
435                         error << _("cannot read sample data for unscaled peak computation") << endmsg;
436                         return -1;
437                 }
438
439                 for (framecnt_t i = 0; i < npeaks; ++i) {
440                         peaks[i].max = raw_staging[i];
441                         peaks[i].min = raw_staging[i];
442                 }
443
444                 return 0;
445         }
446
447         if (scale == 1.0) {
448                 off_t first_peak_byte = (start / samples_per_file_peak) * sizeof (PeakData);
449                 size_t bytes_to_read = sizeof (PeakData) * read_npeaks;
450                 /* open, read, close */
451
452                 DEBUG_TRACE (DEBUG::Peaks, "DIRECT PEAKS\n");
453
454                 off_t  map_off =  first_peak_byte;
455                 off_t  read_map_off = map_off & ~(bufsize - 1);
456                 off_t  map_delta = map_off - read_map_off;
457                 size_t map_length = bytes_to_read + map_delta;
458
459                 if (_first_run  || (_last_scale != samples_per_visual_peak) || (_last_map_off != map_off) || (_last_raw_map_length  < bytes_to_read)) {
460                         peak_cache.reset (new PeakData[npeaks]);
461                         char* addr;
462 #ifdef PLATFORM_WINDOWS
463                         HANDLE file_handle = (HANDLE) _get_osfhandle(int(sfd));
464                         HANDLE map_handle;
465                         LPVOID view_handle;
466                         bool err_flag;
467
468                         map_handle = CreateFileMapping(file_handle, NULL, PAGE_READONLY, 0, 0, NULL);
469                         if (map_handle == NULL) {
470                                 error << string_compose (_("map failed - could not create file mapping for peakfile %1."), _peakpath) << endmsg;
471                                 return -1;
472                         }
473
474                         view_handle = MapViewOfFile(map_handle, FILE_MAP_READ, 0, read_map_off, map_length);
475                         if (view_handle == NULL) {
476                                 error << string_compose (_("map failed - could not map peakfile %1."), _peakpath) << endmsg;
477                                 return -1;
478                         }
479
480                         addr = (char*) view_handle;
481
482                         memcpy ((void*)peak_cache.get(), (void*)(addr + map_delta), bytes_to_read);
483
484                         err_flag = UnmapViewOfFile (view_handle);
485                         err_flag = CloseHandle(map_handle);
486                         if(!err_flag) {
487                                 error << string_compose (_("unmap failed - could not unmap peakfile %1."), _peakpath) << endmsg;
488                                 return -1;
489                         }
490 #else
491                         addr = (char*) mmap (0, map_length, PROT_READ, MAP_PRIVATE, sfd, read_map_off);
492                         if (addr ==  MAP_FAILED) {
493                                 error << string_compose (_("map failed - could not mmap peakfile %1."), _peakpath) << endmsg;
494                                 return -1;
495                         }
496
497                         memcpy ((void*)peak_cache.get(), (void*)(addr + map_delta), bytes_to_read);
498                         munmap (addr, map_length);
499 #endif
500                         if (zero_fill) {
501                                 memset (&peak_cache[read_npeaks], 0, sizeof (PeakData) * zero_fill);
502                         }
503
504                         _first_run = false;
505                         _last_scale = samples_per_visual_peak;
506                         _last_map_off = map_off;
507                         _last_raw_map_length = bytes_to_read;
508                 }
509
510                 memcpy ((void*)peaks, (void*)peak_cache.get(), npeaks * sizeof(PeakData));
511
512                 return 0;
513         }
514
515         if (scale < 1.0) {
516
517                 DEBUG_TRACE (DEBUG::Peaks, "DOWNSAMPLE\n");
518
519                 /* the caller wants:
520
521                     - more frames-per-peak (lower resolution) than the peakfile, or to put it another way,
522                     - less peaks than the peakfile holds for the same range
523
524                     So, read a block into a staging area, and then downsample from there.
525
526                     to avoid confusion, I'll refer to the requested peaks as visual_peaks and the peakfile peaks as stored_peaks
527                 */
528
529                 const framecnt_t chunksize = (framecnt_t) expected_peaks; // we read all the peaks we need in one hit.
530
531                 /* compute the rounded up frame position  */
532
533                 framepos_t current_stored_peak = (framepos_t) ceil (start / (double) samples_per_file_peak);
534                 framepos_t next_visual_peak  = (framepos_t) ceil (start / samples_per_visual_peak);
535                 double     next_visual_peak_frame = next_visual_peak * samples_per_visual_peak;
536                 framepos_t stored_peak_before_next_visual_peak = (framepos_t) next_visual_peak_frame / samples_per_file_peak;
537                 framecnt_t nvisual_peaks = 0;
538                 uint32_t i = 0;
539
540                 /* handle the case where the initial visual peak is on a pixel boundary */
541
542                 current_stored_peak = min (current_stored_peak, stored_peak_before_next_visual_peak);
543
544                 /* open ... close during out: handling */
545
546                 off_t  map_off =  (uint32_t) (ceil (start / (double) samples_per_file_peak)) * sizeof(PeakData);
547                 off_t  read_map_off = map_off & ~(bufsize - 1);
548                 off_t  map_delta = map_off - read_map_off;
549                 size_t raw_map_length = chunksize * sizeof(PeakData);
550                 size_t map_length = (chunksize * sizeof(PeakData)) + map_delta;
551
552                 if (_first_run || (_last_scale != samples_per_visual_peak) || (_last_map_off != map_off) || (_last_raw_map_length < raw_map_length)) {
553                         peak_cache.reset (new PeakData[npeaks]);
554                         boost::scoped_array<PeakData> staging (new PeakData[chunksize]);
555
556                         char* addr;
557 #ifdef PLATFORM_WINDOWS
558                         HANDLE file_handle =  (HANDLE) _get_osfhandle(int(sfd));
559                         HANDLE map_handle;
560                         LPVOID view_handle;
561                         bool err_flag;
562
563                         map_handle = CreateFileMapping(file_handle, NULL, PAGE_READONLY, 0, 0, NULL);
564                         if (map_handle == NULL) {
565                                 error << string_compose (_("map failed - could not create file mapping for peakfile %1."), _peakpath) << endmsg;
566                                 return -1;
567                         }
568
569                         view_handle = MapViewOfFile(map_handle, FILE_MAP_READ, 0, read_map_off, map_length);
570                         if (view_handle == NULL) {
571                                 error << string_compose (_("map failed - could not map peakfile %1."), _peakpath) << endmsg;
572                                 return -1;
573                         }
574
575                         addr = (char *) view_handle;
576
577                         memcpy ((void*)staging.get(), (void*)(addr + map_delta), raw_map_length);
578
579                         err_flag = UnmapViewOfFile (view_handle);
580                         err_flag = CloseHandle(map_handle);
581                         if(!err_flag) {
582                                 error << string_compose (_("unmap failed - could not unmap peakfile %1."), _peakpath) << endmsg;
583                                 return -1;
584                         }
585 #else
586                         addr = (char*) mmap (0, map_length, PROT_READ, MAP_PRIVATE, sfd, read_map_off);
587                         if (addr ==  MAP_FAILED) {
588                                 error << string_compose (_("map failed - could not mmap peakfile %1."), _peakpath) << endmsg;
589                                 return -1;
590                         }
591
592                         memcpy ((void*)staging.get(), (void*)(addr + map_delta), raw_map_length);
593                         munmap (addr, map_length);
594 #endif
595                         while (nvisual_peaks < read_npeaks) {
596
597                                 xmax = -1.0;
598                                 xmin = 1.0;
599
600                                 while ((current_stored_peak <= stored_peak_before_next_visual_peak) && (i < chunksize)) {
601
602                                         xmax = max (xmax, staging[i].max);
603                                         xmin = min (xmin, staging[i].min);
604                                         ++i;
605                                         ++current_stored_peak;
606                                 }
607
608                                 peak_cache[nvisual_peaks].max = xmax;
609                                 peak_cache[nvisual_peaks].min = xmin;
610                                 ++nvisual_peaks;
611                                 next_visual_peak_frame =  min ((double) start + cnt, (next_visual_peak_frame + samples_per_visual_peak));
612                                 stored_peak_before_next_visual_peak = (uint32_t) next_visual_peak_frame / samples_per_file_peak;
613                         }
614
615                         if (zero_fill) {
616                                 cerr << "Zero fill end of peaks (@ " << read_npeaks << " with " << zero_fill << ")" << endl;
617                                 memset (&peak_cache[read_npeaks], 0, sizeof (PeakData) * zero_fill);
618                         }
619
620                         _first_run = false;
621                         _last_scale = samples_per_visual_peak;
622                         _last_map_off = map_off;
623                         _last_raw_map_length = raw_map_length;
624                 }
625
626                 memcpy ((void*)peaks, (void*)peak_cache.get(), npeaks * sizeof(PeakData));
627
628         } else {
629                 DEBUG_TRACE (DEBUG::Peaks, "UPSAMPLE\n");
630
631                 /* the caller wants
632
633                      - less frames-per-peak (more resolution)
634                      - more peaks than stored in the Peakfile
635
636                    So, fetch data from the raw source, and generate peak
637                    data on the fly.
638                 */
639
640                 framecnt_t frames_read = 0;
641                 framepos_t current_frame = start;
642                 framecnt_t i = 0;
643                 framecnt_t nvisual_peaks = 0;
644                 framecnt_t chunksize = (framecnt_t) min (cnt, (framecnt_t) 4096);
645                 boost::scoped_array<Sample> raw_staging(new Sample[chunksize]);
646
647                 framepos_t frame_pos = start;
648                 double pixel_pos = floor (frame_pos / samples_per_visual_peak);
649                 double next_pixel_pos = ceil (frame_pos / samples_per_visual_peak);
650                 double pixels_per_frame = 1.0 / samples_per_visual_peak;
651
652                 xmin = 1.0;
653                 xmax = -1.0;
654
655                 while (nvisual_peaks < read_npeaks) {
656
657                         if (i == frames_read) {
658
659                                 to_read = min (chunksize, (framecnt_t)(_length - current_frame));
660
661                                 if (current_frame >= _length) {
662
663                                         /* hmm, error condition - we've reached the end of the file
664                                            without generating all the peak data. cook up a zero-filled
665                                            data buffer and then use it. this is simpler than
666                                            adjusting zero_fill and read_npeaks and then breaking out of
667                                            this loop early
668                                         */
669
670                                         memset (raw_staging.get(), 0, sizeof (Sample) * chunksize);
671
672                                 } else {
673
674                                         to_read = min (chunksize, (_length - current_frame));
675
676
677                                         if ((frames_read = read_unlocked (raw_staging.get(), current_frame, to_read)) == 0) {
678                                                 error << string_compose(_("AudioSource[%1]: peak read - cannot read %2 samples at offset %3 of %4 (%5)"),
679                                                                         _name, to_read, current_frame, _length, strerror (errno))
680                                                       << endmsg;
681                                                 return -1;
682                                         }
683                                 }
684
685                                 i = 0;
686                         }
687
688                         xmax = max (xmax, raw_staging[i]);
689                         xmin = min (xmin, raw_staging[i]);
690                         ++i;
691                         ++current_frame;
692                         pixel_pos += pixels_per_frame;
693
694                         if (pixel_pos >= next_pixel_pos) {
695
696                                 peaks[nvisual_peaks].max = xmax;
697                                 peaks[nvisual_peaks].min = xmin;
698                                 ++nvisual_peaks;
699                                 xmin = 1.0;
700                                 xmax = -1.0;
701
702                                 next_pixel_pos = ceil (pixel_pos + 0.5);
703                         }
704                 }
705
706                 if (zero_fill) {
707                         memset (&peaks[read_npeaks], 0, sizeof (PeakData) * zero_fill);
708                 }
709         }
710
711         DEBUG_TRACE (DEBUG::Peaks, "READPEAKS DONE\n");
712         return 0;
713 }
714
715 int
716 AudioSource::build_peaks_from_scratch ()
717 {
718         const framecnt_t bufsize = 65536; // 256kB per disk read for mono data is about ideal
719
720         DEBUG_TRACE (DEBUG::Peaks, "Building peaks from scratch\n");
721
722         int ret = -1;
723
724         {
725                 /* hold lock while building peaks */
726
727                 Glib::Threads::Mutex::Lock lp (_lock);
728
729                 if (prepare_for_peakfile_writes ()) {
730                         goto out;
731                 }
732
733                 framecnt_t current_frame = 0;
734                 framecnt_t cnt = _length;
735
736                 _peaks_built = false;
737                 boost::scoped_array<Sample> buf(new Sample[bufsize]);
738
739                 while (cnt) {
740
741                         framecnt_t frames_to_read = min (bufsize, cnt);
742                         framecnt_t frames_read;
743
744                         if ((frames_read = read_unlocked (buf.get(), current_frame, frames_to_read)) != frames_to_read) {
745                                 error << string_compose(_("%1: could not write read raw data for peak computation (%2)"), _name, strerror (errno)) << endmsg;
746                                 done_with_peakfile_writes (false);
747                                 goto out;
748                         }
749
750                         lp.release(); // allow butler to refill buffers
751
752                         if (_session.deletion_in_progress() || _session.peaks_cleanup_in_progres()) {
753                                 cerr << "peak file creation interrupted: " << _name << endmsg;
754                                 lp.acquire();
755                                 done_with_peakfile_writes (false);
756                                 goto out;
757                         }
758
759                         if (compute_and_write_peaks (buf.get(), current_frame, frames_read, true, false, _FPP)) {
760                                 break;
761                         }
762
763                         current_frame += frames_read;
764                         cnt -= frames_read;
765
766                         lp.acquire();
767                 }
768
769                 if (cnt == 0) {
770                         /* success */
771                         truncate_peakfile();
772                 }
773
774                 done_with_peakfile_writes ((cnt == 0));
775                 if (cnt == 0) {
776                         ret = 0;
777                 }
778         }
779
780   out:
781         if (ret) {
782                 DEBUG_TRACE (DEBUG::Peaks, string_compose("Could not write peak data, attempting to remove peakfile %1\n", _peakpath));
783                 ::g_unlink (_peakpath.c_str());
784         }
785
786         return ret;
787 }
788
789 int
790 AudioSource::close_peakfile ()
791 {
792         Glib::Threads::Mutex::Lock lp (_lock);
793         if (_peakfile_fd >= 0) {
794                 close (_peakfile_fd);
795                 _peakfile_fd = -1;
796         }
797         if (!_peakpath.empty()) {
798                 ::g_unlink (_peakpath.c_str());
799         }
800         _peaks_built = false;
801         return 0;
802 }
803
804 int
805 AudioSource::prepare_for_peakfile_writes ()
806 {
807         if (_session.deletion_in_progress() || _session.peaks_cleanup_in_progres()) {
808                 return -1;
809         }
810
811         if ((_peakfile_fd = g_open (_peakpath.c_str(), O_CREAT|O_RDWR, 0664)) < 0) {
812                 error << string_compose(_("AudioSource: cannot open _peakpath (c) \"%1\" (%2)"), _peakpath, strerror (errno)) << endmsg;
813                 return -1;
814         }
815         return 0;
816 }
817
818 void
819 AudioSource::done_with_peakfile_writes (bool done)
820 {
821         if (_session.deletion_in_progress() || _session.peaks_cleanup_in_progres()) {
822                 if (_peakfile_fd) {
823                         close (_peakfile_fd);
824                         _peakfile_fd = -1;
825                 }
826                 return;
827         }
828
829         if (peak_leftover_cnt) {
830                 compute_and_write_peaks (0, 0, 0, true, false, _FPP);
831         }
832
833         if (done) {
834                 Glib::Threads::Mutex::Lock lm (_peaks_ready_lock);
835                 _peaks_built = true;
836                 PeaksReady (); /* EMIT SIGNAL */
837         }
838
839         close (_peakfile_fd);
840         _peakfile_fd = -1;
841 }
842
843 /** @param first_frame Offset from the source start of the first frame to
844  * process. _lock MUST be held by caller.
845 */
846 int
847 AudioSource::compute_and_write_peaks (Sample* buf, framecnt_t first_frame, framecnt_t cnt,
848                                       bool force, bool intermediate_peaks_ready)
849 {
850         return compute_and_write_peaks (buf, first_frame, cnt, force, intermediate_peaks_ready, _FPP);
851 }
852
853 int
854 AudioSource::compute_and_write_peaks (Sample* buf, framecnt_t first_frame, framecnt_t cnt,
855                                       bool force, bool intermediate_peaks_ready, framecnt_t fpp)
856 {
857         framecnt_t to_do;
858         uint32_t  peaks_computed;
859         framepos_t current_frame;
860         framecnt_t frames_done;
861         const size_t blocksize = (128 * 1024);
862         off_t first_peak_byte;
863         boost::scoped_array<Sample> buf2;
864
865         if (_peakfile_fd < 0) {
866                 if (prepare_for_peakfile_writes ()) {
867                         return -1;
868                 }
869         }
870
871   restart:
872         if (peak_leftover_cnt) {
873
874                 if (first_frame != peak_leftover_frame + peak_leftover_cnt) {
875
876                         /* uh-oh, ::seek() since the last ::compute_and_write_peaks(),
877                            and we have leftovers. flush a single peak (since the leftovers
878                            never represent more than that, and restart.
879                         */
880
881                         PeakData x;
882
883                         x.min = peak_leftovers[0];
884                         x.max = peak_leftovers[0];
885
886                         off_t byte = (peak_leftover_frame / fpp) * sizeof (PeakData);
887
888                         off_t offset = lseek (_peakfile_fd, byte, SEEK_SET);
889
890                         if (offset != byte) {
891                                 error << string_compose(_("%1: could not seek in peak file data (%2)"), _name, strerror (errno)) << endmsg;
892                                 return -1;
893                         }
894
895                         if (::write (_peakfile_fd, &x, sizeof (PeakData)) != sizeof (PeakData)) {
896                                 error << string_compose(_("%1: could not write peak file data (%2)"), _name, strerror (errno)) << endmsg;
897                                 return -1;
898                         }
899
900                         _peak_byte_max = max (_peak_byte_max, (off_t) (byte + sizeof(PeakData)));
901
902                         {
903                                 Glib::Threads::Mutex::Lock lm (_peaks_ready_lock);
904                                 PeakRangeReady (peak_leftover_frame, peak_leftover_cnt); /* EMIT SIGNAL */
905                                 if (intermediate_peaks_ready) {
906                                         PeaksReady (); /* EMIT SIGNAL */
907                                 }
908                         }
909
910                         /* left overs are done */
911
912                         peak_leftover_cnt = 0;
913                         goto restart;
914                 }
915
916                 /* else ... had leftovers, but they immediately preceed the new data, so just
917                    merge them and compute.
918                 */
919
920                 /* make a new contiguous buffer containing leftovers and the new stuff */
921
922                 to_do = cnt + peak_leftover_cnt;
923                 buf2.reset(new Sample[to_do]);
924
925                 /* the remnants */
926                 memcpy (buf2.get(), peak_leftovers, peak_leftover_cnt * sizeof (Sample));
927
928                 /* the new stuff */
929                 memcpy (buf2.get()+peak_leftover_cnt, buf, cnt * sizeof (Sample));
930
931                 /* no more leftovers */
932                 peak_leftover_cnt = 0;
933
934                 /* use the temporary buffer */
935                 buf = buf2.get();
936
937                 /* make sure that when we write into the peakfile, we startup where we left off */
938
939                 first_frame = peak_leftover_frame;
940
941         } else {
942                 to_do = cnt;
943         }
944
945         boost::scoped_array<PeakData> peakbuf(new PeakData[(to_do/fpp)+1]);
946         peaks_computed = 0;
947         current_frame = first_frame;
948         frames_done = 0;
949
950         while (to_do) {
951
952                 /* if some frames were passed in (i.e. we're not flushing leftovers)
953                    and there are less than fpp to do, save them till
954                    next time
955                 */
956
957                 if (force && (to_do < fpp)) {
958                         /* keep the left overs around for next time */
959
960                         if (peak_leftover_size < to_do) {
961                                 delete [] peak_leftovers;
962                                 peak_leftovers = new Sample[to_do];
963                                 peak_leftover_size = to_do;
964                         }
965                         memcpy (peak_leftovers, buf, to_do * sizeof (Sample));
966                         peak_leftover_cnt = to_do;
967                         peak_leftover_frame = current_frame;
968
969                         /* done for now */
970
971                         break;
972                 }
973
974                 framecnt_t this_time = min (fpp, to_do);
975
976                 peakbuf[peaks_computed].max = buf[0];
977                 peakbuf[peaks_computed].min = buf[0];
978
979                 ARDOUR::find_peaks (buf+1, this_time-1, &peakbuf[peaks_computed].min, &peakbuf[peaks_computed].max);
980
981                 peaks_computed++;
982                 buf += this_time;
983                 to_do -= this_time;
984                 frames_done += this_time;
985                 current_frame += this_time;
986         }
987
988         first_peak_byte = (first_frame / fpp) * sizeof (PeakData);
989
990         if (can_truncate_peaks()) {
991
992                 /* on some filesystems (ext3, at least) this helps to reduce fragmentation of
993                    the peakfiles. its not guaranteed to do so, and even on ext3 (as of december 2006)
994                    it does not cause single-extent allocation even for peakfiles of
995                    less than BLOCKSIZE bytes.  only call ftruncate if we'll make the file larger.
996                 */
997
998                 off_t endpos = lseek (_peakfile_fd, 0, SEEK_END);
999                 off_t target_length = blocksize * ((first_peak_byte + blocksize + 1) / blocksize);
1000
1001                 if (endpos < target_length) {
1002                         DEBUG_TRACE(DEBUG::Peaks, string_compose ("Truncating Peakfile %1\n", _peakpath));
1003                         if (ftruncate (_peakfile_fd, target_length)) {
1004                                 /* error doesn't actually matter so continue on without testing */
1005                         }
1006                 }
1007         }
1008
1009
1010         off_t offset = lseek(_peakfile_fd, first_peak_byte, SEEK_SET);
1011
1012         if (offset != first_peak_byte) {
1013                 error << string_compose(_("%1: could not seek in peak file data (%2)"), _name, strerror (errno)) << endmsg;
1014                 return -1;
1015         }
1016
1017         ssize_t bytes_to_write = sizeof (PeakData) * peaks_computed;
1018
1019         ssize_t bytes_written = ::write (_peakfile_fd, peakbuf.get(), bytes_to_write);
1020
1021         if (bytes_written != bytes_to_write) {
1022                 error << string_compose(_("%1: could not write peak file data (%2)"), _name, strerror (errno)) << endmsg;
1023                 return -1;
1024         }
1025
1026         _peak_byte_max = max (_peak_byte_max, (off_t) (first_peak_byte + bytes_to_write));
1027
1028         if (frames_done) {
1029                 Glib::Threads::Mutex::Lock lm (_peaks_ready_lock);
1030                 PeakRangeReady (first_frame, frames_done); /* EMIT SIGNAL */
1031                 if (intermediate_peaks_ready) {
1032                         PeaksReady (); /* EMIT SIGNAL */
1033                 }
1034         }
1035
1036         return 0;
1037 }
1038
1039 void
1040 AudioSource::truncate_peakfile ()
1041 {
1042         if (_peakfile_fd < 0) {
1043                 error << string_compose (_("programming error: %1"), "AudioSource::truncate_peakfile() called without open peakfile descriptor")
1044                       << endmsg;
1045                 return;
1046         }
1047
1048         /* truncate the peakfile down to its natural length if necessary */
1049
1050         off_t end = lseek (_peakfile_fd, 0, SEEK_END);
1051
1052         if (end > _peak_byte_max) {
1053                 DEBUG_TRACE(DEBUG::Peaks, string_compose ("Truncating Peakfile  %1\n", _peakpath));
1054                 if (ftruncate (_peakfile_fd, _peak_byte_max)) {
1055                         error << string_compose (_("could not truncate peakfile %1 to %2 (error: %3)"),
1056                                                  _peakpath, _peak_byte_max, errno) << endmsg;
1057                 }
1058         }
1059 }
1060
1061 framecnt_t
1062 AudioSource::available_peaks (double zoom_factor) const
1063 {
1064         if (zoom_factor < _FPP) {
1065                 return length(_timeline_position); // peak data will come from the audio file
1066         }
1067
1068         /* peak data comes from peakfile, but the filesize might not represent
1069            the valid data due to ftruncate optimizations, so use _peak_byte_max state.
1070            XXX - there might be some atomicity issues here, we should probably add a lock,
1071            but _peak_byte_max only monotonically increases after initialization.
1072         */
1073
1074         off_t end = _peak_byte_max;
1075
1076         return (end/sizeof(PeakData)) * _FPP;
1077 }
1078
1079 void
1080 AudioSource::mark_streaming_write_completed (const Lock& lock)
1081 {
1082         Glib::Threads::Mutex::Lock lm (_peaks_ready_lock);
1083
1084         if (_peaks_built) {
1085                 PeaksReady (); /* EMIT SIGNAL */
1086         }
1087 }
1088
1089 void
1090 AudioSource::allocate_working_buffers (framecnt_t framerate)
1091 {
1092         Glib::Threads::Mutex::Lock lm (_level_buffer_lock);
1093
1094
1095         /* Note: we don't need any buffers allocated until
1096            a level 1 audiosource is created, at which
1097            time we'll call ::ensure_buffers_for_level()
1098            with the right value and do the right thing.
1099         */
1100
1101         if (!_mixdown_buffers.empty()) {
1102                 ensure_buffers_for_level_locked ( _mixdown_buffers.size(), framerate);
1103         }
1104 }
1105
1106 void
1107 AudioSource::ensure_buffers_for_level (uint32_t level, framecnt_t frame_rate)
1108 {
1109         Glib::Threads::Mutex::Lock lm (_level_buffer_lock);
1110         ensure_buffers_for_level_locked (level, frame_rate);
1111 }
1112
1113 void
1114 AudioSource::ensure_buffers_for_level_locked (uint32_t level, framecnt_t frame_rate)
1115 {
1116         framecnt_t nframes = (framecnt_t) floor (Config->get_audio_playback_buffer_seconds() * frame_rate);
1117
1118         /* this may be called because either "level" or "frame_rate" have
1119          * changed. and it may be called with "level" smaller than the current
1120          * number of buffers, because a new compound region has been created at
1121          * a more shallow level than the deepest one we currently have.
1122          */
1123
1124         uint32_t limit = max ((size_t) level, _mixdown_buffers.size());
1125
1126         _mixdown_buffers.clear ();
1127         _gain_buffers.clear ();
1128
1129         for (uint32_t n = 0; n < limit; ++n) {
1130                 _mixdown_buffers.push_back (boost::shared_array<Sample> (new Sample[nframes]));
1131                 _gain_buffers.push_back (boost::shared_array<gain_t> (new gain_t[nframes]));
1132         }
1133 }