2 Copyright (C) 2000 Paul Davis
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.
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.
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.
21 #include <sys/utime.h>
37 #ifdef PLATFORM_WINDOWS
46 #include <glib/gstdio.h>
48 #include <boost/scoped_ptr.hpp>
50 #include <glibmm/fileutils.h>
51 #include <glibmm/miscutils.h>
53 #include "pbd/scoped_file_descriptor.h"
54 #include "pbd/xml++.h"
56 #include "ardour/audiosource.h"
57 #include "ardour/rc_configuration.h"
58 #include "ardour/runtime_functions.h"
62 #include "ardour/debug.h"
65 using namespace ARDOUR;
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;
73 /** true if we want peakfiles (e.g. if we are displaying a GUI) */
74 bool AudioSource::_build_peakfiles = false;
78 AudioSource::AudioSource (Session& s, const string& name)
79 : Source (s, DataType::AUDIO, name)
82 , _peaks_built (false)
84 , peak_leftover_cnt (0)
85 , peak_leftover_size (0)
90 , _last_raw_map_length (0)
94 AudioSource::AudioSource (Session& s, const XMLNode& node)
98 , _peaks_built (false)
100 , peak_leftover_cnt (0)
101 , peak_leftover_size (0)
106 , _last_raw_map_length (0)
108 if (set_state (node, Stateful::loading_state_version)) {
109 throw failed_constructor();
113 AudioSource::~AudioSource ()
115 /* shouldn't happen but make sure we don't leak file descriptors anyway */
117 if (peak_leftover_cnt) {
118 cerr << "AudioSource destroyed with leftover peak data pending" << endl;
121 if ((-1) != _peakfile_fd) {
122 close (_peakfile_fd);
126 delete [] peak_leftovers;
130 AudioSource::get_state ()
132 XMLNode& node (Source::get_state());
134 if (_captured_for.length()) {
135 node.add_property ("captured-for", _captured_for);
142 AudioSource::set_state (const XMLNode& node, int /*version*/)
144 const XMLProperty* prop;
146 if ((prop = node.property ("captured-for")) != 0) {
147 _captured_for = prop->value();
154 AudioSource::empty () const
160 AudioSource::length (framepos_t /*pos*/) const
166 AudioSource::update_length (framecnt_t len)
174 /***********************************************************************
176 ***********************************************************************/
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.
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.
188 AudioSource::peaks_ready (boost::function<void()> doThisWhenReady, ScopedConnection** connect_here_if_not, EventLoop* event_loop) const
191 Glib::Threads::Mutex::Lock lm (_peaks_ready_lock);
193 if (!(ret = _peaks_built)) {
194 *connect_here_if_not = new ScopedConnection;
195 PeaksReady.connect (**connect_here_if_not, MISSING_INVALIDATOR, doThisWhenReady, event_loop);
202 AudioSource::touch_peakfile ()
206 if (g_stat (_peakpath.c_str(), &statbuf) != 0 || statbuf.st_size == 0) {
212 tbuf.actime = statbuf.st_atime;
213 tbuf.modtime = time ((time_t*) 0);
215 g_utime (_peakpath.c_str(), &tbuf);
219 AudioSource::rename_peakfile (string newpath)
221 /* caller must hold _lock */
223 string oldpath = _peakpath;
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;
238 AudioSource::initialize_peakfile (const string& audio_path)
242 _peakpath = construct_peak_filepath (audio_path);
244 DEBUG_TRACE(DEBUG::Peaks, string_compose ("Initialize Peakfile %1 for Audio file %2\n", _peakpath, audio_path));
246 /* if the peak file should be there, but isn't .... */
248 if (!empty() && !Glib::file_test (_peakpath.c_str(), Glib::FILE_TEST_EXISTS)) {
249 _peakpath = find_broken_peakfile (_peakpath, audio_path);
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 */
256 error << string_compose(_("AudioSource: cannot stat peakfile \"%1\""), _peakpath) << endmsg;
260 DEBUG_TRACE(DEBUG::Peaks, string_compose("Peakfile %1 does not exist\n", _peakpath));
262 _peaks_built = false;
266 /* we found it in the peaks dir, so check it out */
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;
272 // Check if the audio file has changed since the peakfile was built.
274 int err = g_stat (audio_path.c_str(), &stat_file);
278 /* no audio path - nested source or we can't
279 read it or ... whatever, use the peakfile as-is.
281 DEBUG_TRACE(DEBUG::Peaks, string_compose("Error when calling stat on Peakfile %1\n", _peakpath));
284 _peak_byte_max = statbuf.st_size;
288 /* allow 6 seconds slop on checking peak vs. file times because of various
292 if (stat_file.st_mtime > statbuf.st_mtime && (stat_file.st_mtime - statbuf.st_mtime > 6)) {
293 _peaks_built = false;
297 _peak_byte_max = statbuf.st_size;
303 if (!empty() && !_peaks_built && _build_missing_peakfiles && _build_peakfiles) {
304 build_peaks_from_scratch ();
311 AudioSource::read (Sample *dst, framepos_t start, framecnt_t cnt, int /*channel*/) const
315 Glib::Threads::Mutex::Lock lm (_lock);
316 return read_unlocked (dst, start, cnt);
320 AudioSource::write (Sample *dst, framecnt_t cnt)
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);
329 AudioSource::read_peaks (PeakData *peaks, framecnt_t npeaks, framepos_t start, framecnt_t cnt, double samples_per_visual_peak) const
331 return read_peaks_with_fpp (peaks, npeaks, start, cnt, samples_per_visual_peak, _FPP);
334 /** @param peaks Buffer to write peak data.
335 * @param npeaks Number of peaks to write.
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
342 Glib::Threads::Mutex::Lock lm (_lock);
344 double expected_peaks;
345 PeakData::PeakDatum xmax;
346 PeakData::PeakDatum xmin;
348 #ifdef PLATFORM_WINDOWS
349 SYSTEM_INFO system_info;
350 GetSystemInfo (&system_info);
351 const int bufsize = system_info.dwAllocationGranularity;;
353 const int bufsize = sysconf(_SC_PAGESIZE);
355 framecnt_t read_npeaks = npeaks;
356 framecnt_t zero_fill = 0;
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;
366 if (!_captured_for.empty()) {
368 /* _captured_for is only set after a capture pass is
369 * complete. so we know that capturing is finished for this
370 * file, and now we can check actual size of the peakfile is at
371 * least large enough for all the data in the audio file. if it
372 * is too short, assume that a crash or other error truncated
373 * it, and rebuild it from scratch.
375 * XXX this may not work for destructive recording, but we
376 * might decided to get rid of that anyway.
380 const off_t expected_file_size = (_length / (double) samples_per_file_peak) * sizeof (PeakData);
382 if (statbuf.st_size < expected_file_size) {
383 warning << string_compose (_("peak file %1 is truncated from %2 to %3"), _peakpath, expected_file_size, statbuf.st_size) << endmsg;
384 const_cast<AudioSource*>(this)->build_peaks_from_scratch ();
385 if (g_stat (_peakpath.c_str(), &statbuf) != 0) {
386 error << string_compose (_("Cannot open peakfile @ %1 for size check (%2) after rebuild"), _peakpath, strerror (errno)) << endmsg;
388 if (statbuf.st_size < expected_file_size) {
389 fatal << "peak file is still truncated after rebuild" << endmsg;
395 ScopedFileDescriptor sfd (g_open (_peakpath.c_str(), O_RDONLY, 0444));
398 error << string_compose (_("Cannot open peakfile @ %1 for reading (%2)"), _peakpath, strerror (errno)) << endmsg;
402 scale = npeaks/expected_peaks;
405 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"
406 , npeaks, start, cnt, _length, samples_per_visual_peak, expected_peaks, scale, peaks));
408 /* fix for near-end-of-file conditions */
410 if (cnt > _length - start) {
411 // cerr << "too close to end @ " << _length << " given " << start << " + " << cnt << " (" << _length - start << ")" << endl;
412 cnt = _length - start;
413 read_npeaks = min ((framecnt_t) floor (cnt / samples_per_visual_peak), npeaks);
414 zero_fill = npeaks - read_npeaks;
415 expected_peaks = (cnt / (double) samples_per_file_peak);
416 scale = npeaks/expected_peaks;
419 // cerr << "actual npeaks = " << read_npeaks << " zf = " << zero_fill << endl;
423 DEBUG_TRACE (DEBUG::Peaks, "RAW DATA\n");
425 /* no scaling at all, just get the sample data and duplicate it for
426 both max and min peak values.
429 boost::scoped_array<Sample> raw_staging(new Sample[cnt]);
431 if (read_unlocked (raw_staging.get(), start, cnt) != cnt) {
432 error << _("cannot read sample data for unscaled peak computation") << endmsg;
436 for (framecnt_t i = 0; i < npeaks; ++i) {
437 peaks[i].max = raw_staging[i];
438 peaks[i].min = raw_staging[i];
445 off_t first_peak_byte = (start / samples_per_file_peak) * sizeof (PeakData);
446 size_t bytes_to_read = sizeof (PeakData) * read_npeaks;
447 /* open, read, close */
449 DEBUG_TRACE (DEBUG::Peaks, "DIRECT PEAKS\n");
451 off_t map_off = first_peak_byte;
452 off_t read_map_off = map_off & ~(bufsize - 1);
453 off_t map_delta = map_off - read_map_off;
454 size_t map_length = bytes_to_read + map_delta;
456 if (_first_run || (_last_scale != samples_per_visual_peak) || (_last_map_off != map_off) || (_last_raw_map_length < bytes_to_read)) {
457 peak_cache.reset (new PeakData[npeaks]);
459 #ifdef PLATFORM_WINDOWS
460 HANDLE file_handle = (HANDLE) _get_osfhandle(int(sfd));
465 map_handle = CreateFileMapping(file_handle, NULL, PAGE_READONLY, 0, 0, NULL);
466 if (map_handle == NULL) {
467 error << string_compose (_("map failed - could not create file mapping for peakfile %1."), _peakpath) << endmsg;
471 view_handle = MapViewOfFile(map_handle, FILE_MAP_READ, 0, read_map_off, map_length);
472 if (view_handle == NULL) {
473 error << string_compose (_("map failed - could not map peakfile %1."), _peakpath) << endmsg;
477 addr = (char*) view_handle;
479 memcpy ((void*)peak_cache.get(), (void*)(addr + map_delta), bytes_to_read);
481 err_flag = UnmapViewOfFile (view_handle);
482 err_flag = CloseHandle(map_handle);
484 error << string_compose (_("unmap failed - could not unmap peakfile %1."), _peakpath) << endmsg;
488 addr = (char*) mmap (0, map_length, PROT_READ, MAP_PRIVATE, sfd, read_map_off);
489 if (addr == MAP_FAILED) {
490 error << string_compose (_("map failed - could not mmap peakfile %1."), _peakpath) << endmsg;
494 memcpy ((void*)peak_cache.get(), (void*)(addr + map_delta), bytes_to_read);
495 munmap (addr, map_length);
498 memset (&peak_cache[read_npeaks], 0, sizeof (PeakData) * zero_fill);
502 _last_scale = samples_per_visual_peak;
503 _last_map_off = map_off;
504 _last_raw_map_length = bytes_to_read;
507 memcpy ((void*)peaks, (void*)peak_cache.get(), npeaks * sizeof(PeakData));
514 DEBUG_TRACE (DEBUG::Peaks, "DOWNSAMPLE\n");
518 - more frames-per-peak (lower resolution) than the peakfile, or to put it another way,
519 - less peaks than the peakfile holds for the same range
521 So, read a block into a staging area, and then downsample from there.
523 to avoid confusion, I'll refer to the requested peaks as visual_peaks and the peakfile peaks as stored_peaks
526 const framecnt_t chunksize = (framecnt_t) expected_peaks; // we read all the peaks we need in one hit.
528 /* compute the rounded up frame position */
530 framepos_t current_stored_peak = (framepos_t) ceil (start / (double) samples_per_file_peak);
531 framepos_t next_visual_peak = (framepos_t) ceil (start / samples_per_visual_peak);
532 double next_visual_peak_frame = next_visual_peak * samples_per_visual_peak;
533 framepos_t stored_peak_before_next_visual_peak = (framepos_t) next_visual_peak_frame / samples_per_file_peak;
534 framecnt_t nvisual_peaks = 0;
537 /* handle the case where the initial visual peak is on a pixel boundary */
539 current_stored_peak = min (current_stored_peak, stored_peak_before_next_visual_peak);
541 /* open ... close during out: handling */
543 off_t map_off = (uint32_t) (ceil (start / (double) samples_per_file_peak)) * sizeof(PeakData);
544 off_t read_map_off = map_off & ~(bufsize - 1);
545 off_t map_delta = map_off - read_map_off;
546 size_t raw_map_length = chunksize * sizeof(PeakData);
547 size_t map_length = (chunksize * sizeof(PeakData)) + map_delta;
549 if (_first_run || (_last_scale != samples_per_visual_peak) || (_last_map_off != map_off) || (_last_raw_map_length < raw_map_length)) {
550 peak_cache.reset (new PeakData[npeaks]);
551 boost::scoped_array<PeakData> staging (new PeakData[chunksize]);
554 #ifdef PLATFORM_WINDOWS
555 HANDLE file_handle = (HANDLE) _get_osfhandle(int(sfd));
560 map_handle = CreateFileMapping(file_handle, NULL, PAGE_READONLY, 0, 0, NULL);
561 if (map_handle == NULL) {
562 error << string_compose (_("map failed - could not create file mapping for peakfile %1."), _peakpath) << endmsg;
566 view_handle = MapViewOfFile(map_handle, FILE_MAP_READ, 0, read_map_off, map_length);
567 if (view_handle == NULL) {
568 error << string_compose (_("map failed - could not map peakfile %1."), _peakpath) << endmsg;
572 addr = (char *) view_handle;
574 memcpy ((void*)staging.get(), (void*)(addr + map_delta), raw_map_length);
576 err_flag = UnmapViewOfFile (view_handle);
577 err_flag = CloseHandle(map_handle);
579 error << string_compose (_("unmap failed - could not unmap peakfile %1."), _peakpath) << endmsg;
583 addr = (char*) mmap (0, map_length, PROT_READ, MAP_PRIVATE, sfd, read_map_off);
584 if (addr == MAP_FAILED) {
585 error << string_compose (_("map failed - could not mmap peakfile %1."), _peakpath) << endmsg;
589 memcpy ((void*)staging.get(), (void*)(addr + map_delta), raw_map_length);
590 munmap (addr, map_length);
592 while (nvisual_peaks < read_npeaks) {
597 while ((current_stored_peak <= stored_peak_before_next_visual_peak) && (i < chunksize)) {
599 xmax = max (xmax, staging[i].max);
600 xmin = min (xmin, staging[i].min);
602 ++current_stored_peak;
605 peak_cache[nvisual_peaks].max = xmax;
606 peak_cache[nvisual_peaks].min = xmin;
608 next_visual_peak_frame = min ((double) start + cnt, (next_visual_peak_frame + samples_per_visual_peak));
609 stored_peak_before_next_visual_peak = (uint32_t) next_visual_peak_frame / samples_per_file_peak;
613 cerr << "Zero fill end of peaks (@ " << read_npeaks << " with " << zero_fill << ")" << endl;
614 memset (&peak_cache[read_npeaks], 0, sizeof (PeakData) * zero_fill);
618 _last_scale = samples_per_visual_peak;
619 _last_map_off = map_off;
620 _last_raw_map_length = raw_map_length;
623 memcpy ((void*)peaks, (void*)peak_cache.get(), npeaks * sizeof(PeakData));
626 DEBUG_TRACE (DEBUG::Peaks, "UPSAMPLE\n");
630 - less frames-per-peak (more resolution)
631 - more peaks than stored in the Peakfile
633 So, fetch data from the raw source, and generate peak
637 framecnt_t frames_read = 0;
638 framepos_t current_frame = start;
640 framecnt_t nvisual_peaks = 0;
641 framecnt_t chunksize = (framecnt_t) min (cnt, (framecnt_t) 4096);
642 boost::scoped_array<Sample> raw_staging(new Sample[chunksize]);
644 framepos_t frame_pos = start;
645 double pixel_pos = floor (frame_pos / samples_per_visual_peak);
646 double next_pixel_pos = ceil (frame_pos / samples_per_visual_peak);
647 double pixels_per_frame = 1.0 / samples_per_visual_peak;
652 while (nvisual_peaks < read_npeaks) {
654 if (i == frames_read) {
656 to_read = min (chunksize, (framecnt_t)(_length - current_frame));
658 if (current_frame >= _length) {
660 /* hmm, error condition - we've reached the end of the file
661 without generating all the peak data. cook up a zero-filled
662 data buffer and then use it. this is simpler than
663 adjusting zero_fill and read_npeaks and then breaking out of
667 memset (raw_staging.get(), 0, sizeof (Sample) * chunksize);
671 to_read = min (chunksize, (_length - current_frame));
674 if ((frames_read = read_unlocked (raw_staging.get(), current_frame, to_read)) == 0) {
675 error << string_compose(_("AudioSource[%1]: peak read - cannot read %2 samples at offset %3 of %4 (%5)"),
676 _name, to_read, current_frame, _length, strerror (errno))
685 xmax = max (xmax, raw_staging[i]);
686 xmin = min (xmin, raw_staging[i]);
689 pixel_pos += pixels_per_frame;
691 if (pixel_pos >= next_pixel_pos) {
693 peaks[nvisual_peaks].max = xmax;
694 peaks[nvisual_peaks].min = xmin;
699 next_pixel_pos = ceil (pixel_pos + 0.5);
704 memset (&peaks[read_npeaks], 0, sizeof (PeakData) * zero_fill);
708 DEBUG_TRACE (DEBUG::Peaks, "READPEAKS DONE\n");
713 AudioSource::build_peaks_from_scratch ()
715 const framecnt_t bufsize = 65536; // 256kB per disk read for mono data is about ideal
717 DEBUG_TRACE (DEBUG::Peaks, "Building peaks from scratch\n");
722 /* hold lock while building peaks */
724 Glib::Threads::Mutex::Lock lp (_lock);
726 if (prepare_for_peakfile_writes ()) {
730 framecnt_t current_frame = 0;
731 framecnt_t cnt = _length;
733 _peaks_built = false;
734 boost::scoped_array<Sample> buf(new Sample[bufsize]);
738 framecnt_t frames_to_read = min (bufsize, cnt);
739 framecnt_t frames_read;
741 if ((frames_read = read_unlocked (buf.get(), current_frame, frames_to_read)) != frames_to_read) {
742 error << string_compose(_("%1: could not write read raw data for peak computation (%2)"), _name, strerror (errno)) << endmsg;
743 done_with_peakfile_writes (false);
747 lp.release(); // allow butler to refill buffers
749 if (compute_and_write_peaks (buf.get(), current_frame, frames_read, true, false, _FPP)) {
753 current_frame += frames_read;
764 done_with_peakfile_writes ((cnt == 0));
772 DEBUG_TRACE (DEBUG::Peaks, string_compose("Could not write peak data, attempting to remove peakfile %1\n", _peakpath));
773 ::g_unlink (_peakpath.c_str());
780 AudioSource::prepare_for_peakfile_writes ()
782 if ((_peakfile_fd = g_open (_peakpath.c_str(), O_CREAT|O_RDWR, 0664)) < 0) {
783 error << string_compose(_("AudioSource: cannot open _peakpath (c) \"%1\" (%2)"), _peakpath, strerror (errno)) << endmsg;
790 AudioSource::done_with_peakfile_writes (bool done)
792 if (peak_leftover_cnt) {
793 compute_and_write_peaks (0, 0, 0, true, false, _FPP);
797 Glib::Threads::Mutex::Lock lm (_peaks_ready_lock);
799 PeaksReady (); /* EMIT SIGNAL */
802 close (_peakfile_fd);
806 /** @param first_frame Offset from the source start of the first frame to
807 * process. _lock MUST be held by caller.
810 AudioSource::compute_and_write_peaks (Sample* buf, framecnt_t first_frame, framecnt_t cnt,
811 bool force, bool intermediate_peaks_ready)
813 return compute_and_write_peaks (buf, first_frame, cnt, force, intermediate_peaks_ready, _FPP);
817 AudioSource::compute_and_write_peaks (Sample* buf, framecnt_t first_frame, framecnt_t cnt,
818 bool force, bool intermediate_peaks_ready, framecnt_t fpp)
821 uint32_t peaks_computed;
822 framepos_t current_frame;
823 framecnt_t frames_done;
824 const size_t blocksize = (128 * 1024);
825 off_t first_peak_byte;
826 boost::scoped_array<Sample> buf2;
828 if (_peakfile_fd < 0) {
829 if (prepare_for_peakfile_writes ()) {
835 if (peak_leftover_cnt) {
837 if (first_frame != peak_leftover_frame + peak_leftover_cnt) {
839 /* uh-oh, ::seek() since the last ::compute_and_write_peaks(),
840 and we have leftovers. flush a single peak (since the leftovers
841 never represent more than that, and restart.
846 x.min = peak_leftovers[0];
847 x.max = peak_leftovers[0];
849 off_t byte = (peak_leftover_frame / fpp) * sizeof (PeakData);
851 off_t offset = lseek (_peakfile_fd, byte, SEEK_SET);
853 if (offset != byte) {
854 error << string_compose(_("%1: could not seek in peak file data (%2)"), _name, strerror (errno)) << endmsg;
858 if (::write (_peakfile_fd, &x, sizeof (PeakData)) != sizeof (PeakData)) {
859 error << string_compose(_("%1: could not write peak file data (%2)"), _name, strerror (errno)) << endmsg;
863 _peak_byte_max = max (_peak_byte_max, (off_t) (byte + sizeof(PeakData)));
866 Glib::Threads::Mutex::Lock lm (_peaks_ready_lock);
867 PeakRangeReady (peak_leftover_frame, peak_leftover_cnt); /* EMIT SIGNAL */
868 if (intermediate_peaks_ready) {
869 PeaksReady (); /* EMIT SIGNAL */
873 /* left overs are done */
875 peak_leftover_cnt = 0;
879 /* else ... had leftovers, but they immediately preceed the new data, so just
880 merge them and compute.
883 /* make a new contiguous buffer containing leftovers and the new stuff */
885 to_do = cnt + peak_leftover_cnt;
886 buf2.reset(new Sample[to_do]);
889 memcpy (buf2.get(), peak_leftovers, peak_leftover_cnt * sizeof (Sample));
892 memcpy (buf2.get()+peak_leftover_cnt, buf, cnt * sizeof (Sample));
894 /* no more leftovers */
895 peak_leftover_cnt = 0;
897 /* use the temporary buffer */
900 /* make sure that when we write into the peakfile, we startup where we left off */
902 first_frame = peak_leftover_frame;
908 boost::scoped_array<PeakData> peakbuf(new PeakData[(to_do/fpp)+1]);
910 current_frame = first_frame;
915 /* if some frames were passed in (i.e. we're not flushing leftovers)
916 and there are less than fpp to do, save them till
920 if (force && (to_do < fpp)) {
921 /* keep the left overs around for next time */
923 if (peak_leftover_size < to_do) {
924 delete [] peak_leftovers;
925 peak_leftovers = new Sample[to_do];
926 peak_leftover_size = to_do;
928 memcpy (peak_leftovers, buf, to_do * sizeof (Sample));
929 peak_leftover_cnt = to_do;
930 peak_leftover_frame = current_frame;
937 framecnt_t this_time = min (fpp, to_do);
939 peakbuf[peaks_computed].max = buf[0];
940 peakbuf[peaks_computed].min = buf[0];
942 ARDOUR::find_peaks (buf+1, this_time-1, &peakbuf[peaks_computed].min, &peakbuf[peaks_computed].max);
947 frames_done += this_time;
948 current_frame += this_time;
951 first_peak_byte = (first_frame / fpp) * sizeof (PeakData);
953 if (can_truncate_peaks()) {
955 /* on some filesystems (ext3, at least) this helps to reduce fragmentation of
956 the peakfiles. its not guaranteed to do so, and even on ext3 (as of december 2006)
957 it does not cause single-extent allocation even for peakfiles of
958 less than BLOCKSIZE bytes. only call ftruncate if we'll make the file larger.
961 off_t endpos = lseek (_peakfile_fd, 0, SEEK_END);
962 off_t target_length = blocksize * ((first_peak_byte + blocksize + 1) / blocksize);
964 if (endpos < target_length) {
965 DEBUG_TRACE(DEBUG::Peaks, string_compose ("Truncating Peakfile %1\n", _peakpath));
966 if (ftruncate (_peakfile_fd, target_length)) {
967 /* error doesn't actually matter so continue on without testing */
973 off_t offset = lseek(_peakfile_fd, first_peak_byte, SEEK_SET);
975 if (offset != first_peak_byte) {
976 error << string_compose(_("%1: could not seek in peak file data (%2)"), _name, strerror (errno)) << endmsg;
980 ssize_t bytes_to_write = sizeof (PeakData) * peaks_computed;
982 ssize_t bytes_written = ::write (_peakfile_fd, peakbuf.get(), bytes_to_write);
984 if (bytes_written != bytes_to_write) {
985 error << string_compose(_("%1: could not write peak file data (%2)"), _name, strerror (errno)) << endmsg;
989 _peak_byte_max = max (_peak_byte_max, (off_t) (first_peak_byte + bytes_to_write));
992 Glib::Threads::Mutex::Lock lm (_peaks_ready_lock);
993 PeakRangeReady (first_frame, frames_done); /* EMIT SIGNAL */
994 if (intermediate_peaks_ready) {
995 PeaksReady (); /* EMIT SIGNAL */
1003 AudioSource::truncate_peakfile ()
1005 if (_peakfile_fd < 0) {
1006 error << string_compose (_("programming error: %1"), "AudioSource::truncate_peakfile() called without open peakfile descriptor")
1011 /* truncate the peakfile down to its natural length if necessary */
1013 off_t end = lseek (_peakfile_fd, 0, SEEK_END);
1015 if (end > _peak_byte_max) {
1016 DEBUG_TRACE(DEBUG::Peaks, string_compose ("Truncating Peakfile %1\n", _peakpath));
1017 if (ftruncate (_peakfile_fd, _peak_byte_max)) {
1018 error << string_compose (_("could not truncate peakfile %1 to %2 (error: %3)"),
1019 _peakpath, _peak_byte_max, errno) << endmsg;
1025 AudioSource::available_peaks (double zoom_factor) const
1027 if (zoom_factor < _FPP) {
1028 return length(_timeline_position); // peak data will come from the audio file
1031 /* peak data comes from peakfile, but the filesize might not represent
1032 the valid data due to ftruncate optimizations, so use _peak_byte_max state.
1033 XXX - there might be some atomicity issues here, we should probably add a lock,
1034 but _peak_byte_max only monotonically increases after initialization.
1037 off_t end = _peak_byte_max;
1039 return (end/sizeof(PeakData)) * _FPP;
1043 AudioSource::mark_streaming_write_completed (const Lock& lock)
1045 Glib::Threads::Mutex::Lock lm (_peaks_ready_lock);
1048 PeaksReady (); /* EMIT SIGNAL */
1053 AudioSource::allocate_working_buffers (framecnt_t framerate)
1055 Glib::Threads::Mutex::Lock lm (_level_buffer_lock);
1058 /* Note: we don't need any buffers allocated until
1059 a level 1 audiosource is created, at which
1060 time we'll call ::ensure_buffers_for_level()
1061 with the right value and do the right thing.
1064 if (!_mixdown_buffers.empty()) {
1065 ensure_buffers_for_level_locked ( _mixdown_buffers.size(), framerate);
1070 AudioSource::ensure_buffers_for_level (uint32_t level, framecnt_t frame_rate)
1072 Glib::Threads::Mutex::Lock lm (_level_buffer_lock);
1073 ensure_buffers_for_level_locked (level, frame_rate);
1077 AudioSource::ensure_buffers_for_level_locked (uint32_t level, framecnt_t frame_rate)
1079 framecnt_t nframes = (framecnt_t) floor (Config->get_audio_playback_buffer_seconds() * frame_rate);
1081 /* this may be called because either "level" or "frame_rate" have
1082 * changed. and it may be called with "level" smaller than the current
1083 * number of buffers, because a new compound region has been created at
1084 * a more shallow level than the deepest one we currently have.
1087 uint32_t limit = max ((size_t) level, _mixdown_buffers.size());
1089 _mixdown_buffers.clear ();
1090 _gain_buffers.clear ();
1092 for (uint32_t n = 0; n < limit; ++n) {
1093 _mixdown_buffers.push_back (boost::shared_array<Sample> (new Sample[nframes]));
1094 _gain_buffers.push_back (boost::shared_array<gain_t> (new gain_t[nframes]));