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;
64 next_peak_clear_should_notify = true;
66 _write_data_count = 0;
69 AudioSource::AudioSource (Session& s, const XMLNode& node)
72 if (pending_peak_sources_lock == 0) {
73 pending_peak_sources_lock = new Glib::Mutex;
78 next_peak_clear_should_notify = true;
80 _write_data_count = 0;
82 if (set_state (node)) {
83 throw failed_constructor();
87 AudioSource::~AudioSource ()
92 AudioSource::get_state ()
94 XMLNode& node (Source::get_state());
96 if (_captured_for.length()) {
97 node.add_property ("captured-for", _captured_for);
104 AudioSource::set_state (const XMLNode& node)
106 const XMLProperty* prop;
108 Source::set_state (node);
110 if ((prop = node.property ("captured-for")) != 0) {
111 _captured_for = prop->value();
117 /***********************************************************************
119 ***********************************************************************/
122 AudioSource::peak_thread_work (void* arg)
124 PBD::ThreadCreated (pthread_self(), X_("Peak"));
125 struct pollfd pfd[1];
127 if (pending_peak_sources_lock == 0) {
128 pending_peak_sources_lock = new Glib::Mutex;
131 Glib::Mutex::Lock lm (*pending_peak_sources_lock);
135 pfd[0].fd = peak_request_pipe[0];
136 pfd[0].events = POLLIN|POLLERR|POLLHUP;
138 pending_peak_sources_lock->unlock ();
140 if (poll (pfd, 1, -1) < 0) {
142 if (errno == EINTR) {
143 pending_peak_sources_lock->lock ();
147 error << string_compose (_("poll on peak request pipe failed (%1)"),
153 if (pfd[0].revents & ~POLLIN) {
154 error << _("Error on peak thread request pipe") << endmsg;
158 if (pfd[0].revents & POLLIN) {
162 /* empty the pipe of all current requests */
165 size_t nread = ::read (peak_request_pipe[0], &req, sizeof (req));
168 switch ((PeakRequest::Type) req) {
170 case PeakRequest::Build:
173 case PeakRequest::Quit:
174 pthread_exit_pbd (0);
182 } else if (nread == 0) {
184 } else if (errno == EAGAIN) {
187 fatal << _("Error reading from peak request pipe") << endmsg;
193 pending_peak_sources_lock->lock ();
195 while (!pending_peak_sources.empty()) {
197 boost::shared_ptr<AudioSource> s = pending_peak_sources.front();
198 pending_peak_sources.erase (pending_peak_sources.begin());
200 pending_peak_sources_lock->unlock ();
202 pending_peak_sources_lock->lock ();
206 pthread_exit_pbd (0);
212 AudioSource::start_peak_thread ()
214 if (!_build_peakfiles) {
218 if (pipe (peak_request_pipe)) {
219 error << string_compose(_("Cannot create transport request signal pipe (%1)"), strerror (errno)) << endmsg;
223 if (fcntl (peak_request_pipe[0], F_SETFL, O_NONBLOCK)) {
224 error << string_compose(_("UI: cannot set O_NONBLOCK on peak request pipe (%1)"), strerror (errno)) << endmsg;
228 if (fcntl (peak_request_pipe[1], F_SETFL, O_NONBLOCK)) {
229 error << string_compose(_("UI: cannot set O_NONBLOCK on peak request pipe (%1)"), strerror (errno)) << endmsg;
233 if (pthread_create_and_store ("peak file builder", &peak_thread, 0, peak_thread_work, 0)) {
234 error << _("AudioSource: could not create peak thread") << endmsg;
238 have_peak_thread = true;
243 AudioSource::stop_peak_thread ()
245 if (!have_peak_thread) {
251 char c = (char) PeakRequest::Quit;
252 ::write (peak_request_pipe[1], &c, 1);
253 pthread_join (peak_thread, &status);
257 AudioSource::queue_for_peaks (boost::shared_ptr<AudioSource> source, bool notify)
259 if (have_peak_thread) {
261 Glib::Mutex::Lock lm (*pending_peak_sources_lock);
263 source->next_peak_clear_should_notify = notify;
265 if (find (pending_peak_sources.begin(),
266 pending_peak_sources.end(),
267 source) == pending_peak_sources.end()) {
268 pending_peak_sources.push_back (source);
271 char c = (char) PeakRequest::Build;
272 ::write (peak_request_pipe[1], &c, 1);
276 void AudioSource::clear_queue_for_peaks ()
278 /* this is done to cancel a group of running peak builds */
279 if (have_peak_thread) {
280 Glib::Mutex::Lock lm (*pending_peak_sources_lock);
281 pending_peak_sources.clear ();
287 AudioSource::peaks_ready (sigc::slot<void> the_slot, sigc::connection& conn) const
290 Glib::Mutex::Lock lm (_lock);
292 /* check to see if the peak data is ready. if not
293 connect the slot while still holding the lock.
296 if (!(ret = _peaks_built)) {
297 conn = PeaksReady.connect (the_slot);
304 AudioSource::touch_peakfile ()
308 if (stat (peakpath.c_str(), &statbuf) != 0 || statbuf.st_size == 0) {
314 tbuf.actime = statbuf.st_atime;
315 tbuf.modtime = time ((time_t) 0);
317 utime (peakpath.c_str(), &tbuf);
321 AudioSource::rename_peakfile (string newpath)
323 /* caller must hold _lock */
325 string oldpath = peakpath;
327 if (access (oldpath.c_str(), F_OK) == 0) {
328 if (rename (oldpath.c_str(), newpath.c_str()) != 0) {
329 error << string_compose (_("cannot rename peakfile for %1 from %2 to %3 (%4)"), _name, oldpath, newpath, strerror (errno)) << endmsg;
340 AudioSource::initialize_peakfile (bool newfile, string audio_path)
344 peakpath = peak_path (audio_path);
346 /* Nasty band-aid for older sessions that were created before we
347 used libsndfile for all audio files.
350 if (!newfile && access (peakpath.c_str(), R_OK) != 0) {
351 string str = old_peak_path (audio_path);
352 if (access (str.c_str(), R_OK) == 0) {
359 if (!_build_peakfiles) {
363 _peaks_built = false;
367 if (stat (peakpath.c_str(), &statbuf)) {
368 if (errno != ENOENT) {
369 /* it exists in the peaks dir, but there is some kind of error */
371 error << string_compose(_("AudioSource: cannot stat peakfile \"%1\""), peakpath) << endmsg;
375 _peaks_built = false;
379 /* we found it in the peaks dir, so check it out */
381 if (statbuf.st_size == 0) {
382 _peaks_built = false;
384 // Check if the audio file has changed since the peakfile was built.
385 struct stat stat_file;
386 int err = stat (audio_path.c_str(), &stat_file);
388 if (!err && stat_file.st_mtime > statbuf.st_mtime){
389 _peaks_built = false;
393 _peak_byte_max = statbuf.st_size;
399 if (!newfile && !_peaks_built && _build_missing_peakfiles && _build_peakfiles) {
400 build_peaks_from_scratch ();
407 AudioSource::read (Sample *dst, nframes_t start, nframes_t cnt) const
409 Glib::Mutex::Lock lm (_lock);
410 return read_unlocked (dst, start, cnt);
414 AudioSource::write (Sample *dst, nframes_t cnt)
416 Glib::Mutex::Lock lm (_lock);
417 return write_unlocked (dst, cnt);
421 AudioSource::read_peaks (PeakData *peaks, nframes_t npeaks, nframes_t start, nframes_t cnt, double samples_per_visual_peak) const
423 Glib::Mutex::Lock lm (_lock);
425 double expected_peaks;
426 PeakData::PeakDatum xmax;
427 PeakData::PeakDatum xmin;
430 nframes_t zero_fill = 0;
432 PeakData* staging = 0;
433 Sample* raw_staging = 0;
436 expected_peaks = (cnt / (double) frames_per_peak);
437 scale = npeaks/expected_peaks;
439 #undef DEBUG_READ_PEAKS
440 #ifdef DEBUG_READ_PEAKS
441 cerr << "======>RP: npeaks = " << npeaks
442 << " start = " << start
444 << " len = " << _length
445 << " samples_per_visual_peak =" << samples_per_visual_peak
446 << " expected was " << expected_peaks << " ... scale = " << scale
447 << " PD ptr = " << peaks
452 /* fix for near-end-of-file conditions */
454 if (cnt > _length - start) {
455 // cerr << "too close to end @ " << _length << " given " << start << " + " << cnt << endl;
456 cnt = _length - start;
457 nframes_t old = npeaks;
458 npeaks = min ((nframes_t) floor (cnt / samples_per_visual_peak), npeaks);
459 zero_fill = old - npeaks;
462 // cerr << "actual npeaks = " << npeaks << " zf = " << zero_fill << endl;
466 #ifdef DEBUG_READ_PEAKS
467 cerr << "RAW DATA\n";
469 /* no scaling at all, just get the sample data and duplicate it for
470 both max and min peak values.
473 Sample* raw_staging = new Sample[cnt];
475 if (read_unlocked (raw_staging, start, cnt) != cnt) {
476 error << _("cannot read sample data for unscaled peak computation") << endmsg;
480 for (nframes_t i = 0; i < npeaks; ++i) {
481 peaks[i].max = raw_staging[i];
482 peaks[i].min = raw_staging[i];
485 delete [] raw_staging;
491 off_t first_peak_byte = (start / frames_per_peak) * sizeof (PeakData);
493 /* open, read, close */
495 if ((peakfile = ::open (peakpath.c_str(), O_RDONLY, 0664)) < 0) {
496 error << string_compose(_("AudioSource: cannot open peakpath \"%1\" (%2)"), peakpath, strerror (errno)) << endmsg;
500 #ifdef DEBUG_READ_PEAKS
501 cerr << "DIRECT PEAKS\n";
504 nread = ::pread (peakfile, peaks, sizeof (PeakData)* npeaks, first_peak_byte);
507 if (nread != sizeof (PeakData) * npeaks) {
508 cerr << "AudioSource["
510 << "]: cannot read peaks from peakfile! (read only "
524 memset (&peaks[npeaks], 0, sizeof (PeakData) * zero_fill);
535 #ifdef DEBUG_READ_PEAKS
536 cerr << "DOWNSAMPLE\n";
540 - more frames-per-peak (lower resolution) than the peakfile, or to put it another way,
541 - less peaks than the peakfile holds for the same range
543 So, read a block into a staging area, and then downsample from there.
545 to avoid confusion, I'll refer to the requested peaks as visual_peaks and the peakfile peaks as stored_peaks
548 const uint32_t chunksize = (uint32_t) min (expected_peaks, 65536.0);
550 staging = new PeakData[chunksize];
552 /* compute the rounded up frame position */
554 nframes_t current_frame = start;
555 nframes_t current_stored_peak = (nframes_t) ceil (current_frame / (double) frames_per_peak);
556 uint32_t next_visual_peak = (uint32_t) ceil (current_frame / samples_per_visual_peak);
557 double next_visual_peak_frame = next_visual_peak * samples_per_visual_peak;
558 uint32_t stored_peak_before_next_visual_peak = (nframes_t) next_visual_peak_frame / frames_per_peak;
559 uint32_t nvisual_peaks = 0;
560 uint32_t stored_peaks_read = 0;
563 /* handle the case where the initial visual peak is on a pixel boundary */
565 current_stored_peak = min (current_stored_peak, stored_peak_before_next_visual_peak);
567 /* open ... close during out: handling */
569 if ((peakfile = ::open (peakpath.c_str(), O_RDONLY, 0664)) < 0) {
570 error << string_compose(_("AudioSource: cannot open peakpath \"%1\" (%2)"), peakpath, strerror (errno)) << endmsg;
574 while (nvisual_peaks < npeaks) {
576 if (i == stored_peaks_read) {
578 uint32_t start_byte = current_stored_peak * sizeof(PeakData);
579 tnp = min ((_length/frames_per_peak - current_stored_peak), (nframes_t) expected_peaks);
580 to_read = min (chunksize, tnp);
582 #ifdef DEBUG_READ_PEAKS
583 cerr << "read " << sizeof (PeakData) * to_read << " from peakfile @ " << start_byte << endl;
586 if ((nread = ::pread (peakfile, staging, sizeof (PeakData) * to_read, start_byte))
587 != sizeof (PeakData) * to_read) {
589 off_t fend = lseek (peakfile, 0, SEEK_END);
591 cerr << "AudioSource["
593 << "]: cannot read peak data from peakfile ("
594 << (nread / sizeof(PeakData))
595 << " peaks instead of "
600 << " at start_byte = " << start_byte
601 << " _length = " << _length << " versus len = " << fend
602 << " expected maxpeaks = " << (_length - current_frame)/frames_per_peak
603 << " npeaks was " << npeaks
609 stored_peaks_read = nread / sizeof(PeakData);
615 while ((i < stored_peaks_read) && (current_stored_peak <= stored_peak_before_next_visual_peak)) {
617 xmax = max (xmax, staging[i].max);
618 xmin = min (xmin, staging[i].min);
620 ++current_stored_peak;
624 peaks[nvisual_peaks].max = xmax;
625 peaks[nvisual_peaks].min = xmin;
629 //next_visual_peak_frame = min ((next_visual_peak * samples_per_visual_peak), (next_visual_peak_frame+samples_per_visual_peak) );
630 next_visual_peak_frame = min ((double) start+cnt, (next_visual_peak_frame+samples_per_visual_peak) );
631 stored_peak_before_next_visual_peak = (uint32_t) next_visual_peak_frame / frames_per_peak;
635 memset (&peaks[npeaks], 0, sizeof (PeakData) * zero_fill);
642 #ifdef DEBUG_READ_PEAKS
643 cerr << "UPSAMPLE\n";
647 - less frames-per-peak (more resolution)
648 - more peaks than stored in the Peakfile
650 So, fetch data from the raw source, and generate peak
654 nframes_t frames_read = 0;
655 nframes_t current_frame = start;
657 nframes_t nvisual_peaks = 0;
658 nframes_t chunksize = (nframes_t) min (cnt, (nframes_t) 4096);
659 raw_staging = new Sample[chunksize];
661 nframes_t frame_pos = start;
662 double pixel_pos = floor (frame_pos / samples_per_visual_peak);
663 double next_pixel_pos = ceil (frame_pos / samples_per_visual_peak);
664 double pixels_per_frame = 1.0 / samples_per_visual_peak;
669 while (nvisual_peaks < npeaks) {
671 if (i == frames_read) {
673 to_read = min (chunksize, (_length - current_frame));
675 if ((frames_read = read_unlocked (raw_staging, current_frame, to_read)) == 0) {
676 error << string_compose(_("AudioSource[%1]: peak read - cannot read %2 samples at offset %3")
677 , _name, to_read, current_frame)
685 xmax = max (xmax, raw_staging[i]);
686 xmin = min (xmin, raw_staging[i]);
689 pixel_pos += pixels_per_frame;
691 if (pixel_pos >= next_pixel_pos) {
693 peaks[nvisual_peaks].max = xmax;
694 peaks[nvisual_peaks].min = xmin;
699 next_pixel_pos = ceil (pixel_pos + 0.5);
704 memset (&peaks[npeaks], 0, sizeof (PeakData) * zero_fill);
720 delete [] raw_staging;
723 #ifdef DEBUG_READ_PEAKS
730 #undef DEBUG_PEAK_BUILD
733 AudioSource::build_peaks ()
735 vector<PeakBuildRecord*> built;
737 bool pr_signal = false;
738 list<PeakBuildRecord*> copy;
741 Glib::Mutex::Lock lm (_lock);
742 copy = pending_peak_builds;
743 pending_peak_builds.clear ();
746 #ifdef DEBUG_PEAK_BUILD
747 cerr << "build peaks with " << copy.size() << " requests pending\n";
750 for (list<PeakBuildRecord *>::iterator i = copy.begin(); i != copy.end(); ++i) {
752 if ((status = do_build_peak ((*i)->frame, (*i)->cnt)) != 0) {
753 unlink (peakpath.c_str());
756 built.push_back (new PeakBuildRecord (*(*i)));
761 Glib::Mutex::Lock lm (_lock);
766 if (next_peak_clear_should_notify) {
767 next_peak_clear_should_notify = false;
774 for (vector<PeakBuildRecord *>::iterator i = built.begin(); i != built.end(); ++i) {
775 PeakRangeReady ((*i)->frame, (*i)->cnt); /* EMIT SIGNAL */
781 PeaksReady (); /* EMIT SIGNAL */
789 AudioSource::do_build_peak (nframes_t first_frame, nframes_t cnt)
791 nframes_t current_frame;
792 Sample buf[frames_per_peak];
796 nframes_t frames_read;
797 nframes_t frames_to_read;
798 off_t first_peak_byte;
804 #ifdef DEBUG_PEAK_BUILD
805 cerr << pthread_self() << ": " << _name << ": building peaks for " << first_frame << " to " << first_frame + cnt - 1 << endl;
808 first_peak_byte = (first_frame / frames_per_peak) * sizeof (PeakData);
810 #ifdef DEBUG_PEAK_BUILD
811 cerr << "seeking to " << first_peak_byte << " before writing new peak data\n";
814 current_frame = first_frame;
815 peakbuf = new PeakData[(cnt/frames_per_peak)+1];
818 if ((peakfile = ::open (peakpath.c_str(), O_RDWR|O_CREAT, 0664)) < 0) {
819 error << string_compose(_("AudioSource: cannot open peakpath \"%1\" (%2)"), peakpath, strerror (errno)) << endmsg;
825 frames_to_read = min (frames_per_peak, cnt);
827 /* lock for every read */
829 if ((frames_read = read (buf, current_frame, frames_to_read)) != frames_to_read) {
830 error << string_compose(_("%1: could not write read raw data for peak computation (%2)"), _name, strerror (errno)) << endmsg;
837 for (nframes_t n = 1; n < frames_read; ++n) {
838 xmax = max (xmax, buf[n]);
839 xmin = min (xmin, buf[n]);
841 // if (current_frame < frames_read) {
842 // cerr << "sample = " << buf[n] << " max = " << xmax << " min = " << xmin << " max of 2 = " << max (xmax, buf[n]) << endl;
846 peakbuf[peaki].max = xmax;
847 peakbuf[peaki].min = xmin;
850 current_frame += frames_read;
854 #define BLOCKSIZE (128 * 1024)
856 /* on some filesystems (ext3, at least) this helps to reduce fragmentation of
857 the peakfiles. its not guaranteed to do so, and even on ext3 (as of december 2006)
858 it does not cause single-extent allocation even for peakfiles of
859 less than BLOCKSIZE bytes. only call ftruncate if we'll make the file larger.
861 endpos = lseek (peakfile, 0, SEEK_END);
863 target_length = BLOCKSIZE * ((first_peak_byte + BLOCKSIZE + 1) / BLOCKSIZE);
865 if (endpos < target_length) {
866 // XXX - we really shouldn't be doing this for destructive source peaks
867 ftruncate (peakfile, target_length);
868 //cerr << "do build TRUNC: " << peakpath << " " << target_length << endl;
870 /* error doesn't actually matter though, so continue on without testing */
873 if (::pwrite (peakfile, peakbuf, sizeof (PeakData) * peaki, first_peak_byte) != (ssize_t) (sizeof (PeakData) * peaki)) {
874 error << string_compose(_("%1: could not write peak file data (%2)"), _name, strerror (errno)) << endmsg;
878 _peak_byte_max = max(_peak_byte_max, (off_t) (first_peak_byte + sizeof(PeakData)*peaki));
891 AudioSource::build_peaks_from_scratch ()
893 Glib::Mutex::Lock lp (_lock);
895 next_peak_clear_should_notify = true;
896 pending_peak_builds.push_back (new PeakBuildRecord (0, _length));
897 queue_for_peaks (shared_from_this(), true);
901 AudioSource::truncate_peakfile ()
905 /* truncate the peakfile down to its natural length if necessary */
907 if ((peakfile = ::open (peakpath.c_str(), O_RDWR)) >= 0) {
908 off_t end = lseek (peakfile, 0, SEEK_END);
910 if (end > _peak_byte_max) {
911 ftruncate(peakfile, _peak_byte_max);
912 //cerr << "truncated " << peakpath << " to " << _peak_byte_max << " bytes" << endl;
915 //cerr << "NOT truncated " << peakpath << " to " << _peak_byte_max << " end " << end << endl;
922 AudioSource::file_changed (string path)
924 struct stat stat_file;
925 struct stat stat_peak;
927 int e1 = stat (path.c_str(), &stat_file);
928 int e2 = stat (peak_path(path).c_str(), &stat_peak);
930 if (!e1 && !e2 && stat_file.st_mtime > stat_peak.st_mtime){
938 AudioSource::available_peaks (double zoom_factor) const
942 if (zoom_factor < frames_per_peak) {
943 return length(); // peak data will come from the audio file
946 /* peak data comes from peakfile, but the filesize might not represent
947 the valid data due to ftruncate optimizations, so use _peak_byte_max state.
948 XXX - there might be some atomicity issues here, we should probably add a lock,
949 but _peak_byte_max only monotonically increases after initialization.
952 end = _peak_byte_max;
954 return (end/sizeof(PeakData)) * frames_per_peak;
958 AudioSource::update_length (nframes_t pos, nframes_t cnt)
960 if (pos + cnt > _length) {