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.
33 #include <pbd/xml++.h>
34 #include <pbd/pthread_utils.h>
36 #include <ardour/audiosource.h>
37 #include <ardour/cycle_timer.h>
42 using namespace ARDOUR;
45 pthread_t AudioSource::peak_thread;
46 bool AudioSource::have_peak_thread = false;
47 vector<boost::shared_ptr<AudioSource> > AudioSource::pending_peak_sources;
48 Glib::Mutex* AudioSource::pending_peak_sources_lock = 0;
49 int AudioSource::peak_request_pipe[2];
51 bool AudioSource::_build_missing_peakfiles = false;
52 bool AudioSource::_build_peakfiles = false;
54 AudioSource::AudioSource (Session& s, string name)
57 if (pending_peak_sources_lock == 0) {
58 pending_peak_sources_lock = new Glib::Mutex;
63 next_peak_clear_should_notify = true;
65 _write_data_count = 0;
68 AudioSource::AudioSource (Session& s, const XMLNode& node)
71 if (pending_peak_sources_lock == 0) {
72 pending_peak_sources_lock = new Glib::Mutex;
77 next_peak_clear_should_notify = true;
79 _write_data_count = 0;
81 if (set_state (node)) {
82 throw failed_constructor();
86 AudioSource::~AudioSource ()
91 AudioSource::get_state ()
93 XMLNode& node (Source::get_state());
95 if (_captured_for.length()) {
96 node.add_property ("captured-for", _captured_for);
103 AudioSource::set_state (const XMLNode& node)
105 const XMLProperty* prop;
107 Source::set_state (node);
109 if ((prop = node.property ("captured-for")) != 0) {
110 _captured_for = prop->value();
116 /***********************************************************************
118 ***********************************************************************/
121 AudioSource::peak_thread_work (void* arg)
123 PBD::ThreadCreated (pthread_self(), X_("Peak"));
124 struct pollfd pfd[1];
126 if (pending_peak_sources_lock == 0) {
127 pending_peak_sources_lock = new Glib::Mutex;
130 Glib::Mutex::Lock lm (*pending_peak_sources_lock);
134 pfd[0].fd = peak_request_pipe[0];
135 pfd[0].events = POLLIN|POLLERR|POLLHUP;
137 pending_peak_sources_lock->unlock ();
139 if (poll (pfd, 1, -1) < 0) {
141 if (errno == EINTR) {
142 pending_peak_sources_lock->lock ();
146 error << string_compose (_("poll on peak request pipe failed (%1)"),
152 if (pfd[0].revents & ~POLLIN) {
153 error << _("Error on peak thread request pipe") << endmsg;
157 if (pfd[0].revents & POLLIN) {
161 /* empty the pipe of all current requests */
164 size_t nread = ::read (peak_request_pipe[0], &req, sizeof (req));
167 switch ((PeakRequest::Type) req) {
169 case PeakRequest::Build:
172 case PeakRequest::Quit:
173 pthread_exit_pbd (0);
181 } else if (nread == 0) {
183 } else if (errno == EAGAIN) {
186 fatal << _("Error reading from peak request pipe") << endmsg;
192 pending_peak_sources_lock->lock ();
194 while (!pending_peak_sources.empty()) {
196 boost::shared_ptr<AudioSource> s = pending_peak_sources.front();
197 pending_peak_sources.erase (pending_peak_sources.begin());
199 pending_peak_sources_lock->unlock ();
201 pending_peak_sources_lock->lock ();
205 pthread_exit_pbd (0);
211 AudioSource::start_peak_thread ()
213 if (!_build_peakfiles) {
217 if (pipe (peak_request_pipe)) {
218 error << string_compose(_("Cannot create transport request signal pipe (%1)"), strerror (errno)) << endmsg;
222 if (fcntl (peak_request_pipe[0], F_SETFL, O_NONBLOCK)) {
223 error << string_compose(_("UI: cannot set O_NONBLOCK on peak request pipe (%1)"), strerror (errno)) << endmsg;
227 if (fcntl (peak_request_pipe[1], F_SETFL, O_NONBLOCK)) {
228 error << string_compose(_("UI: cannot set O_NONBLOCK on peak request pipe (%1)"), strerror (errno)) << endmsg;
232 if (pthread_create_and_store ("peak file builder", &peak_thread, 0, peak_thread_work, 0)) {
233 error << _("AudioSource: could not create peak thread") << endmsg;
237 have_peak_thread = true;
242 AudioSource::stop_peak_thread ()
244 if (!have_peak_thread) {
250 char c = (char) PeakRequest::Quit;
251 ::write (peak_request_pipe[1], &c, 1);
252 pthread_join (peak_thread, &status);
256 AudioSource::queue_for_peaks (boost::shared_ptr<AudioSource> source, bool notify)
258 if (have_peak_thread) {
260 Glib::Mutex::Lock lm (*pending_peak_sources_lock);
262 source->next_peak_clear_should_notify = notify;
264 if (find (pending_peak_sources.begin(),
265 pending_peak_sources.end(),
266 source) == pending_peak_sources.end()) {
267 pending_peak_sources.push_back (source);
270 char c = (char) PeakRequest::Build;
271 ::write (peak_request_pipe[1], &c, 1);
275 void AudioSource::clear_queue_for_peaks ()
277 /* this is done to cancel a group of running peak builds */
278 if (have_peak_thread) {
279 Glib::Mutex::Lock lm (*pending_peak_sources_lock);
280 pending_peak_sources.clear ();
286 AudioSource::peaks_ready (sigc::slot<void> the_slot, sigc::connection& conn) const
289 Glib::Mutex::Lock lm (_lock);
291 /* check to see if the peak data is ready. if not
292 connect the slot while still holding the lock.
295 if (!(ret = _peaks_built)) {
296 conn = PeaksReady.connect (the_slot);
303 AudioSource::touch_peakfile ()
307 if (stat (peakpath.c_str(), &statbuf) != 0 || statbuf.st_size == 0) {
313 tbuf.actime = statbuf.st_atime;
314 tbuf.modtime = time ((time_t) 0);
316 utime (peakpath.c_str(), &tbuf);
320 AudioSource::rename_peakfile (string newpath)
322 /* caller must hold _lock */
324 string oldpath = peakpath;
326 if (access (oldpath.c_str(), F_OK) == 0) {
327 if (rename (oldpath.c_str(), newpath.c_str()) != 0) {
328 error << string_compose (_("cannot rename peakfile for %1 from %2 to %3 (%4)"), _name, oldpath, newpath, strerror (errno)) << endmsg;
339 AudioSource::initialize_peakfile (bool newfile, string audio_path)
343 peakpath = peak_path (audio_path);
345 /* Nasty band-aid for older sessions that were created before we
346 used libsndfile for all audio files.
349 if (!newfile && access (peakpath.c_str(), R_OK) != 0) {
350 string str = old_peak_path (audio_path);
351 if (access (str.c_str(), R_OK) == 0) {
358 if (!_build_peakfiles) {
362 _peaks_built = false;
366 if (stat (peakpath.c_str(), &statbuf)) {
367 if (errno != ENOENT) {
368 /* it exists in the peaks dir, but there is some kind of error */
370 error << string_compose(_("AudioSource: cannot stat peakfile \"%1\""), peakpath) << endmsg;
374 _peaks_built = false;
378 /* we found it in the peaks dir, so check it out */
380 if (statbuf.st_size == 0) {
381 _peaks_built = false;
383 // Check if the audio file has changed since the peakfile was built.
384 struct stat stat_file;
385 int err = stat (audio_path.c_str(), &stat_file);
387 if (!err && stat_file.st_mtime > statbuf.st_mtime){
388 _peaks_built = false;
392 _peak_byte_max = statbuf.st_size;
398 if (!newfile && !_peaks_built && _build_missing_peakfiles && _build_peakfiles) {
399 build_peaks_from_scratch ();
406 AudioSource::read (Sample *dst, nframes_t start, nframes_t cnt) const
408 Glib::Mutex::Lock lm (_lock);
409 return read_unlocked (dst, start, cnt);
413 AudioSource::write (Sample *dst, nframes_t cnt)
415 Glib::Mutex::Lock lm (_lock);
416 return write_unlocked (dst, cnt);
420 AudioSource::read_peaks (PeakData *peaks, nframes_t npeaks, nframes_t start, nframes_t cnt, double samples_per_visual_peak) const
422 Glib::Mutex::Lock lm (_lock);
424 double expected_peaks;
425 PeakData::PeakDatum xmax;
426 PeakData::PeakDatum xmin;
429 nframes_t zero_fill = 0;
431 PeakData* staging = 0;
432 Sample* raw_staging = 0;
435 expected_peaks = (cnt / (double) frames_per_peak);
436 scale = npeaks/expected_peaks;
438 #undef DEBUG_READ_PEAKS
439 #ifdef DEBUG_READ_PEAKS
440 cerr << "======>RP: npeaks = " << npeaks
441 << " start = " << start
443 << " len = " << _length
444 << " samples_per_visual_peak =" << samples_per_visual_peak
445 << " expected was " << expected_peaks << " ... scale = " << scale
446 << " PD ptr = " << peaks
451 /* fix for near-end-of-file conditions */
453 if (cnt > _length - start) {
454 // cerr << "too close to end @ " << _length << " given " << start << " + " << cnt << endl;
455 cnt = _length - start;
456 nframes_t old = npeaks;
457 npeaks = min ((nframes_t) floor (cnt / samples_per_visual_peak), npeaks);
458 zero_fill = old - npeaks;
461 // cerr << "actual npeaks = " << npeaks << " zf = " << zero_fill << endl;
465 #ifdef DEBUG_READ_PEAKS
466 cerr << "RAW DATA\n";
468 /* no scaling at all, just get the sample data and duplicate it for
469 both max and min peak values.
472 Sample* raw_staging = new Sample[cnt];
474 if (read_unlocked (raw_staging, start, cnt) != cnt) {
475 error << _("cannot read sample data for unscaled peak computation") << endmsg;
479 for (nframes_t i = 0; i < npeaks; ++i) {
480 peaks[i].max = raw_staging[i];
481 peaks[i].min = raw_staging[i];
484 delete [] raw_staging;
490 off_t first_peak_byte = (start / frames_per_peak) * sizeof (PeakData);
492 /* open, read, close */
494 if ((peakfile = ::open (peakpath.c_str(), O_RDONLY, 0664)) < 0) {
495 error << string_compose(_("AudioSource: cannot open peakpath \"%1\" (%2)"), peakpath, strerror (errno)) << endmsg;
499 #ifdef DEBUG_READ_PEAKS
500 cerr << "DIRECT PEAKS\n";
503 nread = ::pread (peakfile, peaks, sizeof (PeakData)* npeaks, first_peak_byte);
506 if (nread != sizeof (PeakData) * npeaks) {
507 cerr << "AudioSource["
509 << "]: cannot read peaks from peakfile! (read only "
523 memset (&peaks[npeaks], 0, sizeof (PeakData) * zero_fill);
534 #ifdef DEBUG_READ_PEAKS
535 cerr << "DOWNSAMPLE\n";
539 - more frames-per-peak (lower resolution) than the peakfile, or to put it another way,
540 - less peaks than the peakfile holds for the same range
542 So, read a block into a staging area, and then downsample from there.
544 to avoid confusion, I'll refer to the requested peaks as visual_peaks and the peakfile peaks as stored_peaks
547 const uint32_t chunksize = (uint32_t) min (expected_peaks, 65536.0);
549 staging = new PeakData[chunksize];
551 /* compute the rounded up frame position */
553 nframes_t current_frame = start;
554 nframes_t current_stored_peak = (nframes_t) ceil (current_frame / (double) frames_per_peak);
555 uint32_t next_visual_peak = (uint32_t) ceil (current_frame / samples_per_visual_peak);
556 double next_visual_peak_frame = next_visual_peak * samples_per_visual_peak;
557 uint32_t stored_peak_before_next_visual_peak = (nframes_t) next_visual_peak_frame / frames_per_peak;
558 uint32_t nvisual_peaks = 0;
559 uint32_t stored_peaks_read = 0;
562 /* handle the case where the initial visual peak is on a pixel boundary */
564 current_stored_peak = min (current_stored_peak, stored_peak_before_next_visual_peak);
566 /* open ... close during out: handling */
568 if ((peakfile = ::open (peakpath.c_str(), O_RDONLY, 0664)) < 0) {
569 error << string_compose(_("AudioSource: cannot open peakpath \"%1\" (%2)"), peakpath, strerror (errno)) << endmsg;
573 while (nvisual_peaks < npeaks) {
575 if (i == stored_peaks_read) {
577 uint32_t start_byte = current_stored_peak * sizeof(PeakData);
578 tnp = min ((_length/frames_per_peak - current_stored_peak), (nframes_t) expected_peaks);
579 to_read = min (chunksize, tnp);
581 #ifdef DEBUG_READ_PEAKS
582 cerr << "read " << sizeof (PeakData) * to_read << " from peakfile @ " << start_byte << endl;
585 if ((nread = ::pread (peakfile, staging, sizeof (PeakData) * to_read, start_byte))
586 != sizeof (PeakData) * to_read) {
588 off_t fend = lseek (peakfile, 0, SEEK_END);
590 cerr << "AudioSource["
592 << "]: cannot read peak data from peakfile ("
593 << (nread / sizeof(PeakData))
594 << " peaks instead of "
599 << " at start_byte = " << start_byte
600 << " _length = " << _length << " versus len = " << fend
601 << " expected maxpeaks = " << (_length - current_frame)/frames_per_peak
602 << " npeaks was " << npeaks
608 stored_peaks_read = nread / sizeof(PeakData);
614 while ((i < stored_peaks_read) && (current_stored_peak <= stored_peak_before_next_visual_peak)) {
616 xmax = max (xmax, staging[i].max);
617 xmin = min (xmin, staging[i].min);
619 ++current_stored_peak;
623 peaks[nvisual_peaks].max = xmax;
624 peaks[nvisual_peaks].min = xmin;
628 //next_visual_peak_frame = min ((next_visual_peak * samples_per_visual_peak), (next_visual_peak_frame+samples_per_visual_peak) );
629 next_visual_peak_frame = min ((double) start+cnt, (next_visual_peak_frame+samples_per_visual_peak) );
630 stored_peak_before_next_visual_peak = (uint32_t) next_visual_peak_frame / frames_per_peak;
634 memset (&peaks[npeaks], 0, sizeof (PeakData) * zero_fill);
641 #ifdef DEBUG_READ_PEAKS
642 cerr << "UPSAMPLE\n";
646 - less frames-per-peak (more resolution)
647 - more peaks than stored in the Peakfile
649 So, fetch data from the raw source, and generate peak
653 nframes_t frames_read = 0;
654 nframes_t current_frame = start;
656 nframes_t nvisual_peaks = 0;
657 nframes_t chunksize = (nframes_t) min (cnt, (nframes_t) 4096);
658 raw_staging = new Sample[chunksize];
660 nframes_t frame_pos = start;
661 double pixel_pos = floor (frame_pos / samples_per_visual_peak);
662 double next_pixel_pos = ceil (frame_pos / samples_per_visual_peak);
663 double pixels_per_frame = 1.0 / samples_per_visual_peak;
668 while (nvisual_peaks < npeaks) {
670 if (i == frames_read) {
672 to_read = min (chunksize, (_length - current_frame));
674 if ((frames_read = read_unlocked (raw_staging, current_frame, to_read)) == 0) {
675 error << string_compose(_("AudioSource[%1]: peak read - cannot read %2 samples at offset %3")
676 , _name, to_read, current_frame)
684 xmax = max (xmax, raw_staging[i]);
685 xmin = min (xmin, raw_staging[i]);
688 pixel_pos += pixels_per_frame;
690 if (pixel_pos >= next_pixel_pos) {
692 peaks[nvisual_peaks].max = xmax;
693 peaks[nvisual_peaks].min = xmin;
698 next_pixel_pos = ceil (pixel_pos + 0.5);
703 memset (&peaks[npeaks], 0, sizeof (PeakData) * zero_fill);
719 delete [] raw_staging;
722 #ifdef DEBUG_READ_PEAKS
729 #undef DEBUG_PEAK_BUILD
732 AudioSource::build_peaks ()
734 vector<PeakBuildRecord*> built;
736 bool pr_signal = false;
737 list<PeakBuildRecord*> copy;
740 Glib::Mutex::Lock lm (_lock);
741 copy = pending_peak_builds;
742 pending_peak_builds.clear ();
745 #ifdef DEBUG_PEAK_BUILD
746 cerr << "build peaks with " << copy.size() << " requests pending\n";
749 for (list<PeakBuildRecord *>::iterator i = copy.begin(); i != copy.end(); ++i) {
751 if ((status = do_build_peak ((*i)->frame, (*i)->cnt)) != 0) {
752 unlink (peakpath.c_str());
755 built.push_back (new PeakBuildRecord (*(*i)));
760 Glib::Mutex::Lock lm (_lock);
765 if (next_peak_clear_should_notify) {
766 next_peak_clear_should_notify = false;
773 for (vector<PeakBuildRecord *>::iterator i = built.begin(); i != built.end(); ++i) {
774 PeakRangeReady ((*i)->frame, (*i)->cnt); /* EMIT SIGNAL */
780 PeaksReady (); /* EMIT SIGNAL */
788 AudioSource::do_build_peak (nframes_t first_frame, nframes_t cnt)
790 nframes_t current_frame;
791 Sample buf[frames_per_peak];
795 nframes_t frames_read;
796 nframes_t frames_to_read;
797 off_t first_peak_byte;
803 #ifdef DEBUG_PEAK_BUILD
804 cerr << pthread_self() << ": " << _name << ": building peaks for " << first_frame << " to " << first_frame + cnt - 1 << endl;
807 first_peak_byte = (first_frame / frames_per_peak) * sizeof (PeakData);
809 #ifdef DEBUG_PEAK_BUILD
810 cerr << "seeking to " << first_peak_byte << " before writing new peak data\n";
813 current_frame = first_frame;
814 peakbuf = new PeakData[(cnt/frames_per_peak)+1];
817 if ((peakfile = ::open (peakpath.c_str(), O_RDWR|O_CREAT, 0664)) < 0) {
818 error << string_compose(_("AudioSource: cannot open peakpath \"%1\" (%2)"), peakpath, strerror (errno)) << endmsg;
824 frames_to_read = min (frames_per_peak, cnt);
826 /* lock for every read */
828 if ((frames_read = read (buf, current_frame, frames_to_read)) != frames_to_read) {
829 error << string_compose(_("%1: could not write read raw data for peak computation (%2)"), _name, strerror (errno)) << endmsg;
836 for (nframes_t n = 1; n < frames_read; ++n) {
837 xmax = max (xmax, buf[n]);
838 xmin = min (xmin, buf[n]);
840 // if (current_frame < frames_read) {
841 // cerr << "sample = " << buf[n] << " max = " << xmax << " min = " << xmin << " max of 2 = " << max (xmax, buf[n]) << endl;
845 peakbuf[peaki].max = xmax;
846 peakbuf[peaki].min = xmin;
849 current_frame += frames_read;
853 #define BLOCKSIZE (128 * 1024)
855 /* on some filesystems (ext3, at least) this helps to reduce fragmentation of
856 the peakfiles. its not guaranteed to do so, and even on ext3 (as of december 2006)
857 it does not cause single-extent allocation even for peakfiles of
858 less than BLOCKSIZE bytes. only call ftruncate if we'll make the file larger.
860 endpos = lseek (peakfile, 0, SEEK_END);
862 target_length = BLOCKSIZE * ((first_peak_byte + BLOCKSIZE + 1) / BLOCKSIZE);
864 if (endpos < target_length) {
865 // XXX - we really shouldn't be doing this for destructive source peaks
866 ftruncate (peakfile, target_length);
867 //cerr << "do build TRUNC: " << peakpath << " " << target_length << endl;
869 /* error doesn't actually matter though, so continue on without testing */
872 if (::pwrite (peakfile, peakbuf, sizeof (PeakData) * peaki, first_peak_byte) != (ssize_t) (sizeof (PeakData) * peaki)) {
873 error << string_compose(_("%1: could not write peak file data (%2)"), _name, strerror (errno)) << endmsg;
877 _peak_byte_max = max(_peak_byte_max, (off_t) (first_peak_byte + sizeof(PeakData)*peaki));
890 AudioSource::build_peaks_from_scratch ()
892 Glib::Mutex::Lock lp (_lock);
894 next_peak_clear_should_notify = true;
895 pending_peak_builds.push_back (new PeakBuildRecord (0, _length));
896 queue_for_peaks (shared_from_this(), true);
900 AudioSource::truncate_peakfile ()
904 /* truncate the peakfile down to its natural length if necessary */
906 if ((peakfile = ::open (peakpath.c_str(), O_RDWR)) >= 0) {
907 off_t end = lseek (peakfile, 0, SEEK_END);
909 if (end > _peak_byte_max) {
910 ftruncate(peakfile, _peak_byte_max);
911 //cerr << "truncated " << peakpath << " to " << _peak_byte_max << " bytes" << endl;
914 //cerr << "NOT truncated " << peakpath << " to " << _peak_byte_max << " end " << end << endl;
921 AudioSource::file_changed (string path)
923 struct stat stat_file;
924 struct stat stat_peak;
926 int e1 = stat (path.c_str(), &stat_file);
927 int e2 = stat (peak_path(path).c_str(), &stat_peak);
929 if (!e1 && !e2 && stat_file.st_mtime > stat_peak.st_mtime){
937 AudioSource::available_peaks (double zoom_factor) const
941 if (zoom_factor < frames_per_peak) {
942 return length(); // peak data will come from the audio file
945 /* peak data comes from peakfile, but the filesize might not represent
946 the valid data due to ftruncate optimizations, so use _peak_byte_max state.
947 XXX - there might be some atomicity issues here, we should probably add a lock,
948 but _peak_byte_max only monotonically increases after initialization.
951 end = _peak_byte_max;
953 return (end/sizeof(PeakData)) * frames_per_peak;
957 AudioSource::update_length (nframes_t pos, nframes_t cnt)
959 if (pos + cnt > _length) {