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