summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaul Davis <paul@linuxaudiosystems.com>2007-09-10 18:45:12 +0000
committerPaul Davis <paul@linuxaudiosystems.com>2007-09-10 18:45:12 +0000
commitafcbba17f01347b7bc59f9cff6e081be7645d60a (patch)
tree2ded17e16b35bdd32476f4d4212e0d1c05d02ae8
parentadfa5978d30f823e9cff0ae7bd555d734be55d18 (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.cc5
-rw-r--r--libs/ardour/ardour/audiosource.h11
-rw-r--r--libs/ardour/audio_track.cc14
-rw-r--r--libs/ardour/audiofilesource.cc8
-rw-r--r--libs/ardour/audiosource.cc60
-rw-r--r--libs/ardour/sndfilesource.cc4
-rw-r--r--libs/ardour/source_factory.cc17
-rw-r--r--libs/pbd/pbd/abstract_ui.cc13
-rw-r--r--libs/pbd/pbd/abstract_ui.h1
-rw-r--r--libs/pbd/pbd/pthread_utils.h1
-rw-r--r--libs/pbd/pthread_utils.cc1
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;
}