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"
59 #include "ardour/session.h"
63 #include "ardour/debug.h"
66 using namespace ARDOUR;
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;
74 /** true if we want peakfiles (e.g. if we are displaying a GUI) */
75 bool AudioSource::_build_peakfiles = false;
79 AudioSource::AudioSource (Session& s, const string& name)
80 : Source (s, DataType::AUDIO, name)
83 , _peaks_built (false)
85 , peak_leftover_cnt (0)
86 , peak_leftover_size (0)
91 , _last_raw_map_length (0)
95 AudioSource::AudioSource (Session& s, const XMLNode& node)
99 , _peaks_built (false)
101 , peak_leftover_cnt (0)
102 , peak_leftover_size (0)
107 , _last_raw_map_length (0)
109 if (set_state (node, Stateful::loading_state_version)) {
110 throw failed_constructor();
114 AudioSource::~AudioSource ()
116 /* shouldn't happen but make sure we don't leak file descriptors anyway */
118 if (peak_leftover_cnt) {
119 cerr << "AudioSource destroyed with leftover peak data pending" << endl;
122 if ((-1) != _peakfile_fd) {
123 close (_peakfile_fd);
127 delete [] peak_leftovers;
131 AudioSource::get_state ()
133 XMLNode& node (Source::get_state());
135 if (_captured_for.length()) {
136 node.add_property ("captured-for", _captured_for);
143 AudioSource::set_state (const XMLNode& node, int /*version*/)
145 const XMLProperty* prop;
147 if ((prop = node.property ("captured-for")) != 0) {
148 _captured_for = prop->value();
155 AudioSource::empty () const
161 AudioSource::length (framepos_t /*pos*/) const
167 AudioSource::update_length (framecnt_t len)
175 /***********************************************************************
177 ***********************************************************************/
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.
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.
189 AudioSource::peaks_ready (boost::function<void()> doThisWhenReady, ScopedConnection** connect_here_if_not, EventLoop* event_loop) const
192 Glib::Threads::Mutex::Lock lm (_peaks_ready_lock);
194 if (!(ret = _peaks_built)) {
195 *connect_here_if_not = new ScopedConnection;
196 PeaksReady.connect (**connect_here_if_not, MISSING_INVALIDATOR, doThisWhenReady, event_loop);
203 AudioSource::touch_peakfile ()
207 if (g_stat (_peakpath.c_str(), &statbuf) != 0 || statbuf.st_size == 0) {
213 tbuf.actime = statbuf.st_atime;
214 tbuf.modtime = time ((time_t*) 0);
216 g_utime (_peakpath.c_str(), &tbuf);
220 AudioSource::rename_peakfile (string newpath)
222 /* caller must hold _lock */
224 string oldpath = _peakpath;
226 if (Glib::file_test (oldpath, Glib::FILE_TEST_EXISTS)) {
227 if (g_rename (oldpath.c_str(), newpath.c_str()) != 0) {
228 error << string_compose (_("cannot rename peakfile for %1 from %2 to %3 (%4)"), _name, oldpath, newpath, strerror (errno)) << endmsg;
239 AudioSource::initialize_peakfile (const string& audio_path)
243 _peakpath = construct_peak_filepath (audio_path);
245 DEBUG_TRACE(DEBUG::Peaks, string_compose ("Initialize Peakfile %1 for Audio file %2\n", _peakpath, audio_path));
247 if (g_stat (_peakpath.c_str(), &statbuf)) {
248 if (errno != ENOENT) {
249 /* it exists in the peaks dir, but there is some kind of error */
251 error << string_compose(_("AudioSource: cannot stat peakfile \"%1\""), _peakpath) << endmsg;
255 DEBUG_TRACE(DEBUG::Peaks, string_compose("Peakfile %1 does not exist\n", _peakpath));
257 _peaks_built = false;
261 /* we found it in the peaks dir, so check it out */
263 if (statbuf.st_size == 0 || (statbuf.st_size < (off_t) ((length(_timeline_position) / _FPP) * sizeof (PeakData)))) {
264 DEBUG_TRACE(DEBUG::Peaks, string_compose("Peakfile %1 is empty\n", _peakpath));
265 _peaks_built = false;
267 // Check if the audio file has changed since the peakfile was built.
269 int err = g_stat (audio_path.c_str(), &stat_file);
273 /* no audio path - nested source or we can't
274 read it or ... whatever, use the peakfile as-is.
276 DEBUG_TRACE(DEBUG::Peaks, string_compose("Error when calling stat on Peakfile %1\n", _peakpath));
279 _peak_byte_max = statbuf.st_size;
283 /* allow 6 seconds slop on checking peak vs. file times because of various
287 if (stat_file.st_mtime > statbuf.st_mtime && (stat_file.st_mtime - statbuf.st_mtime > 6)) {
288 _peaks_built = false;
292 _peak_byte_max = statbuf.st_size;
298 if (!empty() && !_peaks_built && _build_missing_peakfiles && _build_peakfiles) {
299 build_peaks_from_scratch ();
306 AudioSource::read (Sample *dst, framepos_t start, framecnt_t cnt, int /*channel*/) const
310 Glib::Threads::Mutex::Lock lm (_lock);
311 return read_unlocked (dst, start, cnt);
315 AudioSource::write (Sample *dst, framecnt_t cnt)
317 Glib::Threads::Mutex::Lock lm (_lock);
318 /* any write makes the file not removable */
319 _flags = Flag (_flags & ~Removable);
320 return write_unlocked (dst, cnt);
324 AudioSource::read_peaks (PeakData *peaks, framecnt_t npeaks, framepos_t start, framecnt_t cnt, double samples_per_visual_peak) const
326 return read_peaks_with_fpp (peaks, npeaks, start, cnt, samples_per_visual_peak, _FPP);
329 /** @param peaks Buffer to write peak data.
330 * @param npeaks Number of peaks to write.
334 AudioSource::read_peaks_with_fpp (PeakData *peaks, framecnt_t npeaks, framepos_t start, framecnt_t cnt,
335 double samples_per_visual_peak, framecnt_t samples_per_file_peak) const
337 Glib::Threads::Mutex::Lock lm (_lock);
339 double expected_peaks;
340 PeakData::PeakDatum xmax;
341 PeakData::PeakDatum xmin;
343 #ifdef PLATFORM_WINDOWS
344 SYSTEM_INFO system_info;
345 GetSystemInfo (&system_info);
346 const int bufsize = system_info.dwAllocationGranularity;;
348 const int bufsize = sysconf(_SC_PAGESIZE);
350 framecnt_t read_npeaks = npeaks;
351 framecnt_t zero_fill = 0;
355 expected_peaks = (cnt / (double) samples_per_file_peak);
356 if (g_stat (_peakpath.c_str(), &statbuf) != 0) {
357 error << string_compose (_("Cannot open peakfile @ %1 for size check (%2)"), _peakpath, strerror (errno)) << endmsg;
361 if (!_captured_for.empty()) {
363 /* _captured_for is only set after a capture pass is
364 * complete. so we know that capturing is finished for this
365 * file, and now we can check actual size of the peakfile is at
366 * least large enough for all the data in the audio file. if it
367 * is too short, assume that a crash or other error truncated
368 * it, and rebuild it from scratch.
370 * XXX this may not work for destructive recording, but we
371 * might decided to get rid of that anyway.
375 const off_t expected_file_size = (_length / (double) samples_per_file_peak) * sizeof (PeakData);
377 if (statbuf.st_size < expected_file_size) {
378 warning << string_compose (_("peak file %1 is truncated from %2 to %3"), _peakpath, expected_file_size, statbuf.st_size) << endmsg;
379 const_cast<AudioSource*>(this)->build_peaks_from_scratch ();
380 if (g_stat (_peakpath.c_str(), &statbuf) != 0) {
381 error << string_compose (_("Cannot open peakfile @ %1 for size check (%2) after rebuild"), _peakpath, strerror (errno)) << endmsg;
383 if (statbuf.st_size < expected_file_size) {
384 fatal << "peak file is still truncated after rebuild" << endmsg;
390 ScopedFileDescriptor sfd (g_open (_peakpath.c_str(), O_RDONLY, 0444));
393 error << string_compose (_("Cannot open peakfile @ %1 for reading (%2)"), _peakpath, strerror (errno)) << endmsg;
397 scale = npeaks/expected_peaks;
400 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"
401 , npeaks, start, cnt, _length, samples_per_visual_peak, expected_peaks, scale, peaks));
403 /* fix for near-end-of-file conditions */
405 if (cnt > _length - start) {
406 // cerr << "too close to end @ " << _length << " given " << start << " + " << cnt << " (" << _length - start << ")" << endl;
407 cnt = _length - start;
408 read_npeaks = min ((framecnt_t) floor (cnt / samples_per_visual_peak), npeaks);
409 zero_fill = npeaks - read_npeaks;
410 expected_peaks = (cnt / (double) samples_per_file_peak);
411 scale = npeaks/expected_peaks;
414 // cerr << "actual npeaks = " << read_npeaks << " zf = " << zero_fill << endl;
418 DEBUG_TRACE (DEBUG::Peaks, "RAW DATA\n");
420 /* no scaling at all, just get the sample data and duplicate it for
421 both max and min peak values.
424 boost::scoped_array<Sample> raw_staging(new Sample[cnt]);
426 if (read_unlocked (raw_staging.get(), start, cnt) != cnt) {
427 error << _("cannot read sample data for unscaled peak computation") << endmsg;
431 for (framecnt_t i = 0; i < npeaks; ++i) {
432 peaks[i].max = raw_staging[i];
433 peaks[i].min = raw_staging[i];
440 off_t first_peak_byte = (start / samples_per_file_peak) * sizeof (PeakData);
441 size_t bytes_to_read = sizeof (PeakData) * read_npeaks;
442 /* open, read, close */
444 DEBUG_TRACE (DEBUG::Peaks, "DIRECT PEAKS\n");
446 off_t map_off = first_peak_byte;
447 off_t read_map_off = map_off & ~(bufsize - 1);
448 off_t map_delta = map_off - read_map_off;
449 size_t map_length = bytes_to_read + map_delta;
451 if (_first_run || (_last_scale != samples_per_visual_peak) || (_last_map_off != map_off) || (_last_raw_map_length < bytes_to_read)) {
452 peak_cache.reset (new PeakData[npeaks]);
454 #ifdef PLATFORM_WINDOWS
455 HANDLE file_handle = (HANDLE) _get_osfhandle(int(sfd));
460 map_handle = CreateFileMapping(file_handle, NULL, PAGE_READONLY, 0, 0, NULL);
461 if (map_handle == NULL) {
462 error << string_compose (_("map failed - could not create file mapping for peakfile %1."), _peakpath) << endmsg;
466 view_handle = MapViewOfFile(map_handle, FILE_MAP_READ, 0, read_map_off, map_length);
467 if (view_handle == NULL) {
468 error << string_compose (_("map failed - could not map peakfile %1."), _peakpath) << endmsg;
472 addr = (char*) view_handle;
474 memcpy ((void*)peak_cache.get(), (void*)(addr + map_delta), bytes_to_read);
476 err_flag = UnmapViewOfFile (view_handle);
477 err_flag = CloseHandle(map_handle);
479 error << string_compose (_("unmap failed - could not unmap peakfile %1."), _peakpath) << endmsg;
483 addr = (char*) mmap (0, map_length, PROT_READ, MAP_PRIVATE, sfd, read_map_off);
484 if (addr == MAP_FAILED) {
485 error << string_compose (_("map failed - could not mmap peakfile %1."), _peakpath) << endmsg;
489 memcpy ((void*)peak_cache.get(), (void*)(addr + map_delta), bytes_to_read);
490 munmap (addr, map_length);
493 memset (&peak_cache[read_npeaks], 0, sizeof (PeakData) * zero_fill);
497 _last_scale = samples_per_visual_peak;
498 _last_map_off = map_off;
499 _last_raw_map_length = bytes_to_read;
502 memcpy ((void*)peaks, (void*)peak_cache.get(), npeaks * sizeof(PeakData));
509 DEBUG_TRACE (DEBUG::Peaks, "DOWNSAMPLE\n");
513 - more frames-per-peak (lower resolution) than the peakfile, or to put it another way,
514 - less peaks than the peakfile holds for the same range
516 So, read a block into a staging area, and then downsample from there.
518 to avoid confusion, I'll refer to the requested peaks as visual_peaks and the peakfile peaks as stored_peaks
521 const framecnt_t chunksize = (framecnt_t) expected_peaks; // we read all the peaks we need in one hit.
523 /* compute the rounded up frame position */
525 framepos_t current_stored_peak = (framepos_t) ceil (start / (double) samples_per_file_peak);
526 framepos_t next_visual_peak = (framepos_t) ceil (start / samples_per_visual_peak);
527 double next_visual_peak_frame = next_visual_peak * samples_per_visual_peak;
528 framepos_t stored_peak_before_next_visual_peak = (framepos_t) next_visual_peak_frame / samples_per_file_peak;
529 framecnt_t nvisual_peaks = 0;
532 /* handle the case where the initial visual peak is on a pixel boundary */
534 current_stored_peak = min (current_stored_peak, stored_peak_before_next_visual_peak);
536 /* open ... close during out: handling */
538 off_t map_off = (uint32_t) (ceil (start / (double) samples_per_file_peak)) * sizeof(PeakData);
539 off_t read_map_off = map_off & ~(bufsize - 1);
540 off_t map_delta = map_off - read_map_off;
541 size_t raw_map_length = chunksize * sizeof(PeakData);
542 size_t map_length = (chunksize * sizeof(PeakData)) + map_delta;
544 if (_first_run || (_last_scale != samples_per_visual_peak) || (_last_map_off != map_off) || (_last_raw_map_length < raw_map_length)) {
545 peak_cache.reset (new PeakData[npeaks]);
546 boost::scoped_array<PeakData> staging (new PeakData[chunksize]);
549 #ifdef PLATFORM_WINDOWS
550 HANDLE file_handle = (HANDLE) _get_osfhandle(int(sfd));
555 map_handle = CreateFileMapping(file_handle, NULL, PAGE_READONLY, 0, 0, NULL);
556 if (map_handle == NULL) {
557 error << string_compose (_("map failed - could not create file mapping for peakfile %1."), _peakpath) << endmsg;
561 view_handle = MapViewOfFile(map_handle, FILE_MAP_READ, 0, read_map_off, map_length);
562 if (view_handle == NULL) {
563 error << string_compose (_("map failed - could not map peakfile %1."), _peakpath) << endmsg;
567 addr = (char *) view_handle;
569 memcpy ((void*)staging.get(), (void*)(addr + map_delta), raw_map_length);
571 err_flag = UnmapViewOfFile (view_handle);
572 err_flag = CloseHandle(map_handle);
574 error << string_compose (_("unmap failed - could not unmap peakfile %1."), _peakpath) << endmsg;
578 addr = (char*) mmap (0, map_length, PROT_READ, MAP_PRIVATE, sfd, read_map_off);
579 if (addr == MAP_FAILED) {
580 error << string_compose (_("map failed - could not mmap peakfile %1."), _peakpath) << endmsg;
584 memcpy ((void*)staging.get(), (void*)(addr + map_delta), raw_map_length);
585 munmap (addr, map_length);
587 while (nvisual_peaks < read_npeaks) {
592 while ((current_stored_peak <= stored_peak_before_next_visual_peak) && (i < chunksize)) {
594 xmax = max (xmax, staging[i].max);
595 xmin = min (xmin, staging[i].min);
597 ++current_stored_peak;
600 peak_cache[nvisual_peaks].max = xmax;
601 peak_cache[nvisual_peaks].min = xmin;
603 next_visual_peak_frame = min ((double) start + cnt, (next_visual_peak_frame + samples_per_visual_peak));
604 stored_peak_before_next_visual_peak = (uint32_t) next_visual_peak_frame / samples_per_file_peak;
608 cerr << "Zero fill end of peaks (@ " << read_npeaks << " with " << zero_fill << ")" << endl;
609 memset (&peak_cache[read_npeaks], 0, sizeof (PeakData) * zero_fill);
613 _last_scale = samples_per_visual_peak;
614 _last_map_off = map_off;
615 _last_raw_map_length = raw_map_length;
618 memcpy ((void*)peaks, (void*)peak_cache.get(), npeaks * sizeof(PeakData));
621 DEBUG_TRACE (DEBUG::Peaks, "UPSAMPLE\n");
625 - less frames-per-peak (more resolution)
626 - more peaks than stored in the Peakfile
628 So, fetch data from the raw source, and generate peak
632 framecnt_t frames_read = 0;
633 framepos_t current_frame = start;
635 framecnt_t nvisual_peaks = 0;
636 framecnt_t chunksize = (framecnt_t) min (cnt, (framecnt_t) 4096);
637 boost::scoped_array<Sample> raw_staging(new Sample[chunksize]);
639 framepos_t frame_pos = start;
640 double pixel_pos = floor (frame_pos / samples_per_visual_peak);
641 double next_pixel_pos = ceil (frame_pos / samples_per_visual_peak);
642 double pixels_per_frame = 1.0 / samples_per_visual_peak;
647 while (nvisual_peaks < read_npeaks) {
649 if (i == frames_read) {
651 to_read = min (chunksize, (framecnt_t)(_length - current_frame));
653 if (current_frame >= _length) {
655 /* hmm, error condition - we've reached the end of the file
656 without generating all the peak data. cook up a zero-filled
657 data buffer and then use it. this is simpler than
658 adjusting zero_fill and read_npeaks and then breaking out of
662 memset (raw_staging.get(), 0, sizeof (Sample) * chunksize);
666 to_read = min (chunksize, (_length - current_frame));
669 if ((frames_read = read_unlocked (raw_staging.get(), current_frame, to_read)) == 0) {
670 error << string_compose(_("AudioSource[%1]: peak read - cannot read %2 samples at offset %3 of %4 (%5)"),
671 _name, to_read, current_frame, _length, strerror (errno))
680 xmax = max (xmax, raw_staging[i]);
681 xmin = min (xmin, raw_staging[i]);
684 pixel_pos += pixels_per_frame;
686 if (pixel_pos >= next_pixel_pos) {
688 peaks[nvisual_peaks].max = xmax;
689 peaks[nvisual_peaks].min = xmin;
694 next_pixel_pos = ceil (pixel_pos + 0.5);
699 memset (&peaks[read_npeaks], 0, sizeof (PeakData) * zero_fill);
703 DEBUG_TRACE (DEBUG::Peaks, "READPEAKS DONE\n");
708 AudioSource::build_peaks_from_scratch ()
710 const framecnt_t bufsize = 65536; // 256kB per disk read for mono data is about ideal
712 DEBUG_TRACE (DEBUG::Peaks, "Building peaks from scratch\n");
717 /* hold lock while building peaks */
719 Glib::Threads::Mutex::Lock lp (_lock);
721 if (prepare_for_peakfile_writes ()) {
725 framecnt_t current_frame = 0;
726 framecnt_t cnt = _length;
728 _peaks_built = false;
729 boost::scoped_array<Sample> buf(new Sample[bufsize]);
733 framecnt_t frames_to_read = min (bufsize, cnt);
734 framecnt_t frames_read;
736 if ((frames_read = read_unlocked (buf.get(), current_frame, frames_to_read)) != frames_to_read) {
737 error << string_compose(_("%1: could not write read raw data for peak computation (%2)"), _name, strerror (errno)) << endmsg;
738 done_with_peakfile_writes (false);
742 lp.release(); // allow butler to refill buffers
744 if (_session.deletion_in_progress()) {
745 cerr << "peak file creation interrupted: " << _name << endmsg;
746 done_with_peakfile_writes (false);
750 if (compute_and_write_peaks (buf.get(), current_frame, frames_read, true, false, _FPP)) {
754 current_frame += frames_read;
765 done_with_peakfile_writes ((cnt == 0));
773 DEBUG_TRACE (DEBUG::Peaks, string_compose("Could not write peak data, attempting to remove peakfile %1\n", _peakpath));
774 ::g_unlink (_peakpath.c_str());
781 AudioSource::prepare_for_peakfile_writes ()
783 if ((_peakfile_fd = g_open (_peakpath.c_str(), O_CREAT|O_RDWR, 0664)) < 0) {
784 error << string_compose(_("AudioSource: cannot open _peakpath (c) \"%1\" (%2)"), _peakpath, strerror (errno)) << endmsg;
791 AudioSource::done_with_peakfile_writes (bool done)
793 if (peak_leftover_cnt) {
794 compute_and_write_peaks (0, 0, 0, true, false, _FPP);
798 Glib::Threads::Mutex::Lock lm (_peaks_ready_lock);
800 PeaksReady (); /* EMIT SIGNAL */
803 close (_peakfile_fd);
807 /** @param first_frame Offset from the source start of the first frame to
808 * process. _lock MUST be held by caller.
811 AudioSource::compute_and_write_peaks (Sample* buf, framecnt_t first_frame, framecnt_t cnt,
812 bool force, bool intermediate_peaks_ready)
814 return compute_and_write_peaks (buf, first_frame, cnt, force, intermediate_peaks_ready, _FPP);
818 AudioSource::compute_and_write_peaks (Sample* buf, framecnt_t first_frame, framecnt_t cnt,
819 bool force, bool intermediate_peaks_ready, framecnt_t fpp)
822 uint32_t peaks_computed;
823 framepos_t current_frame;
824 framecnt_t frames_done;
825 const size_t blocksize = (128 * 1024);
826 off_t first_peak_byte;
827 boost::scoped_array<Sample> buf2;
829 if (_peakfile_fd < 0) {
830 if (prepare_for_peakfile_writes ()) {
836 if (peak_leftover_cnt) {
838 if (first_frame != peak_leftover_frame + peak_leftover_cnt) {
840 /* uh-oh, ::seek() since the last ::compute_and_write_peaks(),
841 and we have leftovers. flush a single peak (since the leftovers
842 never represent more than that, and restart.
847 x.min = peak_leftovers[0];
848 x.max = peak_leftovers[0];
850 off_t byte = (peak_leftover_frame / fpp) * sizeof (PeakData);
852 off_t offset = lseek (_peakfile_fd, byte, SEEK_SET);
854 if (offset != byte) {
855 error << string_compose(_("%1: could not seek in peak file data (%2)"), _name, strerror (errno)) << endmsg;
859 if (::write (_peakfile_fd, &x, sizeof (PeakData)) != sizeof (PeakData)) {
860 error << string_compose(_("%1: could not write peak file data (%2)"), _name, strerror (errno)) << endmsg;
864 _peak_byte_max = max (_peak_byte_max, (off_t) (byte + sizeof(PeakData)));
867 Glib::Threads::Mutex::Lock lm (_peaks_ready_lock);
868 PeakRangeReady (peak_leftover_frame, peak_leftover_cnt); /* EMIT SIGNAL */
869 if (intermediate_peaks_ready) {
870 PeaksReady (); /* EMIT SIGNAL */
874 /* left overs are done */
876 peak_leftover_cnt = 0;
880 /* else ... had leftovers, but they immediately preceed the new data, so just
881 merge them and compute.
884 /* make a new contiguous buffer containing leftovers and the new stuff */
886 to_do = cnt + peak_leftover_cnt;
887 buf2.reset(new Sample[to_do]);
890 memcpy (buf2.get(), peak_leftovers, peak_leftover_cnt * sizeof (Sample));
893 memcpy (buf2.get()+peak_leftover_cnt, buf, cnt * sizeof (Sample));
895 /* no more leftovers */
896 peak_leftover_cnt = 0;
898 /* use the temporary buffer */
901 /* make sure that when we write into the peakfile, we startup where we left off */
903 first_frame = peak_leftover_frame;
909 boost::scoped_array<PeakData> peakbuf(new PeakData[(to_do/fpp)+1]);
911 current_frame = first_frame;
916 /* if some frames were passed in (i.e. we're not flushing leftovers)
917 and there are less than fpp to do, save them till
921 if (force && (to_do < fpp)) {
922 /* keep the left overs around for next time */
924 if (peak_leftover_size < to_do) {
925 delete [] peak_leftovers;
926 peak_leftovers = new Sample[to_do];
927 peak_leftover_size = to_do;
929 memcpy (peak_leftovers, buf, to_do * sizeof (Sample));
930 peak_leftover_cnt = to_do;
931 peak_leftover_frame = current_frame;
938 framecnt_t this_time = min (fpp, to_do);
940 peakbuf[peaks_computed].max = buf[0];
941 peakbuf[peaks_computed].min = buf[0];
943 ARDOUR::find_peaks (buf+1, this_time-1, &peakbuf[peaks_computed].min, &peakbuf[peaks_computed].max);
948 frames_done += this_time;
949 current_frame += this_time;
952 first_peak_byte = (first_frame / fpp) * sizeof (PeakData);
954 if (can_truncate_peaks()) {
956 /* on some filesystems (ext3, at least) this helps to reduce fragmentation of
957 the peakfiles. its not guaranteed to do so, and even on ext3 (as of december 2006)
958 it does not cause single-extent allocation even for peakfiles of
959 less than BLOCKSIZE bytes. only call ftruncate if we'll make the file larger.
962 off_t endpos = lseek (_peakfile_fd, 0, SEEK_END);
963 off_t target_length = blocksize * ((first_peak_byte + blocksize + 1) / blocksize);
965 if (endpos < target_length) {
966 DEBUG_TRACE(DEBUG::Peaks, string_compose ("Truncating Peakfile %1\n", _peakpath));
967 if (ftruncate (_peakfile_fd, target_length)) {
968 /* error doesn't actually matter so continue on without testing */
974 off_t offset = lseek(_peakfile_fd, first_peak_byte, SEEK_SET);
976 if (offset != first_peak_byte) {
977 error << string_compose(_("%1: could not seek in peak file data (%2)"), _name, strerror (errno)) << endmsg;
981 ssize_t bytes_to_write = sizeof (PeakData) * peaks_computed;
983 ssize_t bytes_written = ::write (_peakfile_fd, peakbuf.get(), bytes_to_write);
985 if (bytes_written != bytes_to_write) {
986 error << string_compose(_("%1: could not write peak file data (%2)"), _name, strerror (errno)) << endmsg;
990 _peak_byte_max = max (_peak_byte_max, (off_t) (first_peak_byte + bytes_to_write));
993 Glib::Threads::Mutex::Lock lm (_peaks_ready_lock);
994 PeakRangeReady (first_frame, frames_done); /* EMIT SIGNAL */
995 if (intermediate_peaks_ready) {
996 PeaksReady (); /* EMIT SIGNAL */
1004 AudioSource::truncate_peakfile ()
1006 if (_peakfile_fd < 0) {
1007 error << string_compose (_("programming error: %1"), "AudioSource::truncate_peakfile() called without open peakfile descriptor")
1012 /* truncate the peakfile down to its natural length if necessary */
1014 off_t end = lseek (_peakfile_fd, 0, SEEK_END);
1016 if (end > _peak_byte_max) {
1017 DEBUG_TRACE(DEBUG::Peaks, string_compose ("Truncating Peakfile %1\n", _peakpath));
1018 if (ftruncate (_peakfile_fd, _peak_byte_max)) {
1019 error << string_compose (_("could not truncate peakfile %1 to %2 (error: %3)"),
1020 _peakpath, _peak_byte_max, errno) << endmsg;
1026 AudioSource::available_peaks (double zoom_factor) const
1028 if (zoom_factor < _FPP) {
1029 return length(_timeline_position); // peak data will come from the audio file
1032 /* peak data comes from peakfile, but the filesize might not represent
1033 the valid data due to ftruncate optimizations, so use _peak_byte_max state.
1034 XXX - there might be some atomicity issues here, we should probably add a lock,
1035 but _peak_byte_max only monotonically increases after initialization.
1038 off_t end = _peak_byte_max;
1040 return (end/sizeof(PeakData)) * _FPP;
1044 AudioSource::mark_streaming_write_completed (const Lock& lock)
1046 Glib::Threads::Mutex::Lock lm (_peaks_ready_lock);
1049 PeaksReady (); /* EMIT SIGNAL */
1054 AudioSource::allocate_working_buffers (framecnt_t framerate)
1056 Glib::Threads::Mutex::Lock lm (_level_buffer_lock);
1059 /* Note: we don't need any buffers allocated until
1060 a level 1 audiosource is created, at which
1061 time we'll call ::ensure_buffers_for_level()
1062 with the right value and do the right thing.
1065 if (!_mixdown_buffers.empty()) {
1066 ensure_buffers_for_level_locked ( _mixdown_buffers.size(), framerate);
1071 AudioSource::ensure_buffers_for_level (uint32_t level, framecnt_t frame_rate)
1073 Glib::Threads::Mutex::Lock lm (_level_buffer_lock);
1074 ensure_buffers_for_level_locked (level, frame_rate);
1078 AudioSource::ensure_buffers_for_level_locked (uint32_t level, framecnt_t frame_rate)
1080 framecnt_t nframes = (framecnt_t) floor (Config->get_audio_playback_buffer_seconds() * frame_rate);
1082 /* this may be called because either "level" or "frame_rate" have
1083 * changed. and it may be called with "level" smaller than the current
1084 * number of buffers, because a new compound region has been created at
1085 * a more shallow level than the deepest one we currently have.
1088 uint32_t limit = max ((size_t) level, _mixdown_buffers.size());
1090 _mixdown_buffers.clear ();
1091 _gain_buffers.clear ();
1093 for (uint32_t n = 0; n < limit; ++n) {
1094 _mixdown_buffers.push_back (boost::shared_array<Sample> (new Sample[nframes]));
1095 _gain_buffers.push_back (boost::shared_array<gain_t> (new gain_t[nframes]));