2 * Copyright (C) 2000-2019 Paul Davis <paul@linuxaudiosystems.com>
3 * Copyright (C) 2006-2014 David Robillard <d@drobilla.net>
4 * Copyright (C) 2007-2016 Tim Mayberry <mojofunk@gmail.com>
5 * Copyright (C) 2008-2012 Carl Hetherington <carl@carlh.net>
6 * Copyright (C) 2013-2015 John Emmas <john@creativepost.co.uk>
7 * Copyright (C) 2015-2019 Robin Gareus <robin@gareus.org>
8 * Copyright (C) 2015 Nick Mainsbridge <mainsbridge@gmail.com>
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 2 of the License, or
13 * (at your option) any later version.
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
20 * You should have received a copy of the GNU General Public License along
21 * with this program; if not, write to the Free Software Foundation, Inc.,
22 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
26 #include <sys/utime.h>
41 #ifdef PLATFORM_WINDOWS
50 #include "pbd/gstdio_compat.h"
52 #include <boost/scoped_ptr.hpp>
54 #include <glibmm/fileutils.h>
55 #include <glibmm/miscutils.h>
57 #include "pbd/file_utils.h"
58 #include "pbd/playback_buffer.h"
59 #include "pbd/scoped_file_descriptor.h"
60 #include "pbd/xml++.h"
62 #include "ardour/audiosource.h"
63 #include "ardour/rc_configuration.h"
64 #include "ardour/runtime_functions.h"
65 #include "ardour/session.h"
69 #include "ardour/debug.h"
72 using namespace ARDOUR;
75 Glib::Threads::Mutex AudioSource::_level_buffer_lock;
76 vector<boost::shared_array<Sample> > AudioSource::_mixdown_buffers;
77 vector<boost::shared_array<gain_t> > AudioSource::_gain_buffers;
78 bool AudioSource::_build_missing_peakfiles = false;
80 /** true if we want peakfiles (e.g. if we are displaying a GUI) */
81 bool AudioSource::_build_peakfiles = false;
85 AudioSource::AudioSource (Session& s, const string& name)
86 : Source (s, DataType::AUDIO, name)
89 , _peaks_built (false)
91 , peak_leftover_cnt (0)
92 , peak_leftover_size (0)
97 , _last_raw_map_length (0)
101 AudioSource::AudioSource (Session& s, const XMLNode& node)
105 , _peaks_built (false)
107 , peak_leftover_cnt (0)
108 , peak_leftover_size (0)
113 , _last_raw_map_length (0)
115 if (set_state (node, Stateful::loading_state_version)) {
116 throw failed_constructor();
120 AudioSource::~AudioSource ()
122 /* shouldn't happen but make sure we don't leak file descriptors anyway */
124 if (peak_leftover_cnt) {
125 cerr << "AudioSource destroyed with leftover peak data pending" << endl;
128 if ((-1) != _peakfile_fd) {
129 close (_peakfile_fd);
133 delete [] peak_leftovers;
137 AudioSource::get_state ()
139 XMLNode& node (Source::get_state());
141 if (_captured_for.length()) {
142 node.set_property ("captured-for", _captured_for);
149 AudioSource::set_state (const XMLNode& node, int /*version*/)
151 node.get_property ("captured-for", _captured_for);
156 AudioSource::empty () const
162 AudioSource::length (samplepos_t /*pos*/) const
168 AudioSource::update_length (samplecnt_t len)
176 /***********************************************************************
178 ***********************************************************************/
180 /** Checks to see if peaks are ready. If so, we return true. If not, we return false, and
181 * things are set up so that doThisWhenReady is called when the peaks are ready.
182 * A new PBD::ScopedConnection is created for the associated connection and written to
183 * *connect_here_if_not.
185 * @param doThisWhenReady Function to call when peaks are ready (if they are not already).
186 * @param connect_here_if_not Address to write new ScopedConnection to.
187 * @param event_loop Event loop for doThisWhenReady to be called in.
190 AudioSource::peaks_ready (boost::function<void()> doThisWhenReady, ScopedConnection** connect_here_if_not, EventLoop* event_loop) const
193 Glib::Threads::Mutex::Lock lm (_peaks_ready_lock);
195 if (!(ret = _peaks_built)) {
196 *connect_here_if_not = new ScopedConnection;
197 PeaksReady.connect (**connect_here_if_not, MISSING_INVALIDATOR, doThisWhenReady, event_loop);
204 AudioSource::touch_peakfile ()
208 if (g_stat (_peakpath.c_str(), &statbuf) != 0 || statbuf.st_size == 0) {
214 tbuf.actime = statbuf.st_atime;
215 tbuf.modtime = time ((time_t*) 0);
217 g_utime (_peakpath.c_str(), &tbuf);
221 AudioSource::rename_peakfile (string newpath)
223 /* caller must hold _lock */
225 string oldpath = _peakpath;
227 if (Glib::file_test (oldpath, Glib::FILE_TEST_EXISTS)) {
228 if (g_rename (oldpath.c_str(), newpath.c_str()) != 0) {
229 error << string_compose (_("cannot rename peakfile for %1 from %2 to %3 (%4)"), _name, oldpath, newpath, strerror (errno)) << endmsg;
240 AudioSource::initialize_peakfile (const string& audio_path, const bool in_session)
242 Glib::Threads::Mutex::Lock lm (_initialize_peaks_lock);
245 _peakpath = construct_peak_filepath (audio_path, in_session);
247 if (!empty() && !Glib::file_test (_peakpath.c_str(), Glib::FILE_TEST_EXISTS)) {
248 string oldpeak = construct_peak_filepath (audio_path, in_session, true);
249 DEBUG_TRACE(DEBUG::Peaks, string_compose ("Looking for old peak file %1 for Audio file %2\n", oldpeak, audio_path));
250 if (Glib::file_test (oldpeak.c_str(), Glib::FILE_TEST_EXISTS)) {
251 // TODO use hard-link if possible
252 DEBUG_TRACE(DEBUG::Peaks, string_compose ("Copy old peakfile %1 to %2\n", oldpeak, _peakpath));
253 PBD::copy_file (oldpeak, _peakpath);
257 DEBUG_TRACE(DEBUG::Peaks, string_compose ("Initialize Peakfile %1 for Audio file %2\n", _peakpath, audio_path));
259 if (g_stat (_peakpath.c_str(), &statbuf)) {
260 if (errno != ENOENT) {
261 /* it exists in the peaks dir, but there is some kind of error */
263 error << string_compose(_("AudioSource: cannot stat peakfile \"%1\""), _peakpath) << endmsg;
267 DEBUG_TRACE(DEBUG::Peaks, string_compose("Peakfile %1 does not exist\n", _peakpath));
269 _peaks_built = false;
273 /* we found it in the peaks dir, so check it out */
275 if (statbuf.st_size == 0 || (statbuf.st_size < (off_t) ((length(_natural_position) / _FPP) * sizeof (PeakData)))) {
276 DEBUG_TRACE(DEBUG::Peaks, string_compose("Peakfile %1 is empty\n", _peakpath));
277 _peaks_built = false;
279 // Check if the audio file has changed since the peakfile was built.
281 int err = g_stat (audio_path.c_str(), &stat_file);
285 /* no audio path - nested source or we can't
286 read it or ... whatever, use the peakfile as-is.
288 DEBUG_TRACE(DEBUG::Peaks, string_compose("Error when calling stat on Peakfile %1\n", _peakpath));
291 _peak_byte_max = statbuf.st_size;
295 /* allow 6 seconds slop on checking peak vs. file times because of various
299 if (stat_file.st_mtime > statbuf.st_mtime && (stat_file.st_mtime - statbuf.st_mtime > 6)) {
300 _peaks_built = false;
304 _peak_byte_max = statbuf.st_size;
310 if (!empty() && !_peaks_built && _build_missing_peakfiles && _build_peakfiles) {
311 build_peaks_from_scratch ();
318 AudioSource::read (Sample *dst, samplepos_t start, samplecnt_t cnt, int /*channel*/) const
322 Glib::Threads::Mutex::Lock lm (_lock);
323 return read_unlocked (dst, start, cnt);
327 AudioSource::write (Sample *dst, samplecnt_t cnt)
329 Glib::Threads::Mutex::Lock lm (_lock);
330 /* any write makes the file not removable */
331 _flags = Flag (_flags & ~Removable);
332 return write_unlocked (dst, cnt);
336 AudioSource::read_peaks (PeakData *peaks, samplecnt_t npeaks, samplepos_t start, samplecnt_t cnt, double samples_per_visual_peak) const
338 return read_peaks_with_fpp (peaks, npeaks, start, cnt, samples_per_visual_peak, _FPP);
341 /** @param peaks Buffer to write peak data.
342 * @param npeaks Number of peaks to write.
346 AudioSource::read_peaks_with_fpp (PeakData *peaks, samplecnt_t npeaks, samplepos_t start, samplecnt_t cnt,
347 double samples_per_visual_peak, samplecnt_t samples_per_file_peak) const
349 Glib::Threads::Mutex::Lock lm (_lock);
351 double expected_peaks;
352 PeakData::PeakDatum xmax;
353 PeakData::PeakDatum xmin;
355 #ifdef PLATFORM_WINDOWS
356 SYSTEM_INFO system_info;
357 GetSystemInfo (&system_info);
358 const int bufsize = system_info.dwAllocationGranularity;;
360 const int bufsize = sysconf(_SC_PAGESIZE);
362 samplecnt_t read_npeaks = npeaks;
363 samplecnt_t zero_fill = 0;
367 expected_peaks = (cnt / (double) samples_per_file_peak);
368 if (g_stat (_peakpath.c_str(), &statbuf) != 0) {
369 error << string_compose (_("Cannot open peakfile @ %1 for size check (%2)"), _peakpath, strerror (errno)) << endmsg;
373 if (!_captured_for.empty()) {
375 /* _captured_for is only set after a capture pass is
376 * complete. so we know that capturing is finished for this
377 * file, and now we can check actual size of the peakfile is at
378 * least large enough for all the data in the audio file. if it
379 * is too short, assume that a crash or other error truncated
380 * it, and rebuild it from scratch.
382 * XXX this may not work for destructive recording, but we
383 * might decided to get rid of that anyway.
387 const off_t expected_file_size = (_length / (double) samples_per_file_peak) * sizeof (PeakData);
389 if (statbuf.st_size < expected_file_size) {
390 warning << string_compose (_("peak file %1 is truncated from %2 to %3"), _peakpath, expected_file_size, statbuf.st_size) << endmsg;
391 lm.release(); // build_peaks_from_scratch() takes _lock
392 const_cast<AudioSource*>(this)->build_peaks_from_scratch ();
394 if (g_stat (_peakpath.c_str(), &statbuf) != 0) {
395 error << string_compose (_("Cannot open peakfile @ %1 for size check (%2) after rebuild"), _peakpath, strerror (errno)) << endmsg;
397 if (statbuf.st_size < expected_file_size) {
398 fatal << "peak file is still truncated after rebuild" << endmsg;
399 abort (); /*NOTREACHED*/
404 ScopedFileDescriptor sfd (g_open (_peakpath.c_str(), O_RDONLY, 0444));
407 error << string_compose (_("Cannot open peakfile @ %1 for reading (%2)"), _peakpath, strerror (errno)) << endmsg;
411 scale = npeaks/expected_peaks;
414 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"
415 , npeaks, start, cnt, _length, samples_per_visual_peak, expected_peaks, scale, peaks));
417 /* fix for near-end-of-file conditions */
419 if (cnt + start > _length) {
420 // cerr << "too close to end @ " << _length << " given " << start << " + " << cnt << " (" << _length - start << ")" << endl;
421 cnt = std::max ((samplecnt_t)0, _length - start);
422 read_npeaks = min ((samplecnt_t) floor (cnt / samples_per_visual_peak), npeaks);
423 zero_fill = npeaks - read_npeaks;
424 expected_peaks = (cnt / (double) samples_per_file_peak);
425 scale = npeaks/expected_peaks;
430 // cerr << "actual npeaks = " << read_npeaks << " zf = " << zero_fill << endl;
434 DEBUG_TRACE (DEBUG::Peaks, "RAW DATA\n");
436 /* no scaling at all, just get the sample data and duplicate it for
437 both max and min peak values.
440 boost::scoped_array<Sample> raw_staging(new Sample[cnt]);
442 if (read_unlocked (raw_staging.get(), start, cnt) != cnt) {
443 error << _("cannot read sample data for unscaled peak computation") << endmsg;
447 for (samplecnt_t i = 0; i < npeaks; ++i) {
448 peaks[i].max = raw_staging[i];
449 peaks[i].min = raw_staging[i];
456 off_t first_peak_byte = (start / samples_per_file_peak) * sizeof (PeakData);
457 size_t bytes_to_read = sizeof (PeakData) * read_npeaks;
458 /* open, read, close */
460 DEBUG_TRACE (DEBUG::Peaks, "DIRECT PEAKS\n");
462 off_t map_off = first_peak_byte;
463 off_t read_map_off = map_off & ~(bufsize - 1);
464 off_t map_delta = map_off - read_map_off;
465 size_t map_length = bytes_to_read + map_delta;
467 if (_first_run || (_last_scale != samples_per_visual_peak) || (_last_map_off != map_off) || (_last_raw_map_length < bytes_to_read)) {
468 peak_cache.reset (new PeakData[npeaks]);
470 #ifdef PLATFORM_WINDOWS
471 HANDLE file_handle = (HANDLE) _get_osfhandle(int(sfd));
476 map_handle = CreateFileMapping(file_handle, NULL, PAGE_READONLY, 0, 0, NULL);
477 if (map_handle == NULL) {
478 error << string_compose (_("map failed - could not create file mapping for peakfile %1."), _peakpath) << endmsg;
482 view_handle = MapViewOfFile(map_handle, FILE_MAP_READ, 0, read_map_off, map_length);
483 if (view_handle == NULL) {
484 error << string_compose (_("map failed - could not map peakfile %1."), _peakpath) << endmsg;
488 addr = (char*) view_handle;
490 memcpy ((void*)peak_cache.get(), (void*)(addr + map_delta), bytes_to_read);
492 err_flag = UnmapViewOfFile (view_handle);
493 err_flag = CloseHandle(map_handle);
495 error << string_compose (_("unmap failed - could not unmap peakfile %1."), _peakpath) << endmsg;
499 addr = (char*) mmap (0, map_length, PROT_READ, MAP_PRIVATE, sfd, read_map_off);
500 if (addr == MAP_FAILED) {
501 error << string_compose (_("map failed - could not mmap peakfile %1."), _peakpath) << endmsg;
505 memcpy ((void*)peak_cache.get(), (void*)(addr + map_delta), bytes_to_read);
506 munmap (addr, map_length);
509 memset (&peak_cache[read_npeaks], 0, sizeof (PeakData) * zero_fill);
513 _last_scale = samples_per_visual_peak;
514 _last_map_off = map_off;
515 _last_raw_map_length = bytes_to_read;
518 memcpy ((void*)peaks, (void*)peak_cache.get(), npeaks * sizeof(PeakData));
525 DEBUG_TRACE (DEBUG::Peaks, "DOWNSAMPLE\n");
529 * - more samples-per-peak (lower resolution) than the peakfile, or to put it another way,
530 * - less peaks than the peakfile holds for the same range
532 * So, read a block into a staging area, and then downsample from there.
534 * to avoid confusion, I'll refer to the requested peaks as visual_peaks and the peakfile peaks as stored_peaks
537 const samplecnt_t chunksize = (samplecnt_t) expected_peaks; // we read all the peaks we need in one hit.
539 /* compute the rounded up sample position */
541 samplepos_t current_stored_peak = (samplepos_t) ceil (start / (double) samples_per_file_peak);
542 samplepos_t next_visual_peak = (samplepos_t) ceil (start / samples_per_visual_peak);
543 double next_visual_peak_sample = next_visual_peak * samples_per_visual_peak;
544 samplepos_t stored_peak_before_next_visual_peak = (samplepos_t) next_visual_peak_sample / samples_per_file_peak;
545 samplecnt_t nvisual_peaks = 0;
548 /* handle the case where the initial visual peak is on a pixel boundary */
550 current_stored_peak = min (current_stored_peak, stored_peak_before_next_visual_peak);
552 /* open ... close during out: handling */
554 off_t map_off = (uint32_t) (ceil (start / (double) samples_per_file_peak)) * sizeof(PeakData);
555 off_t read_map_off = map_off & ~(bufsize - 1);
556 off_t map_delta = map_off - read_map_off;
557 size_t raw_map_length = chunksize * sizeof(PeakData);
558 size_t map_length = (chunksize * sizeof(PeakData)) + map_delta;
560 if (_first_run || (_last_scale != samples_per_visual_peak) || (_last_map_off != map_off) || (_last_raw_map_length < raw_map_length)) {
561 peak_cache.reset (new PeakData[npeaks]);
562 boost::scoped_array<PeakData> staging (new PeakData[chunksize]);
565 #ifdef PLATFORM_WINDOWS
566 HANDLE file_handle = (HANDLE) _get_osfhandle(int(sfd));
571 map_handle = CreateFileMapping(file_handle, NULL, PAGE_READONLY, 0, 0, NULL);
572 if (map_handle == NULL) {
573 error << string_compose (_("map failed - could not create file mapping for peakfile %1."), _peakpath) << endmsg;
577 view_handle = MapViewOfFile(map_handle, FILE_MAP_READ, 0, read_map_off, map_length);
578 if (view_handle == NULL) {
579 error << string_compose (_("map failed - could not map peakfile %1."), _peakpath) << endmsg;
583 addr = (char *) view_handle;
585 memcpy ((void*)staging.get(), (void*)(addr + map_delta), raw_map_length);
587 err_flag = UnmapViewOfFile (view_handle);
588 err_flag = CloseHandle(map_handle);
590 error << string_compose (_("unmap failed - could not unmap peakfile %1."), _peakpath) << endmsg;
594 addr = (char*) mmap (0, map_length, PROT_READ, MAP_PRIVATE, sfd, read_map_off);
595 if (addr == MAP_FAILED) {
596 error << string_compose (_("map failed - could not mmap peakfile %1."), _peakpath) << endmsg;
600 memcpy ((void*)staging.get(), (void*)(addr + map_delta), raw_map_length);
601 munmap (addr, map_length);
603 while (nvisual_peaks < read_npeaks) {
608 while ((current_stored_peak <= stored_peak_before_next_visual_peak) && (i < chunksize)) {
610 xmax = max (xmax, staging[i].max);
611 xmin = min (xmin, staging[i].min);
613 ++current_stored_peak;
616 peak_cache[nvisual_peaks].max = xmax;
617 peak_cache[nvisual_peaks].min = xmin;
619 next_visual_peak_sample = min ((double) start + cnt, (next_visual_peak_sample + samples_per_visual_peak));
620 stored_peak_before_next_visual_peak = (uint32_t) next_visual_peak_sample / samples_per_file_peak;
624 cerr << "Zero fill end of peaks (@ " << read_npeaks << " with " << zero_fill << ")" << endl;
625 memset (&peak_cache[read_npeaks], 0, sizeof (PeakData) * zero_fill);
629 _last_scale = samples_per_visual_peak;
630 _last_map_off = map_off;
631 _last_raw_map_length = raw_map_length;
634 memcpy ((void*)peaks, (void*)peak_cache.get(), npeaks * sizeof(PeakData));
637 DEBUG_TRACE (DEBUG::Peaks, "UPSAMPLE\n");
641 * - less samples-per-peak (more resolution)
642 * - more peaks than stored in the Peakfile
644 * So, fetch data from the raw source, and generate peak
648 samplecnt_t samples_read = 0;
649 samplepos_t current_sample = start;
651 samplecnt_t nvisual_peaks = 0;
652 samplecnt_t chunksize = (samplecnt_t) min (cnt, (samplecnt_t) 4096);
653 boost::scoped_array<Sample> raw_staging(new Sample[chunksize]);
655 double pixel_pos = start / samples_per_visual_peak;
656 double next_pixel_pos = 1.0 + floor (pixel_pos);
657 double pixels_per_sample = 1.0 / samples_per_visual_peak;
662 while (nvisual_peaks < read_npeaks) {
664 if (i == samples_read) {
666 to_read = min (chunksize, (samplecnt_t)(_length - current_sample));
668 if (current_sample >= _length) {
670 /* hmm, error condition - we've reached the end of the file
671 * without generating all the peak data. cook up a zero-filled
672 * data buffer and then use it. this is simpler than
673 * adjusting zero_fill and read_npeaks and then breaking out of
677 memset (raw_staging.get(), 0, sizeof (Sample) * chunksize);
681 to_read = min (chunksize, (_length - current_sample));
684 if ((samples_read = read_unlocked (raw_staging.get(), current_sample, to_read)) == 0) {
685 error << string_compose(_("AudioSource[%1]: peak read - cannot read %2 samples at offset %3 of %4 (%5)"),
686 _name, to_read, current_sample, _length, strerror (errno))
695 xmax = max (xmax, raw_staging[i]);
696 xmin = min (xmin, raw_staging[i]);
699 pixel_pos += pixels_per_sample;
701 if (pixel_pos >= next_pixel_pos) {
703 peaks[nvisual_peaks].max = xmax;
704 peaks[nvisual_peaks].min = xmin;
709 next_pixel_pos = ceil (pixel_pos + 0.5);
714 memset (&peaks[read_npeaks], 0, sizeof (PeakData) * zero_fill);
718 DEBUG_TRACE (DEBUG::Peaks, "READPEAKS DONE\n");
723 AudioSource::build_peaks_from_scratch ()
725 const samplecnt_t bufsize = 65536; // 256kB per disk read for mono data is about ideal
727 DEBUG_TRACE (DEBUG::Peaks, "Building peaks from scratch\n");
732 /* hold lock while building peaks */
734 Glib::Threads::Mutex::Lock lp (_lock);
736 if (prepare_for_peakfile_writes ()) {
740 samplecnt_t current_sample = 0;
741 samplecnt_t cnt = _length;
743 _peaks_built = false;
744 boost::scoped_array<Sample> buf(new Sample[bufsize]);
748 samplecnt_t samples_to_read = min (bufsize, cnt);
749 samplecnt_t samples_read;
751 if ((samples_read = read_unlocked (buf.get(), current_sample, samples_to_read)) != samples_to_read) {
752 error << string_compose(_("%1: could not write read raw data for peak computation (%2)"), _name, strerror (errno)) << endmsg;
753 done_with_peakfile_writes (false);
757 lp.release(); // allow butler to refill buffers
759 if (_session.deletion_in_progress() || _session.peaks_cleanup_in_progres()) {
760 cerr << "peak file creation interrupted: " << _name << endmsg;
762 done_with_peakfile_writes (false);
766 if (compute_and_write_peaks (buf.get(), current_sample, samples_read, true, false, _FPP)) {
770 current_sample += samples_read;
781 done_with_peakfile_writes ((cnt == 0));
789 DEBUG_TRACE (DEBUG::Peaks, string_compose("Could not write peak data, attempting to remove peakfile %1\n", _peakpath));
790 ::g_unlink (_peakpath.c_str());
797 AudioSource::close_peakfile ()
799 Glib::Threads::Mutex::Lock lp (_lock);
800 if (_peakfile_fd >= 0) {
801 close (_peakfile_fd);
804 if (!_peakpath.empty()) {
805 ::g_unlink (_peakpath.c_str());
807 _peaks_built = false;
812 AudioSource::prepare_for_peakfile_writes ()
814 if (_session.deletion_in_progress() || _session.peaks_cleanup_in_progres()) {
818 if ((_peakfile_fd = g_open (_peakpath.c_str(), O_CREAT|O_RDWR, 0664)) < 0) {
819 error << string_compose(_("AudioSource: cannot open _peakpath (c) \"%1\" (%2)"), _peakpath, strerror (errno)) << endmsg;
826 AudioSource::done_with_peakfile_writes (bool done)
828 if (_session.deletion_in_progress() || _session.peaks_cleanup_in_progres()) {
830 close (_peakfile_fd);
836 if (peak_leftover_cnt) {
837 compute_and_write_peaks (0, 0, 0, true, false, _FPP);
841 Glib::Threads::Mutex::Lock lm (_peaks_ready_lock);
843 PeaksReady (); /* EMIT SIGNAL */
846 close (_peakfile_fd);
850 /** @param first_sample Offset from the source start of the first sample to
851 * process. _lock MUST be held by caller.
854 AudioSource::compute_and_write_peaks (Sample* buf, samplecnt_t first_sample, samplecnt_t cnt,
855 bool force, bool intermediate_peaks_ready)
857 return compute_and_write_peaks (buf, first_sample, cnt, force, intermediate_peaks_ready, _FPP);
861 AudioSource::compute_and_write_peaks (Sample* buf, samplecnt_t first_sample, samplecnt_t cnt,
862 bool force, bool intermediate_peaks_ready, samplecnt_t fpp)
865 uint32_t peaks_computed;
866 samplepos_t current_sample;
867 samplecnt_t samples_done;
868 const size_t blocksize = (128 * 1024);
869 off_t first_peak_byte;
870 boost::scoped_array<Sample> buf2;
872 if (_peakfile_fd < 0) {
873 if (prepare_for_peakfile_writes ()) {
879 if (peak_leftover_cnt) {
881 if (first_sample != peak_leftover_sample + peak_leftover_cnt) {
883 /* uh-oh, ::seek() since the last ::compute_and_write_peaks(),
884 and we have leftovers. flush a single peak (since the leftovers
885 never represent more than that, and restart.
890 x.min = peak_leftovers[0];
891 x.max = peak_leftovers[0];
893 off_t byte = (peak_leftover_sample / fpp) * sizeof (PeakData);
895 off_t offset = lseek (_peakfile_fd, byte, SEEK_SET);
897 if (offset != byte) {
898 error << string_compose(_("%1: could not seek in peak file data (%2)"), _name, strerror (errno)) << endmsg;
902 if (::write (_peakfile_fd, &x, sizeof (PeakData)) != sizeof (PeakData)) {
903 error << string_compose(_("%1: could not write peak file data (%2)"), _name, strerror (errno)) << endmsg;
907 _peak_byte_max = max (_peak_byte_max, (off_t) (byte + sizeof(PeakData)));
910 Glib::Threads::Mutex::Lock lm (_peaks_ready_lock);
911 PeakRangeReady (peak_leftover_sample, peak_leftover_cnt); /* EMIT SIGNAL */
912 if (intermediate_peaks_ready) {
913 PeaksReady (); /* EMIT SIGNAL */
917 /* left overs are done */
919 peak_leftover_cnt = 0;
923 /* else ... had leftovers, but they immediately preceed the new data, so just
924 merge them and compute.
927 /* make a new contiguous buffer containing leftovers and the new stuff */
929 to_do = cnt + peak_leftover_cnt;
930 buf2.reset(new Sample[to_do]);
933 memcpy (buf2.get(), peak_leftovers, peak_leftover_cnt * sizeof (Sample));
936 if (buf && cnt > 0) {
937 memcpy (buf2.get()+peak_leftover_cnt, buf, cnt * sizeof (Sample));
940 /* no more leftovers */
941 peak_leftover_cnt = 0;
943 /* use the temporary buffer */
946 /* make sure that when we write into the peakfile, we startup where we left off */
948 first_sample = peak_leftover_sample;
954 boost::scoped_array<PeakData> peakbuf(new PeakData[(to_do/fpp)+1]);
956 current_sample = first_sample;
961 /* if some samples were passed in (i.e. we're not flushing leftovers)
962 and there are less than fpp to do, save them till
966 if (force && (to_do < fpp)) {
967 /* keep the left overs around for next time */
969 if (peak_leftover_size < to_do) {
970 delete [] peak_leftovers;
971 peak_leftovers = new Sample[to_do];
972 peak_leftover_size = to_do;
974 memcpy (peak_leftovers, buf, to_do * sizeof (Sample));
975 peak_leftover_cnt = to_do;
976 peak_leftover_sample = current_sample;
983 samplecnt_t this_time = min (fpp, to_do);
985 peakbuf[peaks_computed].max = buf[0];
986 peakbuf[peaks_computed].min = buf[0];
988 ARDOUR::find_peaks (buf+1, this_time-1, &peakbuf[peaks_computed].min, &peakbuf[peaks_computed].max);
993 samples_done += this_time;
994 current_sample += this_time;
997 first_peak_byte = (first_sample / fpp) * sizeof (PeakData);
999 if (can_truncate_peaks()) {
1001 /* on some filesystems (ext3, at least) this helps to reduce fragmentation of
1002 the peakfiles. its not guaranteed to do so, and even on ext3 (as of december 2006)
1003 it does not cause single-extent allocation even for peakfiles of
1004 less than BLOCKSIZE bytes. only call ftruncate if we'll make the file larger.
1007 off_t endpos = lseek (_peakfile_fd, 0, SEEK_END);
1008 off_t target_length = blocksize * ((first_peak_byte + blocksize + 1) / blocksize);
1010 if (endpos < target_length) {
1011 DEBUG_TRACE(DEBUG::Peaks, string_compose ("Truncating Peakfile %1\n", _peakpath));
1012 if (ftruncate (_peakfile_fd, target_length)) {
1013 /* error doesn't actually matter so continue on without testing */
1019 off_t offset = lseek(_peakfile_fd, first_peak_byte, SEEK_SET);
1021 if (offset != first_peak_byte) {
1022 error << string_compose(_("%1: could not seek in peak file data (%2)"), _name, strerror (errno)) << endmsg;
1026 ssize_t bytes_to_write = sizeof (PeakData) * peaks_computed;
1028 ssize_t bytes_written = ::write (_peakfile_fd, peakbuf.get(), bytes_to_write);
1030 if (bytes_written != bytes_to_write) {
1031 error << string_compose(_("%1: could not write peak file data (%2)"), _name, strerror (errno)) << endmsg;
1035 _peak_byte_max = max (_peak_byte_max, (off_t) (first_peak_byte + bytes_to_write));
1038 Glib::Threads::Mutex::Lock lm (_peaks_ready_lock);
1039 PeakRangeReady (first_sample, samples_done); /* EMIT SIGNAL */
1040 if (intermediate_peaks_ready) {
1041 PeaksReady (); /* EMIT SIGNAL */
1049 AudioSource::truncate_peakfile ()
1051 if (_peakfile_fd < 0) {
1052 error << string_compose (_("programming error: %1"), "AudioSource::truncate_peakfile() called without open peakfile descriptor")
1057 /* truncate the peakfile down to its natural length if necessary */
1059 off_t end = lseek (_peakfile_fd, 0, SEEK_END);
1061 if (end > _peak_byte_max) {
1062 DEBUG_TRACE(DEBUG::Peaks, string_compose ("Truncating Peakfile %1\n", _peakpath));
1063 if (ftruncate (_peakfile_fd, _peak_byte_max)) {
1064 error << string_compose (_("could not truncate peakfile %1 to %2 (error: %3)"),
1065 _peakpath, _peak_byte_max, errno) << endmsg;
1071 AudioSource::available_peaks (double zoom_factor) const
1073 if (zoom_factor < _FPP) {
1074 return length(_natural_position); // peak data will come from the audio file
1077 /* peak data comes from peakfile, but the filesize might not represent
1078 the valid data due to ftruncate optimizations, so use _peak_byte_max state.
1079 XXX - there might be some atomicity issues here, we should probably add a lock,
1080 but _peak_byte_max only monotonically increases after initialization.
1083 off_t end = _peak_byte_max;
1085 return (end/sizeof(PeakData)) * _FPP;
1089 AudioSource::mark_streaming_write_completed (const Lock& lock)
1091 Glib::Threads::Mutex::Lock lm (_peaks_ready_lock);
1094 PeaksReady (); /* EMIT SIGNAL */
1099 AudioSource::allocate_working_buffers (samplecnt_t framerate)
1101 Glib::Threads::Mutex::Lock lm (_level_buffer_lock);
1104 /* Note: we don't need any buffers allocated until
1105 a level 1 audiosource is created, at which
1106 time we'll call ::ensure_buffers_for_level()
1107 with the right value and do the right thing.
1110 if (!_mixdown_buffers.empty()) {
1111 ensure_buffers_for_level_locked ( _mixdown_buffers.size(), framerate);
1116 AudioSource::ensure_buffers_for_level (uint32_t level, samplecnt_t sample_rate)
1118 Glib::Threads::Mutex::Lock lm (_level_buffer_lock);
1119 ensure_buffers_for_level_locked (level, sample_rate);
1123 AudioSource::ensure_buffers_for_level_locked (uint32_t level, samplecnt_t sample_rate)
1125 samplecnt_t nframes = PlaybackBuffer<Sample>::power_of_two_size ((samplecnt_t) floor (Config->get_audio_playback_buffer_seconds() * sample_rate));
1127 /* this may be called because either "level" or "sample_rate" have
1128 * changed. and it may be called with "level" smaller than the current
1129 * number of buffers, because a new compound region has been created at
1130 * a more shallow level than the deepest one we currently have.
1133 uint32_t limit = max ((size_t) level, _mixdown_buffers.size());
1135 _mixdown_buffers.clear ();
1136 _gain_buffers.clear ();
1138 for (uint32_t n = 0; n < limit; ++n) {
1139 _mixdown_buffers.push_back (boost::shared_array<Sample> (new Sample[nframes]));
1140 _gain_buffers.push_back (boost::shared_array<gain_t> (new gain_t[nframes]));