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