rework check for old configuration files
[ardour.git] / libs / ardour / audiosource.cc
1 /*
2     Copyright (C) 2000 Paul Davis
3
4     This program is free software; you can redistribute it and/or modify
5     it under the terms of the GNU General Public License as published by
6     the Free Software Foundation; either version 2 of the License, or
7     (at your option) any later version.
8
9     This program is distributed in the hope that it will be useful,
10     but WITHOUT ANY WARRANTY; without even the implied warranty of
11     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12     GNU General Public License for more details.
13
14     You should have received a copy of the GNU General Public License
15     along with this program; if not, write to the Free Software
16     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
17
18 */
19
20 #ifdef COMPILER_MSVC
21 #include <sys/utime.h>
22 #else
23 #include <unistd.h>
24 #include <utime.h>
25 #endif
26 #include <sys/stat.h>
27 #include <fcntl.h>
28 #include <float.h>
29 #include <cerrno>
30 #include <ctime>
31 #include <cmath>
32 #include <iomanip>
33 #include <fstream>
34 #include <algorithm>
35 #include <vector>
36
37 #ifdef PLATFORM_WINDOWS
38 #include <windows.h>
39
40 #else
41 #include <sys/mman.h>
42
43 #endif
44
45 #include <glib.h>
46 #include <glib/gstdio.h>
47
48 #include <boost/scoped_ptr.hpp>
49
50 #include <glibmm/fileutils.h>
51 #include <glibmm/miscutils.h>
52
53 #include "pbd/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 size_t AudioSource::_working_buffers_size = 0;
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, 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 (string audio_path)
240 {
241         GStatBuf statbuf;
242
243         peakpath = peak_path (audio_path);
244
245         DEBUG_TRACE(DEBUG::Peaks, string_compose ("Initialize Peakfile %1 for Audio file %2\n", peakpath, audio_path));
246
247         /* if the peak file should be there, but isn't .... */
248
249         if (!empty() && !Glib::file_test (peakpath.c_str(), Glib::FILE_TEST_EXISTS)) {
250                 peakpath = find_broken_peakfile (peakpath, audio_path);
251         }
252
253         if (g_stat (peakpath.c_str(), &statbuf)) {
254                 if (errno != ENOENT) {
255                         /* it exists in the peaks dir, but there is some kind of error */
256
257                         error << string_compose(_("AudioSource: cannot stat peakfile \"%1\""), peakpath) << endmsg;
258                         return -1;
259                 }
260
261                 DEBUG_TRACE(DEBUG::Peaks, string_compose("Peakfile %1 does not exist\n", peakpath));
262
263                 _peaks_built = false;
264
265         } else {
266
267                 /* we found it in the peaks dir, so check it out */
268
269                 if (statbuf.st_size == 0 || (statbuf.st_size < (off_t) ((length(_timeline_position) / _FPP) * sizeof (PeakData)))) {
270                         DEBUG_TRACE(DEBUG::Peaks, string_compose("Peakfile %1 is empty\n", peakpath));
271                         _peaks_built = false;
272                 } else {
273                         // Check if the audio file has changed since the peakfile was built.
274                         struct stat stat_file;
275                         int err = stat (audio_path.c_str(), &stat_file);
276
277                         if (err) {
278
279                                 /* no audio path - nested source or we can't
280                                    read it or ... whatever, use the peakfile as-is.
281                                 */
282                                 DEBUG_TRACE(DEBUG::Peaks, string_compose("Error when calling stat on Peakfile %1\n", peakpath));
283
284                                 _peaks_built = true;
285                                 _peak_byte_max = statbuf.st_size;
286
287                         } else {
288
289                                 /* allow 6 seconds slop on checking peak vs. file times because of various
290                                    disk action "races"
291                                 */
292
293                                 if (stat_file.st_mtime > statbuf.st_mtime && (stat_file.st_mtime - statbuf.st_mtime > 6)) {
294                                         _peaks_built = false;
295                                         _peak_byte_max = 0;
296                                 } else {
297                                         _peaks_built = true;
298                                         _peak_byte_max = statbuf.st_size;
299                                 }
300                         }
301                 }
302         }
303
304         if (!empty() && !_peaks_built && _build_missing_peakfiles && _build_peakfiles) {
305                 build_peaks_from_scratch ();
306         }
307
308         return 0;
309 }
310
311 framecnt_t
312 AudioSource::read (Sample *dst, framepos_t start, framecnt_t cnt, int /*channel*/) const
313 {
314         assert (cnt >= 0);
315         
316         Glib::Threads::Mutex::Lock lm (_lock);
317         return read_unlocked (dst, start, cnt);
318 }
319
320 framecnt_t
321 AudioSource::write (Sample *dst, framecnt_t cnt)
322 {
323         Glib::Threads::Mutex::Lock lm (_lock);
324         /* any write makes the file not removable */
325         _flags = Flag (_flags & ~Removable);
326         return write_unlocked (dst, cnt);
327 }
328
329 int
330 AudioSource::read_peaks (PeakData *peaks, framecnt_t npeaks, framepos_t start, framecnt_t cnt, double samples_per_visual_peak) const
331 {
332         return read_peaks_with_fpp (peaks, npeaks, start, cnt, samples_per_visual_peak, _FPP);
333 }
334
335 /** @param peaks Buffer to write peak data.
336  *  @param npeaks Number of peaks to write.
337  */
338
339 int
340 AudioSource::read_peaks_with_fpp (PeakData *peaks, framecnt_t npeaks, framepos_t start, framecnt_t cnt,
341                                   double samples_per_visual_peak, framecnt_t samples_per_file_peak) const
342 {
343         Glib::Threads::Mutex::Lock lm (_lock);
344         double scale;
345         double expected_peaks;
346         PeakData::PeakDatum xmax;
347         PeakData::PeakDatum xmin;
348         int32_t to_read;
349 #ifdef PLATFORM_WINDOWS
350         SYSTEM_INFO system_info;
351         GetSystemInfo (&system_info);
352         const int bufsize = system_info.dwAllocationGranularity;;
353 #else
354         const int bufsize = sysconf(_SC_PAGESIZE);
355 #endif
356         framecnt_t zero_fill = 0;
357
358         ScopedFileDescriptor sfd (::open (peakpath.c_str(), O_RDONLY));
359
360         if (sfd < 0) {
361                 error << string_compose (_("Cannot open peakfile @ %1 for reading (%2)"), peakpath, strerror (errno)) << endmsg;
362                 return -1;
363         }
364                                   
365         expected_peaks = (cnt / (double) samples_per_file_peak);
366         scale = npeaks/expected_peaks;
367
368         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"
369                         , npeaks, start, cnt, _length, samples_per_visual_peak, expected_peaks, scale, peaks));
370
371         /* fix for near-end-of-file conditions */
372
373         if (cnt > _length - start) {
374                 // cerr << "too close to end @ " << _length << " given " << start << " + " << cnt << " (" << _length - start << ")" << endl;
375                 cnt = _length - start;
376                 framecnt_t old = npeaks;
377                 npeaks = min ((framecnt_t) floor (cnt / samples_per_visual_peak), npeaks);
378                 zero_fill = old - npeaks;
379         }
380
381         // cerr << "actual npeaks = " << npeaks << " zf = " << zero_fill << endl;
382
383         if (npeaks == cnt) {
384
385                 DEBUG_TRACE (DEBUG::Peaks, "RAW DATA\n");
386
387                 /* no scaling at all, just get the sample data and duplicate it for
388                    both max and min peak values.
389                 */
390
391                 boost::scoped_array<Sample> raw_staging(new Sample[cnt]);
392
393                 if (read_unlocked (raw_staging.get(), start, cnt) != cnt) {
394                         error << _("cannot read sample data for unscaled peak computation") << endmsg;
395                         return -1;
396                 }
397
398                 for (framecnt_t i = 0; i < npeaks; ++i) {
399                         peaks[i].max = raw_staging[i];
400                         peaks[i].min = raw_staging[i];
401                 }
402
403                 return 0;
404         }
405
406         if (scale == 1.0) {
407                 off_t first_peak_byte = (start / samples_per_file_peak) * sizeof (PeakData);
408                 size_t bytes_to_read = sizeof (PeakData)* npeaks;
409                 /* open, read, close */
410
411                 DEBUG_TRACE (DEBUG::Peaks, "DIRECT PEAKS\n");
412
413                 off_t  map_off =  first_peak_byte;
414                 off_t  read_map_off = map_off & ~(bufsize - 1);
415                 off_t  map_delta = map_off - read_map_off;
416                 size_t map_length = bytes_to_read + map_delta;
417
418                 if (_first_run  || (_last_scale != samples_per_visual_peak) || (_last_map_off != map_off) || (_last_raw_map_length  < bytes_to_read)) {
419                         peak_cache.reset (new PeakData[npeaks]);
420                         boost::scoped_array<PeakData> staging (new PeakData[npeaks]);
421                         char* addr;
422 #ifdef PLATFORM_WINDOWS
423                         HANDLE file_handle = (HANDLE) _get_osfhandle(int(sfd));
424                         HANDLE map_handle;
425                         LPVOID view_handle;
426                         bool err_flag;
427
428                         map_handle = CreateFileMapping(file_handle, NULL, PAGE_READONLY, 0, 0, NULL);
429                         if (map_handle == NULL) {
430                                 error << string_compose (_("map failed - could not create file mapping for peakfile %1."), peakpath) << endmsg;
431                                 return -1;
432                         }
433
434                         view_handle = MapViewOfFile(map_handle, FILE_MAP_READ, 0, read_map_off, map_length);
435                         if (view_handle == NULL) {
436                                 error << string_compose (_("map failed - could not map peakfile %1."), peakpath) << endmsg;
437                                 return -1;
438                         }
439
440                         addr = (char*) view_handle;
441
442                         memcpy ((void*)peak_cache.get(), (void*)(addr + map_delta), bytes_to_read);
443
444                         err_flag = UnmapViewOfFile (view_handle);
445                         err_flag = CloseHandle(map_handle);
446                         if(!err_flag) {
447                                 error << string_compose (_("unmap failed - could not unmap peakfile %1."), peakpath) << endmsg;
448                                 return -1;
449                         }
450 #else
451                         addr = (char*) mmap (0, map_length, PROT_READ, MAP_PRIVATE, sfd, read_map_off);
452                         if (addr ==  MAP_FAILED) {
453                                 error << string_compose (_("map failed - could not mmap peakfile %1."), peakpath) << endmsg;
454                                 return -1;
455                         }
456
457                         memcpy ((void*)peak_cache.get(), (void*)(addr + map_delta), bytes_to_read);
458                         munmap (addr, map_length);
459 #endif
460                         if (zero_fill) {
461                                 memset (&peak_cache[npeaks], 0, sizeof (PeakData) * zero_fill);
462                         }
463
464                         _first_run = false;
465                         _last_scale = samples_per_visual_peak;
466                         _last_map_off = map_off;
467                         _last_raw_map_length = bytes_to_read;
468                 }
469
470                 memcpy ((void*)peaks, (void*)peak_cache.get(), npeaks * sizeof(PeakData));
471
472                 return 0;
473         }
474
475         if (scale < 1.0) {
476
477                 DEBUG_TRACE (DEBUG::Peaks, "DOWNSAMPLE\n");
478
479                 /* the caller wants:
480
481                     - more frames-per-peak (lower resolution) than the peakfile, or to put it another way,
482                     - less peaks than the peakfile holds for the same range
483
484                     So, read a block into a staging area, and then downsample from there.
485
486                     to avoid confusion, I'll refer to the requested peaks as visual_peaks and the peakfile peaks as stored_peaks
487                 */
488
489                 const framecnt_t chunksize = (framecnt_t) expected_peaks; // we read all the peaks we need in one hit.
490
491                 /* compute the rounded up frame position  */
492
493                 framepos_t current_stored_peak = (framepos_t) ceil (start / (double) samples_per_file_peak);
494                 framepos_t next_visual_peak  = (framepos_t) ceil (start / samples_per_visual_peak);
495                 double     next_visual_peak_frame = next_visual_peak * samples_per_visual_peak;
496                 framepos_t stored_peak_before_next_visual_peak = (framepos_t) next_visual_peak_frame / samples_per_file_peak;
497                 framecnt_t nvisual_peaks = 0;
498                 uint32_t i = 0;
499
500                 /* handle the case where the initial visual peak is on a pixel boundary */
501
502                 current_stored_peak = min (current_stored_peak, stored_peak_before_next_visual_peak);
503
504                 /* open ... close during out: handling */
505
506                 off_t  map_off =  (uint32_t) (ceil (start / (double) samples_per_file_peak)) * sizeof(PeakData);
507                 off_t  read_map_off = map_off & ~(bufsize - 1);
508                 off_t  map_delta = map_off - read_map_off;
509                 size_t raw_map_length = chunksize * sizeof(PeakData);
510                 size_t map_length = (chunksize * sizeof(PeakData)) + map_delta;
511
512                 if (_first_run || (_last_scale != samples_per_visual_peak) || (_last_map_off != map_off) || (_last_raw_map_length < raw_map_length)) {
513                         peak_cache.reset (new PeakData[npeaks]);
514                         boost::scoped_array<PeakData> staging (new PeakData[chunksize]);
515
516                         char* addr;
517 #ifdef PLATFORM_WINDOWS
518                         HANDLE file_handle =  (HANDLE) _get_osfhandle(int(sfd));
519                         HANDLE map_handle;
520                         LPVOID view_handle;
521                         bool err_flag;
522
523                         map_handle = CreateFileMapping(file_handle, NULL, PAGE_READONLY, 0, 0, NULL);
524                         if (map_handle == NULL) {
525                                 error << string_compose (_("map failed - could not create file mapping for peakfile %1."), peakpath) << endmsg;
526                                 return -1;
527                         }
528
529                         view_handle = MapViewOfFile(map_handle, FILE_MAP_READ, 0, read_map_off, map_length);
530                         if (view_handle == NULL) {
531                                 error << string_compose (_("map failed - could not map peakfile %1."), peakpath) << endmsg;
532                                 return -1;
533                         }
534
535                         addr = (char *) view_handle;
536
537                         memcpy ((void*)staging.get(), (void*)(addr + map_delta), raw_map_length);
538
539                         err_flag = UnmapViewOfFile (view_handle);
540                         err_flag = CloseHandle(map_handle);
541                         if(!err_flag) {
542                                 error << string_compose (_("unmap failed - could not unmap peakfile %1."), peakpath) << endmsg;
543                                 return -1;
544                         }
545 #else
546                         addr = (char*) mmap (0, map_length, PROT_READ, MAP_PRIVATE, sfd, read_map_off);
547                         if (addr ==  MAP_FAILED) {
548                                 error << string_compose (_("map failed - could not mmap peakfile %1."), peakpath) << endmsg;
549                                 return -1;
550                         }
551
552                         memcpy ((void*)staging.get(), (void*)(addr + map_delta), raw_map_length);
553                         munmap (addr, map_length);
554 #endif
555                         while (nvisual_peaks < npeaks) {
556
557                                 xmax = -1.0;
558                                 xmin = 1.0;
559
560                                 while ((current_stored_peak <= stored_peak_before_next_visual_peak) && (i < raw_map_length)) {
561
562                                         xmax = max (xmax, staging[i].max);
563                                         xmin = min (xmin, staging[i].min);
564                                         ++i;
565                                         ++current_stored_peak;
566                                 }
567
568                                 peak_cache[nvisual_peaks].max = xmax;
569                                 peak_cache[nvisual_peaks].min = xmin;
570                                 ++nvisual_peaks;
571                                 next_visual_peak_frame =  min ((double) start + cnt, (next_visual_peak_frame + samples_per_visual_peak));
572                                 stored_peak_before_next_visual_peak = (uint32_t) next_visual_peak_frame / samples_per_file_peak;
573                         }
574
575                         if (zero_fill) {
576                                 cerr << "Zero fill end of peaks (@ " << npeaks << " with " << zero_fill << endl;
577                                 memset (&peak_cache[npeaks], 0, sizeof (PeakData) * zero_fill);
578                         }
579
580                         _first_run = false;
581                         _last_scale = samples_per_visual_peak;
582                         _last_map_off = map_off;
583                         _last_raw_map_length = raw_map_length;
584                 }
585
586                 memcpy ((void*)peaks, (void*)peak_cache.get(), npeaks * sizeof(PeakData));
587
588         } else {
589                 DEBUG_TRACE (DEBUG::Peaks, "UPSAMPLE\n");
590
591                 /* the caller wants
592
593                      - less frames-per-peak (more resolution)
594                      - more peaks than stored in the Peakfile
595
596                    So, fetch data from the raw source, and generate peak
597                    data on the fly.
598                 */
599
600                 framecnt_t frames_read = 0;
601                 framepos_t current_frame = start;
602                 framecnt_t i = 0;
603                 framecnt_t nvisual_peaks = 0;
604                 framecnt_t chunksize = (framecnt_t) min (cnt, (framecnt_t) 4096);
605                 boost::scoped_array<Sample> raw_staging(new Sample[chunksize]);
606
607                 framepos_t frame_pos = start;
608                 double pixel_pos = floor (frame_pos / samples_per_visual_peak);
609                 double next_pixel_pos = ceil (frame_pos / samples_per_visual_peak);
610                 double pixels_per_frame = 1.0 / samples_per_visual_peak;
611
612                 xmin = 1.0;
613                 xmax = -1.0;
614
615                 while (nvisual_peaks < npeaks) {
616
617                         if (i == frames_read) {
618
619                                 to_read = min (chunksize, (framecnt_t)(_length - current_frame));
620
621                                 if (current_frame >= _length) {
622
623                                         /* hmm, error condition - we've reached the end of the file
624                                            without generating all the peak data. cook up a zero-filled
625                                            data buffer and then use it. this is simpler than
626                                            adjusting zero_fill and npeaks and then breaking out of
627                                            this loop early
628                                         */
629
630                                         memset (raw_staging.get(), 0, sizeof (Sample) * chunksize);
631
632                                 } else {
633
634                                         to_read = min (chunksize, (_length - current_frame));
635
636
637                                         if ((frames_read = read_unlocked (raw_staging.get(), current_frame, to_read)) == 0) {
638                                                 error << string_compose(_("AudioSource[%1]: peak read - cannot read %2 samples at offset %3 of %4 (%5)"),
639                                                                         _name, to_read, current_frame, _length, strerror (errno))
640                                                       << endmsg;
641                                                 return -1;
642                                         }
643                                 }
644
645                                 i = 0;
646                         }
647
648                         xmax = max (xmax, raw_staging[i]);
649                         xmin = min (xmin, raw_staging[i]);
650                         ++i;
651                         ++current_frame;
652                         pixel_pos += pixels_per_frame;
653
654                         if (pixel_pos >= next_pixel_pos) {
655
656                                 peaks[nvisual_peaks].max = xmax;
657                                 peaks[nvisual_peaks].min = xmin;
658                                 ++nvisual_peaks;
659                                 xmin = 1.0;
660                                 xmax = -1.0;
661
662                                 next_pixel_pos = ceil (pixel_pos + 0.5);
663                         }
664                 }
665
666                 if (zero_fill) {
667                         memset (&peaks[npeaks], 0, sizeof (PeakData) * zero_fill);
668                 }
669         }
670
671         DEBUG_TRACE (DEBUG::Peaks, "READPEAKS DONE\n");
672         return 0;
673 }
674
675 int
676 AudioSource::build_peaks_from_scratch ()
677 {
678         const framecnt_t bufsize = 65536; // 256kB per disk read for mono data is about ideal
679
680         DEBUG_TRACE (DEBUG::Peaks, "Building peaks from scratch\n");
681
682         int ret = -1;
683
684         {
685                 /* hold lock while building peaks */
686
687                 Glib::Threads::Mutex::Lock lp (_lock);
688
689                 if (prepare_for_peakfile_writes ()) {
690                         goto out;
691                 }
692
693                 framecnt_t current_frame = 0;
694                 framecnt_t cnt = _length;
695
696                 _peaks_built = false;
697                 boost::scoped_array<Sample> buf(new Sample[bufsize]);
698
699                 while (cnt) {
700
701                         framecnt_t frames_to_read = min (bufsize, cnt);
702                         framecnt_t frames_read;
703                         
704                         if ((frames_read = read_unlocked (buf.get(), current_frame, frames_to_read)) != frames_to_read) {
705                                 error << string_compose(_("%1: could not write read raw data for peak computation (%2)"), _name, strerror (errno)) << endmsg;
706                                 done_with_peakfile_writes (false);
707                                 goto out;
708                         }
709
710                         if (compute_and_write_peaks (buf.get(), current_frame, frames_read, true, false, _FPP)) {
711                                 break;
712                         }
713
714                         current_frame += frames_read;
715                         cnt -= frames_read;
716                 }
717
718                 if (cnt == 0) {
719                         /* success */
720                         truncate_peakfile();
721                 }
722
723                 done_with_peakfile_writes ((cnt == 0));
724                 if (cnt == 0) {
725                         ret = 0;
726                 }
727         }
728
729   out:
730         if (ret) {
731                 DEBUG_TRACE (DEBUG::Peaks, string_compose("Could not write peak data, attempting to remove peakfile %1\n", peakpath));
732                 ::g_unlink (peakpath.c_str());
733         }
734
735         return ret;
736 }
737
738 int
739 AudioSource::prepare_for_peakfile_writes ()
740 {
741         if ((_peakfile_fd = open (peakpath.c_str(), O_CREAT|O_RDWR, 0664)) < 0) {
742                 error << string_compose(_("AudioSource: cannot open peakpath (c) \"%1\" (%2)"), peakpath, strerror (errno)) << endmsg;
743                 return -1;
744         }
745         return 0;
746 }
747
748 void
749 AudioSource::done_with_peakfile_writes (bool done)
750 {
751         if (peak_leftover_cnt) {
752                 compute_and_write_peaks (0, 0, 0, true, false, _FPP);
753         }
754
755         if (done) {
756                 Glib::Threads::Mutex::Lock lm (_peaks_ready_lock);
757                 _peaks_built = true;
758                 PeaksReady (); /* EMIT SIGNAL */
759         }
760
761         close (_peakfile_fd);
762         _peakfile_fd = -1;
763 }
764
765 /** @param first_frame Offset from the source start of the first frame to process */
766 int
767 AudioSource::compute_and_write_peaks (Sample* buf, framecnt_t first_frame, framecnt_t cnt,
768                                       bool force, bool intermediate_peaks_ready)
769 {
770         return compute_and_write_peaks (buf, first_frame, cnt, force, intermediate_peaks_ready, _FPP);
771 }
772
773 int
774 AudioSource::compute_and_write_peaks (Sample* buf, framecnt_t first_frame, framecnt_t cnt,
775                                       bool force, bool intermediate_peaks_ready, framecnt_t fpp)
776 {
777         framecnt_t to_do;
778         uint32_t  peaks_computed;
779         framepos_t current_frame;
780         framecnt_t frames_done;
781         const size_t blocksize = (128 * 1024);
782         off_t first_peak_byte;
783         boost::scoped_array<Sample> buf2;
784
785         if (_peakfile_fd < 0) {
786                 if (prepare_for_peakfile_writes ()) {
787                         return -1;
788                 }
789         }
790
791   restart:
792         if (peak_leftover_cnt) {
793
794                 if (first_frame != peak_leftover_frame + peak_leftover_cnt) {
795
796                         /* uh-oh, ::seek() since the last ::compute_and_write_peaks(),
797                            and we have leftovers. flush a single peak (since the leftovers
798                            never represent more than that, and restart.
799                         */
800
801                         PeakData x;
802
803                         x.min = peak_leftovers[0];
804                         x.max = peak_leftovers[0];
805
806                         off_t byte = (peak_leftover_frame / fpp) * sizeof (PeakData);
807
808                         off_t offset = lseek (_peakfile_fd, byte, SEEK_SET);
809
810                         if (offset != byte) {
811                                 error << string_compose(_("%1: could not seek in peak file data (%2)"), _name, strerror (errno)) << endmsg;
812                                 return -1;
813                         }
814
815                         if (::write (_peakfile_fd, &x, sizeof (PeakData)) != sizeof (PeakData)) {
816                                 error << string_compose(_("%1: could not write peak file data (%2)"), _name, strerror (errno)) << endmsg;
817                                 return -1;
818                         }
819
820                         _peak_byte_max = max (_peak_byte_max, (off_t) (byte + sizeof(PeakData)));
821
822                         {
823                                 Glib::Threads::Mutex::Lock lm (_peaks_ready_lock);
824                                 PeakRangeReady (peak_leftover_frame, peak_leftover_cnt); /* EMIT SIGNAL */
825                                 if (intermediate_peaks_ready) {
826                                         PeaksReady (); /* EMIT SIGNAL */
827                                 }
828                         }
829
830                         /* left overs are done */
831
832                         peak_leftover_cnt = 0;
833                         goto restart;
834                 }
835
836                 /* else ... had leftovers, but they immediately preceed the new data, so just
837                    merge them and compute.
838                 */
839
840                 /* make a new contiguous buffer containing leftovers and the new stuff */
841
842                 to_do = cnt + peak_leftover_cnt;
843                 buf2.reset(new Sample[to_do]);
844
845                 /* the remnants */
846                 memcpy (buf2.get(), peak_leftovers, peak_leftover_cnt * sizeof (Sample));
847
848                 /* the new stuff */
849                 memcpy (buf2.get()+peak_leftover_cnt, buf, cnt * sizeof (Sample));
850
851                 /* no more leftovers */
852                 peak_leftover_cnt = 0;
853
854                 /* use the temporary buffer */
855                 buf = buf2.get();
856
857                 /* make sure that when we write into the peakfile, we startup where we left off */
858
859                 first_frame = peak_leftover_frame;
860
861         } else {
862                 to_do = cnt;
863         }
864
865         boost::scoped_array<PeakData> peakbuf(new PeakData[(to_do/fpp)+1]);
866         peaks_computed = 0;
867         current_frame = first_frame;
868         frames_done = 0;
869
870         while (to_do) {
871
872                 /* if some frames were passed in (i.e. we're not flushing leftovers)
873                    and there are less than fpp to do, save them till
874                    next time
875                 */
876
877                 if (force && (to_do < fpp)) {
878                         /* keep the left overs around for next time */
879
880                         if (peak_leftover_size < to_do) {
881                                 delete [] peak_leftovers;
882                                 peak_leftovers = new Sample[to_do];
883                                 peak_leftover_size = to_do;
884                         }
885                         memcpy (peak_leftovers, buf, to_do * sizeof (Sample));
886                         peak_leftover_cnt = to_do;
887                         peak_leftover_frame = current_frame;
888
889                         /* done for now */
890
891                         break;
892                 }
893
894                 framecnt_t this_time = min (fpp, to_do);
895
896                 peakbuf[peaks_computed].max = buf[0];
897                 peakbuf[peaks_computed].min = buf[0];
898
899                 ARDOUR::find_peaks (buf+1, this_time-1, &peakbuf[peaks_computed].min, &peakbuf[peaks_computed].max);
900
901                 peaks_computed++;
902                 buf += this_time;
903                 to_do -= this_time;
904                 frames_done += this_time;
905                 current_frame += this_time;
906         }
907
908         first_peak_byte = (first_frame / fpp) * sizeof (PeakData);
909
910         if (can_truncate_peaks()) {
911
912                 /* on some filesystems (ext3, at least) this helps to reduce fragmentation of
913                    the peakfiles. its not guaranteed to do so, and even on ext3 (as of december 2006)
914                    it does not cause single-extent allocation even for peakfiles of
915                    less than BLOCKSIZE bytes.  only call ftruncate if we'll make the file larger.
916                 */
917
918                 off_t endpos = lseek (_peakfile_fd, 0, SEEK_END);
919                 off_t target_length = blocksize * ((first_peak_byte + blocksize + 1) / blocksize);
920
921                 if (endpos < target_length) {
922                         DEBUG_TRACE(DEBUG::Peaks, string_compose ("Truncating Peakfile %1\n", peakpath));
923                         if (ftruncate (_peakfile_fd, target_length)) {
924                                 /* error doesn't actually matter so continue on without testing */
925                         }
926                 }
927         }
928
929
930         off_t offset = lseek(_peakfile_fd, first_peak_byte, SEEK_SET);
931
932         if (offset != first_peak_byte) {
933                 error << string_compose(_("%1: could not seek in peak file data (%2)"), _name, strerror (errno)) << endmsg;
934                 return -1;
935         }
936
937         ssize_t bytes_to_write = sizeof (PeakData) * peaks_computed;
938
939         ssize_t bytes_written = ::write (_peakfile_fd, peakbuf.get(), bytes_to_write);
940
941         if (bytes_written != bytes_to_write) {
942                 error << string_compose(_("%1: could not write peak file data (%2)"), _name, strerror (errno)) << endmsg;
943                 return -1;
944         }
945
946         _peak_byte_max = max (_peak_byte_max, (off_t) (first_peak_byte + bytes_to_write));
947
948         if (frames_done) {
949                 Glib::Threads::Mutex::Lock lm (_peaks_ready_lock);
950                 PeakRangeReady (first_frame, frames_done); /* EMIT SIGNAL */
951                 if (intermediate_peaks_ready) {
952                         PeaksReady (); /* EMIT SIGNAL */
953                 }
954         }
955
956         return 0;
957 }
958
959 void
960 AudioSource::truncate_peakfile ()
961 {
962         if (_peakfile_fd < 0) {
963                 error << string_compose (_("programming error: %1"), "AudioSource::truncate_peakfile() called without open peakfile descriptor")
964                       << endmsg;
965                 return;
966         }
967
968         /* truncate the peakfile down to its natural length if necessary */
969
970         off_t end = lseek (_peakfile_fd, 0, SEEK_END);
971
972         if (end > _peak_byte_max) {
973                 DEBUG_TRACE(DEBUG::Peaks, string_compose ("Truncating Peakfile  %1\n", peakpath));
974                 if (ftruncate (_peakfile_fd, _peak_byte_max)) {
975                         error << string_compose (_("could not truncate peakfile %1 to %2 (error: %3)"),
976                                                  peakpath, _peak_byte_max, errno) << endmsg;
977                 }
978         }
979 }
980
981 framecnt_t
982 AudioSource::available_peaks (double zoom_factor) const
983 {
984         if (zoom_factor < _FPP) {
985                 return length(_timeline_position); // peak data will come from the audio file
986         }
987
988         /* peak data comes from peakfile, but the filesize might not represent
989            the valid data due to ftruncate optimizations, so use _peak_byte_max state.
990            XXX - there might be some atomicity issues here, we should probably add a lock,
991            but _peak_byte_max only monotonically increases after initialization.
992         */
993
994         off_t end = _peak_byte_max;
995
996         return (end/sizeof(PeakData)) * _FPP;
997 }
998
999 void
1000 AudioSource::mark_streaming_write_completed (const Lock& lock)
1001 {
1002         Glib::Threads::Mutex::Lock lm (_peaks_ready_lock);
1003
1004         if (_peaks_built) {
1005                 PeaksReady (); /* EMIT SIGNAL */
1006         }
1007 }
1008
1009 void
1010 AudioSource::allocate_working_buffers (framecnt_t framerate)
1011 {
1012         Glib::Threads::Mutex::Lock lm (_level_buffer_lock);
1013
1014
1015         /* Note: we don't need any buffers allocated until
1016            a level 1 audiosource is created, at which
1017            time we'll call ::ensure_buffers_for_level()
1018            with the right value and do the right thing.
1019         */
1020
1021         if (!_mixdown_buffers.empty()) {
1022                 ensure_buffers_for_level_locked ( _mixdown_buffers.size(), framerate);
1023         }
1024 }
1025
1026 void
1027 AudioSource::ensure_buffers_for_level (uint32_t level, framecnt_t frame_rate)
1028 {
1029         Glib::Threads::Mutex::Lock lm (_level_buffer_lock);
1030         ensure_buffers_for_level_locked (level, frame_rate);
1031 }
1032
1033 void
1034 AudioSource::ensure_buffers_for_level_locked (uint32_t level, framecnt_t frame_rate)
1035 {
1036         framecnt_t nframes = (framecnt_t) floor (Config->get_audio_playback_buffer_seconds() * frame_rate);
1037
1038         /* this may be called because either "level" or "frame_rate" have
1039          * changed. and it may be called with "level" smaller than the current
1040          * number of buffers, because a new compound region has been created at
1041          * a more shallow level than the deepest one we currently have.
1042          */
1043
1044         uint32_t limit = max ((size_t) level, _mixdown_buffers.size());
1045
1046         _mixdown_buffers.clear ();
1047         _gain_buffers.clear ();
1048
1049         for (uint32_t n = 0; n < limit; ++n) {
1050                 _mixdown_buffers.push_back (boost::shared_array<Sample> (new Sample[nframes]));
1051                 _gain_buffers.push_back (boost::shared_array<gain_t> (new gain_t[nframes]));
1052         }
1053 }