diff options
author | Paul Davis <paul@linuxaudiosystems.com> | 2007-09-10 18:45:12 +0000 |
---|---|---|
committer | Paul Davis <paul@linuxaudiosystems.com> | 2007-09-10 18:45:12 +0000 |
commit | afcbba17f01347b7bc59f9cff6e081be7645d60a (patch) | |
tree | 2ded17e16b35bdd32476f4d4212e0d1c05d02ae8 | |
parent | adfa5978d30f823e9cff0ae7bd555d734be55d18 (diff) |
WARNING WARNING WARNING >>>> DEEP CHANGES >>> EXPERIMENTAL CODE .... fixes to make region(views) pick up peakfile data asynchronously, like they used to in 0.99
git-svn-id: svn://localhost/ardour2/branches/2.0-ongoing@2444 d708f5d6-7413-0410-9779-e7cbd77b26cf
-rw-r--r-- | gtk2_ardour/audio_region_view.cc | 5 | ||||
-rw-r--r-- | libs/ardour/ardour/audiosource.h | 11 | ||||
-rw-r--r-- | libs/ardour/audio_track.cc | 14 | ||||
-rw-r--r-- | libs/ardour/audiofilesource.cc | 8 | ||||
-rw-r--r-- | libs/ardour/audiosource.cc | 60 | ||||
-rw-r--r-- | libs/ardour/sndfilesource.cc | 4 | ||||
-rw-r--r-- | libs/ardour/source_factory.cc | 17 | ||||
-rw-r--r-- | libs/pbd/pbd/abstract_ui.cc | 13 | ||||
-rw-r--r-- | libs/pbd/pbd/abstract_ui.h | 1 | ||||
-rw-r--r-- | libs/pbd/pbd/pthread_utils.h | 1 | ||||
-rw-r--r-- | libs/pbd/pthread_utils.cc | 1 |
11 files changed, 99 insertions, 36 deletions
diff --git a/gtk2_ardour/audio_region_view.cc b/gtk2_ardour/audio_region_view.cc index 4f7192e373..794f8dc34b 100644 --- a/gtk2_ardour/audio_region_view.cc +++ b/gtk2_ardour/audio_region_view.cc @@ -113,7 +113,7 @@ AudioRegionView::AudioRegionView (const AudioRegionView& other) UINT_TO_RGBA (other.fill_color, &r, &g, &b, &a); c.set_rgb_p (r/255.0, g/255.0, b/255.0); - init (c, false); + init (c, true); } void @@ -122,7 +122,7 @@ AudioRegionView::init (Gdk::Color& basic_color, bool wfd) // FIXME: Some redundancy here with RegionView::init. Need to figure out // where order is important and where it isn't... - RegionView::init(basic_color, false); + RegionView::init (basic_color, true); XMLNode *node; @@ -865,7 +865,6 @@ AudioRegionView::create_one_wave (uint32_t which, bool direct) /* all waves created, don't hook into peaks ready anymore */ data_ready_connection.disconnect (); - if(0) if (!zero_line) { zero_line = new ArdourCanvas::SimpleLine (*group); zero_line->property_x1() = (gdouble) 1.0; diff --git a/libs/ardour/ardour/audiosource.h b/libs/ardour/ardour/audiosource.h index b1062c43a9..fefc5d8964 100644 --- a/libs/ardour/ardour/audiosource.h +++ b/libs/ardour/ardour/audiosource.h @@ -108,15 +108,16 @@ const nframes_t frames_per_peak = 256; virtual int setup_peakfile () { return 0; } int prepare_for_peakfile_writes (); - void done_with_peakfile_writes (); + void done_with_peakfile_writes (bool done = true); protected: static bool _build_missing_peakfiles; static bool _build_peakfiles; - bool _peaks_built; - mutable Glib::Mutex _lock; - nframes_t _length; + bool _peaks_built; + mutable Glib::RWLock _lock; + mutable Glib::Mutex _peaks_ready_lock; + nframes_t _length; ustring peakpath; ustring _captured_for; @@ -125,7 +126,7 @@ const nframes_t frames_per_peak = 256; int initialize_peakfile (bool newfile, ustring path); int build_peaks_from_scratch (); - int compute_and_write_peaks (Sample* buf, nframes_t first_frame, nframes_t cnt, bool force); + int compute_and_write_peaks (Sample* buf, nframes_t first_frame, nframes_t cnt, bool force, bool intermediate_peaks_ready_signal); void truncate_peakfile(); mutable off_t _peak_byte_max; // modified in compute_and_write_peak() diff --git a/libs/ardour/audio_track.cc b/libs/ardour/audio_track.cc index 7c25a8c899..c2f76f339d 100644 --- a/libs/ardour/audio_track.cc +++ b/libs/ardour/audio_track.cc @@ -138,14 +138,22 @@ AudioTrack::deprecated_use_diskstream_connections () if (c == 0) { error << string_compose(_("Unknown connection \"%1\" listed for input of %2"), prop->value(), _name) << endmsg; + + string replacement_connection; + + if (prop->value().find ('+') != string::npos) { + replacement_connection = _("in 1+2"); + } else { + replacement_connection = _("in 1"); + } - if ((c = _session.connection_by_name (_("in 1"))) == 0) { + if ((c = _session.connection_by_name (replacement_connection)) == 0) { error << _("No input connections available as a replacement") << endmsg; return -1; } else { - info << string_compose (_("Connection %1 was not available - \"in 1\" used instead"), prop->value()) - << endmsg; + info << string_compose (_("Connection %1 was not available - \"%2\" used instead"), prop->value(), replacement_connection) + << endmsg; } } diff --git a/libs/ardour/audiofilesource.cc b/libs/ardour/audiofilesource.cc index b9aa977e0a..39b0228791 100644 --- a/libs/ardour/audiofilesource.cc +++ b/libs/ardour/audiofilesource.cc @@ -265,8 +265,12 @@ AudioFileSource::mark_streaming_write_completed () return; } - Glib::Mutex::Lock lm (_lock); + /* XXX notice that we're readers of _peaks_built + but we must hold a solid lock on PeaksReady. + */ + Glib::RWLock::WriterLock lm (_lock); + if (_peaks_built) { PeaksReady (); /* EMIT SIGNAL */ } @@ -564,7 +568,7 @@ AudioFileSource::set_allow_remove_if_empty (bool yn) int AudioFileSource::set_name (ustring newname, bool destructive) { - Glib::Mutex::Lock lm (_lock); + Glib::RWLock::WriterLock lm (_lock); ustring oldpath = _path; ustring newpath = Session::change_audio_path_by_name (oldpath, _name, newname, destructive); diff --git a/libs/ardour/audiosource.cc b/libs/ardour/audiosource.cc index 3511b0c519..5df5e0b23a 100644 --- a/libs/ardour/audiosource.cc +++ b/libs/ardour/audiosource.cc @@ -127,16 +127,16 @@ bool AudioSource::peaks_ready (sigc::slot<void> the_slot, sigc::connection& conn) const { bool ret; - Glib::Mutex::Lock lm (_lock); + Glib::Mutex::Lock lm (_peaks_ready_lock); /* check to see if the peak data is ready. if not connect the slot while still holding the lock. */ - + if (!(ret = _peaks_built)) { conn = PeaksReady.connect (the_slot); } - + return ret; } @@ -246,21 +246,21 @@ AudioSource::initialize_peakfile (bool newfile, ustring audio_path) nframes_t AudioSource::read (Sample *dst, nframes_t start, nframes_t cnt) const { - Glib::Mutex::Lock lm (_lock); + Glib::RWLock::ReaderLock lm (_lock); return read_unlocked (dst, start, cnt); } nframes_t AudioSource::write (Sample *dst, nframes_t cnt) { - Glib::Mutex::Lock lm (_lock); + Glib::RWLock::WriterLock lm (_lock); return write_unlocked (dst, cnt); } int AudioSource::read_peaks (PeakData *peaks, nframes_t npeaks, nframes_t start, nframes_t cnt, double samples_per_visual_peak) const { - Glib::Mutex::Lock lm (_lock); + Glib::RWLock::ReaderLock lm (_lock); double scale; double expected_peaks; PeakData::PeakDatum xmax; @@ -590,7 +590,7 @@ AudioSource::build_peaks_from_scratch () { /* hold lock while building peaks */ - Glib::Mutex::Lock lp (_lock); + Glib::RWLock::ReaderLock lp (_lock); if (prepare_for_peakfile_writes ()) { goto out; @@ -606,11 +606,11 @@ AudioSource::build_peaks_from_scratch () if ((frames_read = read_unlocked (buf, current_frame, frames_to_read)) != frames_to_read) { error << string_compose(_("%1: could not write read raw data for peak computation (%2)"), _name, strerror (errno)) << endmsg; - done_with_peakfile_writes (); + done_with_peakfile_writes (false); goto out; } - if (compute_and_write_peaks (buf, current_frame, frames_read, true)) { + if (compute_and_write_peaks (buf, current_frame, frames_read, true, false)) { break; } @@ -626,12 +626,15 @@ AudioSource::build_peaks_from_scratch () done_with_peakfile_writes (); } + + { + Glib::Mutex::Lock lm (_peaks_ready_lock); + + if (_peaks_built) { + PeaksReady (); /* EMIT SIGNAL */ - /* lock no longer held, safe to signal */ - - if (_peaks_built) { - PeaksReady (); /* EMIT SIGNAL */ - ret = 0; + ret = 0; + } } out: @@ -653,10 +656,14 @@ AudioSource::prepare_for_peakfile_writes () } void -AudioSource::done_with_peakfile_writes () +AudioSource::done_with_peakfile_writes (bool done) { if (peak_leftover_cnt) { - compute_and_write_peaks (0, 0, 0, true); + compute_and_write_peaks (0, 0, 0, true, false); + } + + if (done) { + _peaks_built = true; } if (peakfile >= 0) { @@ -666,7 +673,7 @@ AudioSource::done_with_peakfile_writes () } int -AudioSource::compute_and_write_peaks (Sample* buf, nframes_t first_frame, nframes_t cnt, bool force) +AudioSource::compute_and_write_peaks (Sample* buf, nframes_t first_frame, nframes_t cnt, bool force, bool intermediate_peaks_ready) { Sample* buf2 = 0; nframes_t to_do; @@ -707,8 +714,15 @@ AudioSource::compute_and_write_peaks (Sample* buf, nframes_t first_frame, nframe _peak_byte_max = max (_peak_byte_max, (off_t) (byte + sizeof(PeakData))); - PeakRangeReady (peak_leftover_frame, peak_leftover_cnt); /* EMIT SIGNAL */ - PeaksReady (); /* EMIT SIGNAL */ + { + Glib::Mutex::Lock lm (_peaks_ready_lock); + PeakRangeReady (peak_leftover_frame, peak_leftover_cnt); /* EMIT SIGNAL */ + if (intermediate_peaks_ready) { + PeaksReady (); /* EMIT SIGNAL */ + } else { + cerr << "skipped PR @ A\n"; + } + } /* left overs are done */ @@ -815,8 +829,14 @@ AudioSource::compute_and_write_peaks (Sample* buf, nframes_t first_frame, nframe _peak_byte_max = max (_peak_byte_max, (off_t) (first_peak_byte + sizeof(PeakData)*peaks_computed)); if (frames_done) { + Glib::Mutex::Lock lm (_peaks_ready_lock); PeakRangeReady (first_frame, frames_done); /* EMIT SIGNAL */ - PeaksReady (); /* EMIT SIGNAL */ + if (intermediate_peaks_ready) { + PeaksReady (); /* EMIT SIGNAL */ + } else { + cerr << "skipped PR @ B\n"; + } + } ret = 0; diff --git a/libs/ardour/sndfilesource.cc b/libs/ardour/sndfilesource.cc index 1878d23d30..0ed8c9cc34 100644 --- a/libs/ardour/sndfilesource.cc +++ b/libs/ardour/sndfilesource.cc @@ -401,7 +401,7 @@ SndFileSource::nondestructive_write_unlocked (Sample *data, nframes_t cnt) update_length (oldlen, cnt); if (_build_peakfiles) { - compute_and_write_peaks (data, frame_pos, cnt, false); + compute_and_write_peaks (data, frame_pos, cnt, false, true); } _write_data_count = cnt; @@ -493,7 +493,7 @@ SndFileSource::destructive_write_unlocked (Sample* data, nframes_t cnt) update_length (file_pos, cnt); if (_build_peakfiles) { - compute_and_write_peaks (data, file_pos, cnt, false); + compute_and_write_peaks (data, file_pos, cnt, false, true); } file_pos += cnt; diff --git a/libs/ardour/source_factory.cc b/libs/ardour/source_factory.cc index cd20060cfa..b2774591e4 100644 --- a/libs/ardour/source_factory.cc +++ b/libs/ardour/source_factory.cc @@ -21,6 +21,8 @@ #include <glibmm/thread.h> #include <pbd/error.h> +#include <pbd/convert.h> +#include <pbd/pthread_utils.h> #include <ardour/source_factory.h> #include <ardour/sndfilesource.h> @@ -40,13 +42,26 @@ using namespace sigc; sigc::signal<void,boost::shared_ptr<Source> > SourceFactory::SourceCreated; +static void setup_peakfile (boost::weak_ptr<AudioSource> was) +{ + boost::shared_ptr<AudioSource> as (was.lock()); + + if (!as) { + return; + } + + PBD::ThreadCreatedWithRequestSize (pthread_self(), string ("peakbuilder-") + to_string (pthread_self(), std::dec), 1024); + as->setup_peakfile (); + // PBD::ThreadLeaving (pthread_self()); +} + int SourceFactory::setup_peakfile (boost::shared_ptr<Source> s, bool async) { boost::shared_ptr<AudioSource> as (boost::dynamic_pointer_cast<AudioSource> (s)); if (as) { if (async) { - Glib::Thread::create (hide_return (mem_fun (*as, &AudioSource::setup_peakfile)), false); + Glib::Thread::create (bind (sigc::ptr_fun (::setup_peakfile), boost::weak_ptr<AudioSource>(as)), false); } else { if (as->setup_peakfile ()) { error << string_compose("SourceFactory: could not set up peakfile for %1", as->name()) << endmsg; diff --git a/libs/pbd/pbd/abstract_ui.cc b/libs/pbd/pbd/abstract_ui.cc index 97f19e1fe5..7b21390764 100644 --- a/libs/pbd/pbd/abstract_ui.cc +++ b/libs/pbd/pbd/abstract_ui.cc @@ -18,6 +18,7 @@ AbstractUI<RequestObject>::AbstractUI (string name, bool with_signal_pipes) } PBD::ThreadCreated.connect (mem_fun (*this, &AbstractUI<RequestObject>::register_thread)); + PBD::ThreadLeaving.connect (mem_fun (*this, &AbstractUI<RequestObject>::unregister_thread)); PBD::ThreadCreatedWithRequestSize.connect (mem_fun (*this, &AbstractUI<RequestObject>::register_thread_with_request_count)); } @@ -40,6 +41,18 @@ AbstractUI<RequestObject>::register_thread_with_request_count (pthread_t thread_ pthread_setspecific (thread_request_buffer_key, b); } +template <typename RequestObject> void +AbstractUI<RequestObject>::unregister_thread (pthread_t thread_id) +{ + { + Glib::Mutex::Lock lm (request_buffer_map_lock); + typename RequestBufferMap::iterator x = request_buffers.find (thread_id); + if (x != request_buffers.end()) { + request_buffers.erase (x); + } + } +} + template <typename RequestObject> RequestObject* AbstractUI<RequestObject>::get_request (RequestType rt) { diff --git a/libs/pbd/pbd/abstract_ui.h b/libs/pbd/pbd/abstract_ui.h index 88c27aa0bc..7718d944ea 100644 --- a/libs/pbd/pbd/abstract_ui.h +++ b/libs/pbd/pbd/abstract_ui.h @@ -56,6 +56,7 @@ class AbstractUI : public BaseUI void register_thread (pthread_t, std::string); void register_thread_with_request_count (pthread_t, std::string, uint32_t num_requests); + void unregister_thread (pthread_t); protected: typedef RingBufferNPT<RequestObject> RequestBuffer; diff --git a/libs/pbd/pbd/pthread_utils.h b/libs/pbd/pbd/pthread_utils.h index 9fa6ba4ce4..157dab6c12 100644 --- a/libs/pbd/pbd/pthread_utils.h +++ b/libs/pbd/pbd/pthread_utils.h @@ -36,6 +36,7 @@ std::string pthread_name (); namespace PBD { extern sigc::signal<void,pthread_t,std::string> ThreadCreated; + extern sigc::signal<void,pthread_t> ThreadLeaving; extern sigc::signal<void,pthread_t,std::string,uint32_t> ThreadCreatedWithRequestSize; } diff --git a/libs/pbd/pthread_utils.cc b/libs/pbd/pthread_utils.cc index 3408f2c0b7..0c9d574e73 100644 --- a/libs/pbd/pthread_utils.cc +++ b/libs/pbd/pthread_utils.cc @@ -33,6 +33,7 @@ static pthread_mutex_t thread_map_lock = PTHREAD_MUTEX_INITIALIZER; namespace PBD { sigc::signal<void,pthread_t,std::string> ThreadCreated; + sigc::signal<void,pthread_t> ThreadLeaving; sigc::signal<void,pthread_t,std::string,uint32_t> ThreadCreatedWithRequestSize; } |