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