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.
18 $Id: source.cc 404 2006-03-17 17:39:21Z pauld $
34 #include <pbd/xml++.h>
35 #include <pbd/pthread_utils.h>
37 #include <ardour/audiosource.h>
38 #include <ardour/cycle_timer.h>
43 using namespace ARDOUR;
46 pthread_t AudioSource::peak_thread;
47 bool AudioSource::have_peak_thread = false;
48 vector<boost::shared_ptr<AudioSource> > AudioSource::pending_peak_sources;
49 Glib::Mutex* AudioSource::pending_peak_sources_lock = 0;
50 int AudioSource::peak_request_pipe[2];
52 bool AudioSource::_build_missing_peakfiles = false;
53 bool AudioSource::_build_peakfiles = false;
55 AudioSource::AudioSource (Session& s, string name)
58 if (pending_peak_sources_lock == 0) {
59 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;
76 next_peak_clear_should_notify = true;
78 _write_data_count = 0;
80 if (set_state (node)) {
81 throw failed_constructor();
85 AudioSource::~AudioSource ()
90 AudioSource::get_state ()
92 XMLNode& node (Source::get_state());
94 if (_captured_for.length()) {
95 node.add_property ("captured-for", _captured_for);
102 AudioSource::set_state (const XMLNode& node)
104 const XMLProperty* prop;
106 Source::set_state (node);
108 if ((prop = node.property ("captured-for")) != 0) {
109 _captured_for = prop->value();
115 /***********************************************************************
117 ***********************************************************************/
120 AudioSource::peak_thread_work (void* arg)
122 PBD::ThreadCreated (pthread_self(), X_("Peak"));
123 struct pollfd pfd[1];
125 if (pending_peak_sources_lock == 0) {
126 pending_peak_sources_lock = new Glib::Mutex;
129 Glib::Mutex::Lock lm (*pending_peak_sources_lock);
133 pfd[0].fd = peak_request_pipe[0];
134 pfd[0].events = POLLIN|POLLERR|POLLHUP;
136 pending_peak_sources_lock->unlock ();
138 if (poll (pfd, 1, -1) < 0) {
140 if (errno == EINTR) {
141 pending_peak_sources_lock->lock ();
145 error << string_compose (_("poll on peak request pipe failed (%1)"),
151 if (pfd[0].revents & ~POLLIN) {
152 error << _("Error on peak thread request pipe") << endmsg;
156 if (pfd[0].revents & POLLIN) {
160 /* empty the pipe of all current requests */
163 size_t nread = ::read (peak_request_pipe[0], &req, sizeof (req));
166 switch ((PeakRequest::Type) req) {
168 case PeakRequest::Build:
171 case PeakRequest::Quit:
172 pthread_exit_pbd (0);
180 } else if (nread == 0) {
182 } else if (errno == EAGAIN) {
185 fatal << _("Error reading from peak request pipe") << endmsg;
191 pending_peak_sources_lock->lock ();
193 while (!pending_peak_sources.empty()) {
195 boost::shared_ptr<AudioSource> s = pending_peak_sources.front();
196 pending_peak_sources.erase (pending_peak_sources.begin());
198 pending_peak_sources_lock->unlock ();
200 pending_peak_sources_lock->lock ();
204 pthread_exit_pbd (0);
210 AudioSource::start_peak_thread ()
212 if (!_build_peakfiles) {
216 if (pipe (peak_request_pipe)) {
217 error << string_compose(_("Cannot create transport request signal pipe (%1)"), strerror (errno)) << endmsg;
221 if (fcntl (peak_request_pipe[0], F_SETFL, O_NONBLOCK)) {
222 error << string_compose(_("UI: cannot set O_NONBLOCK on peak request pipe (%1)"), strerror (errno)) << endmsg;
226 if (fcntl (peak_request_pipe[1], F_SETFL, O_NONBLOCK)) {
227 error << string_compose(_("UI: cannot set O_NONBLOCK on peak request pipe (%1)"), strerror (errno)) << endmsg;
231 if (pthread_create_and_store ("peak file builder", &peak_thread, 0, peak_thread_work, 0)) {
232 error << _("AudioSource: could not create peak thread") << endmsg;
236 have_peak_thread = true;
241 AudioSource::stop_peak_thread ()
243 if (!have_peak_thread) {
249 char c = (char) PeakRequest::Quit;
250 ::write (peak_request_pipe[1], &c, 1);
251 pthread_join (peak_thread, &status);
255 AudioSource::queue_for_peaks (boost::shared_ptr<AudioSource> source)
257 if (have_peak_thread) {
259 Glib::Mutex::Lock lm (*pending_peak_sources_lock);
261 source->next_peak_clear_should_notify = true;
263 if (find (pending_peak_sources.begin(),
264 pending_peak_sources.end(),
265 source) == pending_peak_sources.end()) {
266 pending_peak_sources.push_back (source);
269 char c = (char) PeakRequest::Build;
270 ::write (peak_request_pipe[1], &c, 1);
274 void AudioSource::clear_queue_for_peaks ()
276 /* this is done to cancel a group of running peak builds */
277 if (have_peak_thread) {
278 Glib::Mutex::Lock lm (*pending_peak_sources_lock);
279 pending_peak_sources.clear ();
285 AudioSource::peaks_ready (sigc::slot<void> the_slot, sigc::connection& conn) const
288 Glib::Mutex::Lock lm (_lock);
290 /* check to see if the peak data is ready. if not
291 connect the slot while still holding the lock.
294 if (!(ret = _peaks_built)) {
295 conn = PeaksReady.connect (the_slot);
302 AudioSource::touch_peakfile ()
306 if (stat (peakpath.c_str(), &statbuf) != 0 || statbuf.st_size == 0) {
312 tbuf.actime = statbuf.st_atime;
313 tbuf.modtime = time ((time_t) 0);
315 utime (peakpath.c_str(), &tbuf);
319 AudioSource::rename_peakfile (string newpath)
321 /* caller must hold _lock */
323 string oldpath = peakpath;
325 if (access (oldpath.c_str(), F_OK) == 0) {
326 if (rename (oldpath.c_str(), newpath.c_str()) != 0) {
327 error << string_compose (_("cannot rename peakfile for %1 from %2 to %3 (%4)"), _name, oldpath, newpath, strerror (errno)) << endmsg;
338 AudioSource::initialize_peakfile (bool newfile, string audio_path)
342 peakpath = peak_path (audio_path);
344 /* Nasty band-aid for older sessions that were created before we
345 used libsndfile for all audio files.
348 if (!newfile && access (peakpath.c_str(), R_OK) != 0) {
349 string str = old_peak_path (audio_path);
350 if (access (str.c_str(), R_OK) == 0) {
357 if (!_build_peakfiles) {
361 _peaks_built = false;
365 if (stat (peakpath.c_str(), &statbuf)) {
366 if (errno != ENOENT) {
367 /* it exists in the peaks dir, but there is some kind of error */
369 error << string_compose(_("AudioSource: cannot stat peakfile \"%1\""), peakpath) << endmsg;
373 _peaks_built = false;
377 /* we found it in the peaks dir, so check it out */
379 if (statbuf.st_size == 0) {
380 _peaks_built = false;
382 // Check if the audio file has changed since the peakfile was built.
383 struct stat stat_file;
384 int err = stat (audio_path.c_str(), &stat_file);
386 if (!err && stat_file.st_mtime > statbuf.st_mtime){
387 _peaks_built = false;
395 if (!newfile && !_peaks_built && _build_missing_peakfiles && _build_peakfiles) {
396 build_peaks_from_scratch ();
403 AudioSource::read (Sample *dst, nframes_t start, nframes_t cnt) const
405 Glib::Mutex::Lock lm (_lock);
406 return read_unlocked (dst, start, cnt);
410 AudioSource::write (Sample *dst, nframes_t cnt)
412 Glib::Mutex::Lock lm (_lock);
413 return write_unlocked (dst, cnt);
417 AudioSource::read_peaks (PeakData *peaks, nframes_t npeaks, nframes_t start, nframes_t cnt, double samples_per_visual_peak) const
419 Glib::Mutex::Lock lm (_lock);
421 double expected_peaks;
422 PeakData::PeakDatum xmax;
423 PeakData::PeakDatum xmin;
426 nframes_t zero_fill = 0;
428 PeakData* staging = 0;
429 Sample* raw_staging = 0;
432 expected_peaks = (cnt / (double) frames_per_peak);
433 scale = npeaks/expected_peaks;
435 #undef DEBUG_READ_PEAKS
436 #ifdef DEBUG_READ_PEAKS
437 cerr << "======>RP: npeaks = " << npeaks
438 << " start = " << start
440 << " len = " << _length
441 << " samples_per_visual_peak =" << samples_per_visual_peak
442 << " expected was " << expected_peaks << " ... scale = " << scale
443 << " PD ptr = " << peaks
448 /* fix for near-end-of-file conditions */
450 if (cnt > _length - start) {
451 // cerr << "too close to end @ " << _length << " given " << start << " + " << cnt << endl;
452 cnt = _length - start;
453 nframes_t old = npeaks;
454 npeaks = min ((nframes_t) floor (cnt / samples_per_visual_peak), npeaks);
455 zero_fill = old - npeaks;
458 // cerr << "actual npeaks = " << npeaks << " zf = " << zero_fill << endl;
462 #ifdef DEBUG_READ_PEAKS
463 cerr << "RAW DATA\n";
465 /* no scaling at all, just get the sample data and duplicate it for
466 both max and min peak values.
469 Sample* raw_staging = new Sample[cnt];
471 if (read_unlocked (raw_staging, start, cnt) != cnt) {
472 error << _("cannot read sample data for unscaled peak computation") << endmsg;
476 for (nframes_t i = 0; i < npeaks; ++i) {
477 peaks[i].max = raw_staging[i];
478 peaks[i].min = raw_staging[i];
481 delete [] raw_staging;
487 off_t first_peak_byte = (start / frames_per_peak) * sizeof (PeakData);
489 /* open, read, close */
491 if ((peakfile = ::open (peakpath.c_str(), O_RDWR|O_CREAT, 0664)) < 0) {
492 error << string_compose(_("AudioSource: cannot open peakpath \"%1\" (%2)"), peakpath, strerror (errno)) << endmsg;
496 #ifdef DEBUG_READ_PEAKS
497 cerr << "DIRECT PEAKS\n";
500 nread = ::pread (peakfile, peaks, sizeof (PeakData)* npeaks, first_peak_byte);
503 if (nread != sizeof (PeakData) * npeaks) {
504 cerr << "AudioSource["
506 << "]: cannot read peaks from peakfile! (read only "
520 memset (&peaks[npeaks], 0, sizeof (PeakData) * zero_fill);
531 #ifdef DEBUG_READ_PEAKS
532 cerr << "DOWNSAMPLE\n";
536 - more frames-per-peak (lower resolution) than the peakfile, or to put it another way,
537 - less peaks than the peakfile holds for the same range
539 So, read a block into a staging area, and then downsample from there.
541 to avoid confusion, I'll refer to the requested peaks as visual_peaks and the peakfile peaks as stored_peaks
544 const uint32_t chunksize = (uint32_t) min (expected_peaks, 65536.0);
546 staging = new PeakData[chunksize];
548 /* compute the rounded up frame position */
550 nframes_t current_frame = start;
551 nframes_t current_stored_peak = (nframes_t) ceil (current_frame / (double) frames_per_peak);
552 uint32_t next_visual_peak = (uint32_t) ceil (current_frame / samples_per_visual_peak);
553 double next_visual_peak_frame = next_visual_peak * samples_per_visual_peak;
554 uint32_t stored_peak_before_next_visual_peak = (nframes_t) next_visual_peak_frame / frames_per_peak;
555 uint32_t nvisual_peaks = 0;
556 uint32_t stored_peaks_read = 0;
559 /* handle the case where the initial visual peak is on a pixel boundary */
561 current_stored_peak = min (current_stored_peak, stored_peak_before_next_visual_peak);
563 /* open ... close during out: handling */
565 if ((peakfile = ::open (peakpath.c_str(), O_RDWR|O_CREAT, 0664)) < 0) {
566 error << string_compose(_("AudioSource: cannot open peakpath \"%1\" (%2)"), peakpath, strerror (errno)) << endmsg;
570 while (nvisual_peaks < npeaks) {
572 if (i == stored_peaks_read) {
574 uint32_t start_byte = current_stored_peak * sizeof(PeakData);
575 tnp = min ((_length/frames_per_peak - current_stored_peak), (nframes_t) expected_peaks);
576 to_read = min (chunksize, tnp);
578 #ifdef DEBUG_READ_PEAKS
579 cerr << "read " << sizeof (PeakData) * to_read << " from peakfile @ " << start_byte << endl;
582 if ((nread = ::pread (peakfile, staging, sizeof (PeakData) * to_read, start_byte))
583 != sizeof (PeakData) * to_read) {
585 off_t fend = lseek (peakfile, 0, SEEK_END);
587 cerr << "AudioSource["
589 << "]: cannot read peak data from peakfile ("
590 << (nread / sizeof(PeakData))
591 << " peaks instead of "
596 << " at start_byte = " << start_byte
597 << " _length = " << _length << " versus len = " << fend
598 << " expected maxpeaks = " << (_length - current_frame)/frames_per_peak
599 << " npeaks was " << npeaks
605 stored_peaks_read = nread / sizeof(PeakData);
611 while ((i < stored_peaks_read) && (current_stored_peak <= stored_peak_before_next_visual_peak)) {
613 xmax = max (xmax, staging[i].max);
614 xmin = min (xmin, staging[i].min);
616 ++current_stored_peak;
620 peaks[nvisual_peaks].max = xmax;
621 peaks[nvisual_peaks].min = xmin;
625 //next_visual_peak_frame = min ((next_visual_peak * samples_per_visual_peak), (next_visual_peak_frame+samples_per_visual_peak) );
626 next_visual_peak_frame = min ((double) start+cnt, (next_visual_peak_frame+samples_per_visual_peak) );
627 stored_peak_before_next_visual_peak = (uint32_t) next_visual_peak_frame / frames_per_peak;
631 memset (&peaks[npeaks], 0, sizeof (PeakData) * zero_fill);
638 #ifdef DEBUG_READ_PEAKS
639 cerr << "UPSAMPLE\n";
643 - less frames-per-peak (more resolution)
644 - more peaks than stored in the Peakfile
646 So, fetch data from the raw source, and generate peak
650 nframes_t frames_read = 0;
651 nframes_t current_frame = start;
653 nframes_t nvisual_peaks = 0;
654 nframes_t chunksize = (nframes_t) min (cnt, (nframes_t) 4096);
655 raw_staging = new Sample[chunksize];
657 nframes_t frame_pos = start;
658 double pixel_pos = floor (frame_pos / samples_per_visual_peak);
659 double next_pixel_pos = ceil (frame_pos / samples_per_visual_peak);
660 double pixels_per_frame = 1.0 / samples_per_visual_peak;
665 while (nvisual_peaks < npeaks) {
667 if (i == frames_read) {
669 to_read = min (chunksize, (_length - current_frame));
671 if ((frames_read = read_unlocked (raw_staging, current_frame, to_read)) == 0) {
672 error << string_compose(_("AudioSource[%1]: peak read - cannot read %2 samples at offset %3")
673 , _name, to_read, current_frame)
681 xmax = max (xmax, raw_staging[i]);
682 xmin = min (xmin, raw_staging[i]);
685 pixel_pos += pixels_per_frame;
687 if (pixel_pos >= next_pixel_pos) {
689 peaks[nvisual_peaks].max = xmax;
690 peaks[nvisual_peaks].min = xmin;
695 next_pixel_pos = ceil (pixel_pos + 0.5);
700 memset (&peaks[npeaks], 0, sizeof (PeakData) * zero_fill);
716 delete [] raw_staging;
719 #ifdef DEBUG_READ_PEAKS
726 #undef DEBUG_PEAK_BUILD
729 AudioSource::build_peaks ()
731 vector<PeakBuildRecord*> built;
733 bool pr_signal = false;
734 list<PeakBuildRecord*> copy;
737 Glib::Mutex::Lock lm (_lock);
738 copy = pending_peak_builds;
739 pending_peak_builds.clear ();
742 #ifdef DEBUG_PEAK_BUILD
743 cerr << "build peaks with " << copy.size() << " requests pending\n";
746 for (list<PeakBuildRecord *>::iterator i = copy.begin(); i != copy.end(); ++i) {
748 if ((status = do_build_peak ((*i)->frame, (*i)->cnt)) != 0) {
749 unlink (peakpath.c_str());
752 built.push_back (new PeakBuildRecord (*(*i)));
757 Glib::Mutex::Lock lm (_lock);
762 if (next_peak_clear_should_notify) {
763 next_peak_clear_should_notify = false;
770 for (vector<PeakBuildRecord *>::iterator i = built.begin(); i != built.end(); ++i) {
771 PeakRangeReady ((*i)->frame, (*i)->cnt); /* EMIT SIGNAL */
776 PeaksReady (); /* EMIT SIGNAL */
784 AudioSource::do_build_peak (nframes_t first_frame, nframes_t cnt)
786 nframes_t current_frame;
787 Sample buf[frames_per_peak];
791 nframes_t frames_read;
792 nframes_t frames_to_read;
793 off_t first_peak_byte;
798 #ifdef DEBUG_PEAK_BUILD
799 cerr << pthread_self() << ": " << _name << ": building peaks for " << first_frame << " to " << first_frame + cnt - 1 << endl;
802 first_peak_byte = (first_frame / frames_per_peak) * sizeof (PeakData);
804 #ifdef DEBUG_PEAK_BUILD
805 cerr << "seeking to " << first_peak_byte << " before writing new peak data\n";
808 current_frame = first_frame;
809 peakbuf = new PeakData[(cnt/frames_per_peak)+1];
812 if ((peakfile = ::open (peakpath.c_str(), O_RDWR|O_CREAT, 0664)) < 0) {
813 error << string_compose(_("AudioSource: cannot open peakpath \"%1\" (%2)"), peakpath, strerror (errno)) << endmsg;
819 frames_to_read = min (frames_per_peak, cnt);
821 /* lock for every read */
823 if ((frames_read = read (buf, current_frame, frames_to_read)) != frames_to_read) {
824 error << string_compose(_("%1: could not write read raw data for peak computation (%2)"), _name, strerror (errno)) << endmsg;
831 for (nframes_t n = 1; n < frames_read; ++n) {
832 xmax = max (xmax, buf[n]);
833 xmin = min (xmin, buf[n]);
835 // if (current_frame < frames_read) {
836 // cerr << "sample = " << buf[n] << " max = " << xmax << " min = " << xmin << " max of 2 = " << max (xmax, buf[n]) << endl;
840 peakbuf[peaki].max = xmax;
841 peakbuf[peaki].min = xmin;
844 current_frame += frames_read;
848 #define BLOCKSIZE (256 * 1024)
850 target_length = BLOCKSIZE * ((first_peak_byte + BLOCKSIZE + 1) / BLOCKSIZE);
852 /* on some filesystems (ext3, at least) this helps to reduce fragmentation of
853 the peakfiles. its not guaranteed to do so, and even on ext3 (as of december 2006)
854 it does not cause single-extent allocation even for peakfiles of
855 less than BLOCKSIZE bytes.
858 ftruncate (peakfile, target_length);
860 /* error doesn't actually matter though, so continue on without testing */
862 if (::pwrite (peakfile, peakbuf, sizeof (PeakData) * peaki, first_peak_byte) != (ssize_t) (sizeof (PeakData) * peaki)) {
863 error << string_compose(_("%1: could not write peak file data (%2)"), _name, strerror (errno)) << endmsg;
878 AudioSource::build_peaks_from_scratch ()
880 Glib::Mutex::Lock lp (_lock);
882 next_peak_clear_should_notify = true;
883 pending_peak_builds.push_back (new PeakBuildRecord (0, _length));
884 queue_for_peaks (shared_from_this());
888 AudioSource::file_changed (string path)
890 struct stat stat_file;
891 struct stat stat_peak;
893 int e1 = stat (path.c_str(), &stat_file);
894 int e2 = stat (peak_path(path).c_str(), &stat_peak);
896 if (!e1 && !e2 && stat_file.st_mtime > stat_peak.st_mtime){
904 AudioSource::available_peaks (double zoom_factor) const
909 if (zoom_factor < frames_per_peak) {
910 return length(); // peak data will come from the audio file
913 /* peak data comes from peakfile */
915 if ((peakfile = ::open (peakpath.c_str(), O_RDONLY)) < 0) {
916 error << string_compose(_("AudioSource: cannot open peakpath \"%1\" (%2)"), peakpath, strerror (errno)) << endmsg;
921 Glib::Mutex::Lock lm (_lock);
922 end = lseek (peakfile, 0, SEEK_END);
927 return (end/sizeof(PeakData)) * frames_per_peak;
931 AudioSource::update_length (nframes_t pos, nframes_t cnt)
933 if (pos + cnt > _length) {