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