merge monitor_section branch
[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 read_npeaks = npeaks;
357         framecnt_t zero_fill = 0;
358
359         ScopedFileDescriptor sfd (::open (peakpath.c_str(), O_RDONLY));
360
361         if (sfd < 0) {
362                 error << string_compose (_("Cannot open peakfile @ %1 for reading (%2)"), peakpath, strerror (errno)) << endmsg;
363                 return -1;
364         }
365                                   
366         expected_peaks = (cnt / (double) samples_per_file_peak);
367         scale = npeaks/expected_peaks;
368
369         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"
370                         , npeaks, start, cnt, _length, samples_per_visual_peak, expected_peaks, scale, peaks));
371
372         /* fix for near-end-of-file conditions */
373
374         if (cnt > _length - start) {
375                 // cerr << "too close to end @ " << _length << " given " << start << " + " << cnt << " (" << _length - start << ")" << endl;
376                 cnt = _length - start;
377                 read_npeaks = min ((framecnt_t) floor (cnt / samples_per_visual_peak), npeaks);
378                 zero_fill = npeaks - read_npeaks;
379         }
380
381         // cerr << "actual npeaks = " << read_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) * read_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                         char* addr;
421 #ifdef PLATFORM_WINDOWS
422                         HANDLE file_handle = (HANDLE) _get_osfhandle(int(sfd));
423                         HANDLE map_handle;
424                         LPVOID view_handle;
425                         bool err_flag;
426
427                         map_handle = CreateFileMapping(file_handle, NULL, PAGE_READONLY, 0, 0, NULL);
428                         if (map_handle == NULL) {
429                                 error << string_compose (_("map failed - could not create file mapping for peakfile %1."), peakpath) << endmsg;
430                                 return -1;
431                         }
432
433                         view_handle = MapViewOfFile(map_handle, FILE_MAP_READ, 0, read_map_off, map_length);
434                         if (view_handle == NULL) {
435                                 error << string_compose (_("map failed - could not map peakfile %1."), peakpath) << endmsg;
436                                 return -1;
437                         }
438
439                         addr = (char*) view_handle;
440
441                         memcpy ((void*)peak_cache.get(), (void*)(addr + map_delta), bytes_to_read);
442
443                         err_flag = UnmapViewOfFile (view_handle);
444                         err_flag = CloseHandle(map_handle);
445                         if(!err_flag) {
446                                 error << string_compose (_("unmap failed - could not unmap peakfile %1."), peakpath) << endmsg;
447                                 return -1;
448                         }
449 #else
450                         addr = (char*) mmap (0, map_length, PROT_READ, MAP_PRIVATE, sfd, read_map_off);
451                         if (addr ==  MAP_FAILED) {
452                                 error << string_compose (_("map failed - could not mmap peakfile %1."), peakpath) << endmsg;
453                                 return -1;
454                         }
455
456                         memcpy ((void*)peak_cache.get(), (void*)(addr + map_delta), bytes_to_read);
457                         munmap (addr, map_length);
458 #endif
459                         if (zero_fill) {
460                                 memset (&peak_cache[read_npeaks], 0, sizeof (PeakData) * zero_fill);
461                         }
462
463                         _first_run = false;
464                         _last_scale = samples_per_visual_peak;
465                         _last_map_off = map_off;
466                         _last_raw_map_length = bytes_to_read;
467                 }
468
469                 memcpy ((void*)peaks, (void*)peak_cache.get(), npeaks * sizeof(PeakData));
470
471                 return 0;
472         }
473
474         if (scale < 1.0) {
475
476                 DEBUG_TRACE (DEBUG::Peaks, "DOWNSAMPLE\n");
477
478                 /* the caller wants:
479
480                     - more frames-per-peak (lower resolution) than the peakfile, or to put it another way,
481                     - less peaks than the peakfile holds for the same range
482
483                     So, read a block into a staging area, and then downsample from there.
484
485                     to avoid confusion, I'll refer to the requested peaks as visual_peaks and the peakfile peaks as stored_peaks
486                 */
487
488                 const framecnt_t chunksize = (framecnt_t) expected_peaks; // we read all the peaks we need in one hit.
489
490                 /* compute the rounded up frame position  */
491
492                 framepos_t current_stored_peak = (framepos_t) ceil (start / (double) samples_per_file_peak);
493                 framepos_t next_visual_peak  = (framepos_t) ceil (start / samples_per_visual_peak);
494                 double     next_visual_peak_frame = next_visual_peak * samples_per_visual_peak;
495                 framepos_t stored_peak_before_next_visual_peak = (framepos_t) next_visual_peak_frame / samples_per_file_peak;
496                 framecnt_t nvisual_peaks = 0;
497                 uint32_t i = 0;
498
499                 /* handle the case where the initial visual peak is on a pixel boundary */
500
501                 current_stored_peak = min (current_stored_peak, stored_peak_before_next_visual_peak);
502
503                 /* open ... close during out: handling */
504
505                 off_t  map_off =  (uint32_t) (ceil (start / (double) samples_per_file_peak)) * sizeof(PeakData);
506                 off_t  read_map_off = map_off & ~(bufsize - 1);
507                 off_t  map_delta = map_off - read_map_off;
508                 size_t raw_map_length = chunksize * sizeof(PeakData);
509                 size_t map_length = (chunksize * sizeof(PeakData)) + map_delta;
510
511                 if (_first_run || (_last_scale != samples_per_visual_peak) || (_last_map_off != map_off) || (_last_raw_map_length < raw_map_length)) {
512                         peak_cache.reset (new PeakData[npeaks]);
513                         boost::scoped_array<PeakData> staging (new PeakData[chunksize]);
514
515                         char* addr;
516 #ifdef PLATFORM_WINDOWS
517                         HANDLE file_handle =  (HANDLE) _get_osfhandle(int(sfd));
518                         HANDLE map_handle;
519                         LPVOID view_handle;
520                         bool err_flag;
521
522                         map_handle = CreateFileMapping(file_handle, NULL, PAGE_READONLY, 0, 0, NULL);
523                         if (map_handle == NULL) {
524                                 error << string_compose (_("map failed - could not create file mapping for peakfile %1."), peakpath) << endmsg;
525                                 return -1;
526                         }
527
528                         view_handle = MapViewOfFile(map_handle, FILE_MAP_READ, 0, read_map_off, map_length);
529                         if (view_handle == NULL) {
530                                 error << string_compose (_("map failed - could not map peakfile %1."), peakpath) << endmsg;
531                                 return -1;
532                         }
533
534                         addr = (char *) view_handle;
535
536                         memcpy ((void*)staging.get(), (void*)(addr + map_delta), raw_map_length);
537
538                         err_flag = UnmapViewOfFile (view_handle);
539                         err_flag = CloseHandle(map_handle);
540                         if(!err_flag) {
541                                 error << string_compose (_("unmap failed - could not unmap peakfile %1."), peakpath) << endmsg;
542                                 return -1;
543                         }
544 #else
545                         addr = (char*) mmap (0, map_length, PROT_READ, MAP_PRIVATE, sfd, read_map_off);
546                         if (addr ==  MAP_FAILED) {
547                                 error << string_compose (_("map failed - could not mmap peakfile %1."), peakpath) << endmsg;
548                                 return -1;
549                         }
550
551                         memcpy ((void*)staging.get(), (void*)(addr + map_delta), raw_map_length);
552                         munmap (addr, map_length);
553 #endif
554                         while (nvisual_peaks < read_npeaks) {
555
556                                 xmax = -1.0;
557                                 xmin = 1.0;
558
559                                 while ((current_stored_peak <= stored_peak_before_next_visual_peak) && (i < chunksize)) {
560
561                                         xmax = max (xmax, staging[i].max);
562                                         xmin = min (xmin, staging[i].min);
563                                         ++i;
564                                         ++current_stored_peak;
565                                 }
566
567                                 peak_cache[nvisual_peaks].max = xmax;
568                                 peak_cache[nvisual_peaks].min = xmin;
569                                 ++nvisual_peaks;
570                                 next_visual_peak_frame =  min ((double) start + cnt, (next_visual_peak_frame + samples_per_visual_peak));
571                                 stored_peak_before_next_visual_peak = (uint32_t) next_visual_peak_frame / samples_per_file_peak;
572                         }
573
574                         if (zero_fill) {
575                                 cerr << "Zero fill end of peaks (@ " << read_npeaks << " with " << zero_fill << ")" << endl;
576                                 memset (&peak_cache[read_npeaks], 0, sizeof (PeakData) * zero_fill);
577                         }
578
579                         _first_run = false;
580                         _last_scale = samples_per_visual_peak;
581                         _last_map_off = map_off;
582                         _last_raw_map_length = raw_map_length;
583                 }
584
585                 memcpy ((void*)peaks, (void*)peak_cache.get(), npeaks * sizeof(PeakData));
586
587         } else {
588                 DEBUG_TRACE (DEBUG::Peaks, "UPSAMPLE\n");
589
590                 /* the caller wants
591
592                      - less frames-per-peak (more resolution)
593                      - more peaks than stored in the Peakfile
594
595                    So, fetch data from the raw source, and generate peak
596                    data on the fly.
597                 */
598
599                 framecnt_t frames_read = 0;
600                 framepos_t current_frame = start;
601                 framecnt_t i = 0;
602                 framecnt_t nvisual_peaks = 0;
603                 framecnt_t chunksize = (framecnt_t) min (cnt, (framecnt_t) 4096);
604                 boost::scoped_array<Sample> raw_staging(new Sample[chunksize]);
605
606                 framepos_t frame_pos = start;
607                 double pixel_pos = floor (frame_pos / samples_per_visual_peak);
608                 double next_pixel_pos = ceil (frame_pos / samples_per_visual_peak);
609                 double pixels_per_frame = 1.0 / samples_per_visual_peak;
610
611                 xmin = 1.0;
612                 xmax = -1.0;
613
614                 while (nvisual_peaks < read_npeaks) {
615
616                         if (i == frames_read) {
617
618                                 to_read = min (chunksize, (framecnt_t)(_length - current_frame));
619
620                                 if (current_frame >= _length) {
621
622                                         /* hmm, error condition - we've reached the end of the file
623                                            without generating all the peak data. cook up a zero-filled
624                                            data buffer and then use it. this is simpler than
625                                            adjusting zero_fill and read_npeaks and then breaking out of
626                                            this loop early
627                                         */
628
629                                         memset (raw_staging.get(), 0, sizeof (Sample) * chunksize);
630
631                                 } else {
632
633                                         to_read = min (chunksize, (_length - current_frame));
634
635
636                                         if ((frames_read = read_unlocked (raw_staging.get(), current_frame, to_read)) == 0) {
637                                                 error << string_compose(_("AudioSource[%1]: peak read - cannot read %2 samples at offset %3 of %4 (%5)"),
638                                                                         _name, to_read, current_frame, _length, strerror (errno))
639                                                       << endmsg;
640                                                 return -1;
641                                         }
642                                 }
643
644                                 i = 0;
645                         }
646
647                         xmax = max (xmax, raw_staging[i]);
648                         xmin = min (xmin, raw_staging[i]);
649                         ++i;
650                         ++current_frame;
651                         pixel_pos += pixels_per_frame;
652
653                         if (pixel_pos >= next_pixel_pos) {
654
655                                 peaks[nvisual_peaks].max = xmax;
656                                 peaks[nvisual_peaks].min = xmin;
657                                 ++nvisual_peaks;
658                                 xmin = 1.0;
659                                 xmax = -1.0;
660
661                                 next_pixel_pos = ceil (pixel_pos + 0.5);
662                         }
663                 }
664
665                 if (zero_fill) {
666                         memset (&peaks[read_npeaks], 0, sizeof (PeakData) * zero_fill);
667                 }
668         }
669
670         DEBUG_TRACE (DEBUG::Peaks, "READPEAKS DONE\n");
671         return 0;
672 }
673
674 int
675 AudioSource::build_peaks_from_scratch ()
676 {
677         const framecnt_t bufsize = 65536; // 256kB per disk read for mono data is about ideal
678
679         DEBUG_TRACE (DEBUG::Peaks, "Building peaks from scratch\n");
680
681         int ret = -1;
682
683         {
684                 /* hold lock while building peaks */
685
686                 Glib::Threads::Mutex::Lock lp (_lock);
687
688                 if (prepare_for_peakfile_writes ()) {
689                         goto out;
690                 }
691
692                 framecnt_t current_frame = 0;
693                 framecnt_t cnt = _length;
694
695                 _peaks_built = false;
696                 boost::scoped_array<Sample> buf(new Sample[bufsize]);
697
698                 while (cnt) {
699
700                         framecnt_t frames_to_read = min (bufsize, cnt);
701                         framecnt_t frames_read;
702                         
703                         if ((frames_read = read_unlocked (buf.get(), current_frame, frames_to_read)) != frames_to_read) {
704                                 error << string_compose(_("%1: could not write read raw data for peak computation (%2)"), _name, strerror (errno)) << endmsg;
705                                 done_with_peakfile_writes (false);
706                                 goto out;
707                         }
708
709                         if (compute_and_write_peaks (buf.get(), current_frame, frames_read, true, false, _FPP)) {
710                                 break;
711                         }
712
713                         current_frame += frames_read;
714                         cnt -= frames_read;
715                 }
716
717                 if (cnt == 0) {
718                         /* success */
719                         truncate_peakfile();
720                 }
721
722                 done_with_peakfile_writes ((cnt == 0));
723                 if (cnt == 0) {
724                         ret = 0;
725                 }
726         }
727
728   out:
729         if (ret) {
730                 DEBUG_TRACE (DEBUG::Peaks, string_compose("Could not write peak data, attempting to remove peakfile %1\n", peakpath));
731                 ::g_unlink (peakpath.c_str());
732         }
733
734         return ret;
735 }
736
737 int
738 AudioSource::prepare_for_peakfile_writes ()
739 {
740         if ((_peakfile_fd = open (peakpath.c_str(), O_CREAT|O_RDWR, 0664)) < 0) {
741                 error << string_compose(_("AudioSource: cannot open peakpath (c) \"%1\" (%2)"), peakpath, strerror (errno)) << endmsg;
742                 return -1;
743         }
744         return 0;
745 }
746
747 void
748 AudioSource::done_with_peakfile_writes (bool done)
749 {
750         if (peak_leftover_cnt) {
751                 compute_and_write_peaks (0, 0, 0, true, false, _FPP);
752         }
753
754         if (done) {
755                 Glib::Threads::Mutex::Lock lm (_peaks_ready_lock);
756                 _peaks_built = true;
757                 PeaksReady (); /* EMIT SIGNAL */
758         }
759
760         close (_peakfile_fd);
761         _peakfile_fd = -1;
762 }
763
764 /** @param first_frame Offset from the source start of the first frame to process */
765 int
766 AudioSource::compute_and_write_peaks (Sample* buf, framecnt_t first_frame, framecnt_t cnt,
767                                       bool force, bool intermediate_peaks_ready)
768 {
769         return compute_and_write_peaks (buf, first_frame, cnt, force, intermediate_peaks_ready, _FPP);
770 }
771
772 int
773 AudioSource::compute_and_write_peaks (Sample* buf, framecnt_t first_frame, framecnt_t cnt,
774                                       bool force, bool intermediate_peaks_ready, framecnt_t fpp)
775 {
776         framecnt_t to_do;
777         uint32_t  peaks_computed;
778         framepos_t current_frame;
779         framecnt_t frames_done;
780         const size_t blocksize = (128 * 1024);
781         off_t first_peak_byte;
782         boost::scoped_array<Sample> buf2;
783
784         if (_peakfile_fd < 0) {
785                 if (prepare_for_peakfile_writes ()) {
786                         return -1;
787                 }
788         }
789
790   restart:
791         if (peak_leftover_cnt) {
792
793                 if (first_frame != peak_leftover_frame + peak_leftover_cnt) {
794
795                         /* uh-oh, ::seek() since the last ::compute_and_write_peaks(),
796                            and we have leftovers. flush a single peak (since the leftovers
797                            never represent more than that, and restart.
798                         */
799
800                         PeakData x;
801
802                         x.min = peak_leftovers[0];
803                         x.max = peak_leftovers[0];
804
805                         off_t byte = (peak_leftover_frame / fpp) * sizeof (PeakData);
806
807                         off_t offset = lseek (_peakfile_fd, byte, SEEK_SET);
808
809                         if (offset != byte) {
810                                 error << string_compose(_("%1: could not seek in peak file data (%2)"), _name, strerror (errno)) << endmsg;
811                                 return -1;
812                         }
813
814                         if (::write (_peakfile_fd, &x, sizeof (PeakData)) != sizeof (PeakData)) {
815                                 error << string_compose(_("%1: could not write peak file data (%2)"), _name, strerror (errno)) << endmsg;
816                                 return -1;
817                         }
818
819                         _peak_byte_max = max (_peak_byte_max, (off_t) (byte + sizeof(PeakData)));
820
821                         {
822                                 Glib::Threads::Mutex::Lock lm (_peaks_ready_lock);
823                                 PeakRangeReady (peak_leftover_frame, peak_leftover_cnt); /* EMIT SIGNAL */
824                                 if (intermediate_peaks_ready) {
825                                         PeaksReady (); /* EMIT SIGNAL */
826                                 }
827                         }
828
829                         /* left overs are done */
830
831                         peak_leftover_cnt = 0;
832                         goto restart;
833                 }
834
835                 /* else ... had leftovers, but they immediately preceed the new data, so just
836                    merge them and compute.
837                 */
838
839                 /* make a new contiguous buffer containing leftovers and the new stuff */
840
841                 to_do = cnt + peak_leftover_cnt;
842                 buf2.reset(new Sample[to_do]);
843
844                 /* the remnants */
845                 memcpy (buf2.get(), peak_leftovers, peak_leftover_cnt * sizeof (Sample));
846
847                 /* the new stuff */
848                 memcpy (buf2.get()+peak_leftover_cnt, buf, cnt * sizeof (Sample));
849
850                 /* no more leftovers */
851                 peak_leftover_cnt = 0;
852
853                 /* use the temporary buffer */
854                 buf = buf2.get();
855
856                 /* make sure that when we write into the peakfile, we startup where we left off */
857
858                 first_frame = peak_leftover_frame;
859
860         } else {
861                 to_do = cnt;
862         }
863
864         boost::scoped_array<PeakData> peakbuf(new PeakData[(to_do/fpp)+1]);
865         peaks_computed = 0;
866         current_frame = first_frame;
867         frames_done = 0;
868
869         while (to_do) {
870
871                 /* if some frames were passed in (i.e. we're not flushing leftovers)
872                    and there are less than fpp to do, save them till
873                    next time
874                 */
875
876                 if (force && (to_do < fpp)) {
877                         /* keep the left overs around for next time */
878
879                         if (peak_leftover_size < to_do) {
880                                 delete [] peak_leftovers;
881                                 peak_leftovers = new Sample[to_do];
882                                 peak_leftover_size = to_do;
883                         }
884                         memcpy (peak_leftovers, buf, to_do * sizeof (Sample));
885                         peak_leftover_cnt = to_do;
886                         peak_leftover_frame = current_frame;
887
888                         /* done for now */
889
890                         break;
891                 }
892
893                 framecnt_t this_time = min (fpp, to_do);
894
895                 peakbuf[peaks_computed].max = buf[0];
896                 peakbuf[peaks_computed].min = buf[0];
897
898                 ARDOUR::find_peaks (buf+1, this_time-1, &peakbuf[peaks_computed].min, &peakbuf[peaks_computed].max);
899
900                 peaks_computed++;
901                 buf += this_time;
902                 to_do -= this_time;
903                 frames_done += this_time;
904                 current_frame += this_time;
905         }
906
907         first_peak_byte = (first_frame / fpp) * sizeof (PeakData);
908
909         if (can_truncate_peaks()) {
910
911                 /* on some filesystems (ext3, at least) this helps to reduce fragmentation of
912                    the peakfiles. its not guaranteed to do so, and even on ext3 (as of december 2006)
913                    it does not cause single-extent allocation even for peakfiles of
914                    less than BLOCKSIZE bytes.  only call ftruncate if we'll make the file larger.
915                 */
916
917                 off_t endpos = lseek (_peakfile_fd, 0, SEEK_END);
918                 off_t target_length = blocksize * ((first_peak_byte + blocksize + 1) / blocksize);
919
920                 if (endpos < target_length) {
921                         DEBUG_TRACE(DEBUG::Peaks, string_compose ("Truncating Peakfile %1\n", peakpath));
922                         if (ftruncate (_peakfile_fd, target_length)) {
923                                 /* error doesn't actually matter so continue on without testing */
924                         }
925                 }
926         }
927
928
929         off_t offset = lseek(_peakfile_fd, first_peak_byte, SEEK_SET);
930
931         if (offset != first_peak_byte) {
932                 error << string_compose(_("%1: could not seek in peak file data (%2)"), _name, strerror (errno)) << endmsg;
933                 return -1;
934         }
935
936         ssize_t bytes_to_write = sizeof (PeakData) * peaks_computed;
937
938         ssize_t bytes_written = ::write (_peakfile_fd, peakbuf.get(), bytes_to_write);
939
940         if (bytes_written != bytes_to_write) {
941                 error << string_compose(_("%1: could not write peak file data (%2)"), _name, strerror (errno)) << endmsg;
942                 return -1;
943         }
944
945         _peak_byte_max = max (_peak_byte_max, (off_t) (first_peak_byte + bytes_to_write));
946
947         if (frames_done) {
948                 Glib::Threads::Mutex::Lock lm (_peaks_ready_lock);
949                 PeakRangeReady (first_frame, frames_done); /* EMIT SIGNAL */
950                 if (intermediate_peaks_ready) {
951                         PeaksReady (); /* EMIT SIGNAL */
952                 }
953         }
954
955         return 0;
956 }
957
958 void
959 AudioSource::truncate_peakfile ()
960 {
961         if (_peakfile_fd < 0) {
962                 error << string_compose (_("programming error: %1"), "AudioSource::truncate_peakfile() called without open peakfile descriptor")
963                       << endmsg;
964                 return;
965         }
966
967         /* truncate the peakfile down to its natural length if necessary */
968
969         off_t end = lseek (_peakfile_fd, 0, SEEK_END);
970
971         if (end > _peak_byte_max) {
972                 DEBUG_TRACE(DEBUG::Peaks, string_compose ("Truncating Peakfile  %1\n", peakpath));
973                 if (ftruncate (_peakfile_fd, _peak_byte_max)) {
974                         error << string_compose (_("could not truncate peakfile %1 to %2 (error: %3)"),
975                                                  peakpath, _peak_byte_max, errno) << endmsg;
976                 }
977         }
978 }
979
980 framecnt_t
981 AudioSource::available_peaks (double zoom_factor) const
982 {
983         if (zoom_factor < _FPP) {
984                 return length(_timeline_position); // peak data will come from the audio file
985         }
986
987         /* peak data comes from peakfile, but the filesize might not represent
988            the valid data due to ftruncate optimizations, so use _peak_byte_max state.
989            XXX - there might be some atomicity issues here, we should probably add a lock,
990            but _peak_byte_max only monotonically increases after initialization.
991         */
992
993         off_t end = _peak_byte_max;
994
995         return (end/sizeof(PeakData)) * _FPP;
996 }
997
998 void
999 AudioSource::mark_streaming_write_completed (const Lock& lock)
1000 {
1001         Glib::Threads::Mutex::Lock lm (_peaks_ready_lock);
1002
1003         if (_peaks_built) {
1004                 PeaksReady (); /* EMIT SIGNAL */
1005         }
1006 }
1007
1008 void
1009 AudioSource::allocate_working_buffers (framecnt_t framerate)
1010 {
1011         Glib::Threads::Mutex::Lock lm (_level_buffer_lock);
1012
1013
1014         /* Note: we don't need any buffers allocated until
1015            a level 1 audiosource is created, at which
1016            time we'll call ::ensure_buffers_for_level()
1017            with the right value and do the right thing.
1018         */
1019
1020         if (!_mixdown_buffers.empty()) {
1021                 ensure_buffers_for_level_locked ( _mixdown_buffers.size(), framerate);
1022         }
1023 }
1024
1025 void
1026 AudioSource::ensure_buffers_for_level (uint32_t level, framecnt_t frame_rate)
1027 {
1028         Glib::Threads::Mutex::Lock lm (_level_buffer_lock);
1029         ensure_buffers_for_level_locked (level, frame_rate);
1030 }
1031
1032 void
1033 AudioSource::ensure_buffers_for_level_locked (uint32_t level, framecnt_t frame_rate)
1034 {
1035         framecnt_t nframes = (framecnt_t) floor (Config->get_audio_playback_buffer_seconds() * frame_rate);
1036
1037         /* this may be called because either "level" or "frame_rate" have
1038          * changed. and it may be called with "level" smaller than the current
1039          * number of buffers, because a new compound region has been created at
1040          * a more shallow level than the deepest one we currently have.
1041          */
1042
1043         uint32_t limit = max ((size_t) level, _mixdown_buffers.size());
1044
1045         _mixdown_buffers.clear ();
1046         _gain_buffers.clear ();
1047
1048         for (uint32_t n = 0; n < limit; ++n) {
1049                 _mixdown_buffers.push_back (boost::shared_array<Sample> (new Sample[nframes]));
1050                 _gain_buffers.push_back (boost::shared_array<gain_t> (new gain_t[nframes]));
1051         }
1052 }