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