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